Initiatives: validate and read files from local directory (#1644)
Helper functions intended to be used in succession by `loadDirectory`. Only `_validatePath` provides helfpul error messages. It's the caller's responsiblity to do this first. Introduces dependency `globby` for globbing with a Promises API.
This commit is contained in:
parent
803a752d80
commit
4a4c35bfdc
|
@ -18,6 +18,7 @@
|
|||
"deep-freeze": "^0.0.1",
|
||||
"express": "^4.16.3",
|
||||
"fs-extra": "8.1.0",
|
||||
"globby": "^11.0.0",
|
||||
"history": "^3.0.0",
|
||||
"htmlparser2": "^4.0.0",
|
||||
"isomorphic-fetch": "^2.2.1",
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`plugins/initiatives/initiativesDirectory _readFiles should read provided initiativeFiles, sorted by name 1`] = `
|
||||
Map {
|
||||
"initiative-A.json" => Object {
|
||||
"champions": Array [
|
||||
"http://foo.bar/A/champ",
|
||||
],
|
||||
"completed": true,
|
||||
"contributions": Array [
|
||||
"http://foo.bar/A/contrib",
|
||||
],
|
||||
"dependencies": Array [
|
||||
"http://foo.bar/A/dep",
|
||||
],
|
||||
"references": Array [
|
||||
"http://foo.bar/A/ref",
|
||||
],
|
||||
"timestampIso": "2020-01-08T22:01:57.711Z",
|
||||
"title": "Initiative A",
|
||||
},
|
||||
"initiative-B.json" => Object {
|
||||
"champions": Array [
|
||||
"http://foo.bar/B/champ",
|
||||
],
|
||||
"completed": false,
|
||||
"contributions": Array [
|
||||
"http://foo.bar/B/contrib",
|
||||
],
|
||||
"dependencies": Array [
|
||||
"http://foo.bar/B/dep",
|
||||
],
|
||||
"references": Array [
|
||||
"http://foo.bar/B/ref",
|
||||
],
|
||||
"timestampIso": "2020-01-08T22:01:57.722Z",
|
||||
"title": "Initiative B",
|
||||
},
|
||||
}
|
||||
`;
|
|
@ -0,0 +1,15 @@
|
|||
[
|
||||
{
|
||||
"type": "sourcecred/initiativeFile",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
{
|
||||
"title": "Initiative A",
|
||||
"timestampIso": "2020-01-08T22:01:57.711Z",
|
||||
"completed": true,
|
||||
"champions": ["http://foo.bar/A/champ"],
|
||||
"contributions": ["http://foo.bar/A/contrib"],
|
||||
"dependencies": ["http://foo.bar/A/dep"],
|
||||
"references": ["http://foo.bar/A/ref"]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,15 @@
|
|||
[
|
||||
{
|
||||
"type": "sourcecred/initiativeFile",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
{
|
||||
"title": "Initiative B",
|
||||
"timestampIso": "2020-01-08T22:01:57.722Z",
|
||||
"completed": false,
|
||||
"champions": ["http://foo.bar/B/champ"],
|
||||
"contributions": ["http://foo.bar/B/contrib"],
|
||||
"dependencies": ["http://foo.bar/B/dep"],
|
||||
"references": ["http://foo.bar/B/ref"]
|
||||
}
|
||||
]
|
|
@ -1,8 +1,12 @@
|
|||
// @flow
|
||||
|
||||
import path from "path";
|
||||
import fs from "fs-extra";
|
||||
import globby from "globby";
|
||||
import {type ReferenceDetector} from "../../core/references";
|
||||
import {type NodeAddressT, NodeAddress} from "../../core/graph";
|
||||
import {type Compatible, fromCompat, toCompat} from "../../util/compat";
|
||||
import {compatReader} from "../../backend/compatIO";
|
||||
import {initiativeNodeType} from "./declaration";
|
||||
import {
|
||||
type InitiativeId,
|
||||
|
@ -98,3 +102,51 @@ export function _initiativeFileId(
|
|||
): InitiativeId {
|
||||
return createId(INITIATIVE_FILE_SUBTYPE, remoteUrl, fileName);
|
||||
}
|
||||
|
||||
// Checks the path exists and is a directory.
|
||||
// Returns the absolute path or throws.
|
||||
export async function _validatePath(localPath: string): Promise<string> {
|
||||
const absPath = path.resolve(localPath);
|
||||
if (!(await fs.exists(absPath))) {
|
||||
throw new Error(
|
||||
`Provided initiatives directory does not exist at: ${absPath}`
|
||||
);
|
||||
}
|
||||
if (!(await fs.lstat(absPath)).isDirectory()) {
|
||||
throw new Error(
|
||||
`Provided initiatives directory is not a directory at: ${absPath}`
|
||||
);
|
||||
}
|
||||
return absPath;
|
||||
}
|
||||
|
||||
// Gets all *.json filenames in the given directory.
|
||||
export async function _findFiles(
|
||||
localPath: string
|
||||
): Promise<$ReadOnlyArray<string>> {
|
||||
const absoluteFileNames = await globby(path.join(localPath, "*.json"));
|
||||
return absoluteFileNames.map((a) => path.basename(a));
|
||||
}
|
||||
|
||||
type NamesToInitiativeFiles = Map<string, InitiativeFile>;
|
||||
|
||||
// Reads all given filenames in the given directory, validating them as compat.
|
||||
export async function _readFiles(
|
||||
localPath: string,
|
||||
fileNames: $ReadOnlyArray<string>
|
||||
): Promise<NamesToInitiativeFiles> {
|
||||
const map: NamesToInitiativeFiles = new Map();
|
||||
const readInitiativeFile = compatReader(fromJSON, "Initiative");
|
||||
|
||||
// Sorting to be careful about predictability.
|
||||
// The eventual output of $ReadOnlyArray<Initiative> is ordered, so we'll see
|
||||
// the order matters for equality throughout the system.
|
||||
const sortedFileNames = [...fileNames].sort();
|
||||
for (const fileName of sortedFileNames) {
|
||||
const filePath = path.join(localPath, fileName);
|
||||
const initiativeFile = await readInitiativeFile(filePath);
|
||||
map.set(fileName, initiativeFile);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
// @flow
|
||||
|
||||
import tmp from "tmp";
|
||||
import path from "path";
|
||||
import fs from "fs-extra";
|
||||
import {NodeAddress} from "../../core/graph";
|
||||
import {createId, addressFromId} from "./initiative";
|
||||
import {
|
||||
|
@ -9,6 +12,9 @@ import {
|
|||
toJSON,
|
||||
initiativeFileURL,
|
||||
_initiativeFileId,
|
||||
_validatePath,
|
||||
_findFiles,
|
||||
_readFiles,
|
||||
} from "./initiativesDirectory";
|
||||
|
||||
const exampleInitiativeFile = (): InitiativeFile => ({
|
||||
|
@ -79,4 +85,102 @@ describe("plugins/initiatives/initiativesDirectory", () => {
|
|||
expect(id).toEqual(createId("INITIATIVE_FILE", dir.remoteUrl, fileName));
|
||||
});
|
||||
});
|
||||
|
||||
describe("_validatePath", () => {
|
||||
it("should resolve relative paths", async () => {
|
||||
// Given
|
||||
const localPath = `${__dirname}/./test/../example/`;
|
||||
|
||||
// When
|
||||
const actual = await _validatePath(localPath);
|
||||
|
||||
// Then
|
||||
expect(actual).toEqual(path.join(__dirname, "example"));
|
||||
});
|
||||
|
||||
it("should throw when directory doesn't exist", async () => {
|
||||
// Given
|
||||
const localPath = path.join(tmp.dirSync().name, "findFiles_test");
|
||||
|
||||
// When
|
||||
const p = _validatePath(localPath);
|
||||
|
||||
// Then
|
||||
await expect(p).rejects.toThrow(
|
||||
`Provided initiatives directory does not exist at: ${localPath}`
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw when directory is not a directory", async () => {
|
||||
// Given
|
||||
const localPath = path.join(tmp.dirSync().name, "findFiles_test");
|
||||
await fs.writeFile(localPath, "");
|
||||
|
||||
// When
|
||||
const p = _validatePath(localPath);
|
||||
|
||||
// Then
|
||||
await expect(p).rejects.toThrow(
|
||||
`Provided initiatives directory is not a directory at: ${localPath}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_findFiles", () => {
|
||||
it("should locate all *.json files in a local path", async () => {
|
||||
// Given
|
||||
const localPath = path.join(__dirname, "example");
|
||||
|
||||
// When
|
||||
const fileNames = await _findFiles(localPath);
|
||||
|
||||
// Then
|
||||
// Shallow copy to sort, because the array is read-only.
|
||||
const actualNames = [...fileNames].sort();
|
||||
expect(actualNames).toEqual(["initiative-A.json", "initiative-B.json"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_readFiles", () => {
|
||||
it("should read provided initiativeFiles, sorted by name", async () => {
|
||||
// Given
|
||||
const localPath = path.join(__dirname, "example");
|
||||
const fileNames = ["initiative-B.json", "initiative-A.json"];
|
||||
|
||||
// When
|
||||
const map = await _readFiles(localPath, fileNames);
|
||||
|
||||
// Then
|
||||
expect([...map.keys()]).toEqual([
|
||||
"initiative-A.json",
|
||||
"initiative-B.json",
|
||||
]);
|
||||
expect(map).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should throw when directory doesn't exist", async () => {
|
||||
// Given
|
||||
const localPath = path.join(tmp.dirSync().name, "findFiles_test");
|
||||
const fileNames = ["initiative-B.json", "initiative-A.json"];
|
||||
|
||||
// When
|
||||
const p = _readFiles(localPath, fileNames);
|
||||
|
||||
// Then
|
||||
await expect(p).rejects.toThrow("Could not find Initiative file at:");
|
||||
});
|
||||
|
||||
it("should throw when directory is not a directory", async () => {
|
||||
// Given
|
||||
const localPath = path.join(tmp.dirSync().name, "findFiles_test");
|
||||
const fileNames = ["initiative-B.json", "initiative-A.json"];
|
||||
await fs.writeFile(localPath, "");
|
||||
|
||||
// When
|
||||
const p = _readFiles(localPath, fileNames);
|
||||
|
||||
// Then
|
||||
await expect(p).rejects.toThrow("Could not find Initiative file at:");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
134
yarn.lock
134
yarn.lock
|
@ -922,6 +922,27 @@
|
|||
"@types/istanbul-reports" "^1.1.1"
|
||||
"@types/yargs" "^13.0.0"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.3":
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
|
||||
integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==
|
||||
dependencies:
|
||||
"@nodelib/fs.stat" "2.0.3"
|
||||
run-parallel "^1.1.9"
|
||||
|
||||
"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3"
|
||||
integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==
|
||||
|
||||
"@nodelib/fs.walk@^1.2.3":
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976"
|
||||
integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==
|
||||
dependencies:
|
||||
"@nodelib/fs.scandir" "2.1.3"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@types/babel__core@^7.1.0":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30"
|
||||
|
@ -1433,6 +1454,11 @@ array-union@^1.0.1:
|
|||
dependencies:
|
||||
array-uniq "^1.0.1"
|
||||
|
||||
array-union@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
|
||||
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
|
||||
|
||||
array-uniq@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
|
||||
|
@ -1775,6 +1801,13 @@ braces@^2.3.1, braces@^2.3.2:
|
|||
split-string "^3.0.2"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
braces@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
brorand@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||
|
@ -2819,6 +2852,13 @@ dir-glob@^2.0.0:
|
|||
dependencies:
|
||||
path-type "^3.0.0"
|
||||
|
||||
dir-glob@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||
integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
|
||||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
discontinuous-range@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
|
||||
|
@ -3585,6 +3625,17 @@ fast-deep-equal@^2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
|
||||
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
|
||||
|
||||
fast-glob@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.1.1.tgz#87ee30e9e9f3eb40d6f254a7997655da753d7c82"
|
||||
integrity sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==
|
||||
dependencies:
|
||||
"@nodelib/fs.stat" "^2.0.2"
|
||||
"@nodelib/fs.walk" "^1.2.3"
|
||||
glob-parent "^5.1.0"
|
||||
merge2 "^1.3.0"
|
||||
micromatch "^4.0.2"
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||
|
@ -3595,6 +3646,13 @@ fast-levenshtein@~2.0.6:
|
|||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2"
|
||||
integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==
|
||||
dependencies:
|
||||
reusify "^1.0.0"
|
||||
|
||||
faye-websocket@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
|
||||
|
@ -3678,6 +3736,13 @@ fill-range@^4.0.0:
|
|||
repeat-string "^1.6.1"
|
||||
to-regex-range "^2.1.0"
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
finalhandler@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
|
||||
|
@ -3926,7 +3991,7 @@ glob-parent@^3.1.0:
|
|||
is-glob "^3.1.0"
|
||||
path-dirname "^1.0.0"
|
||||
|
||||
glob-parent@^5.0.0:
|
||||
glob-parent@^5.0.0, glob-parent@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2"
|
||||
integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==
|
||||
|
@ -3993,6 +4058,18 @@ globals@^12.1.0:
|
|||
dependencies:
|
||||
type-fest "^0.8.1"
|
||||
|
||||
globby@^11.0.0:
|
||||
version "11.0.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.0.tgz#56fd0e9f0d4f8fb0c456f1ab0dee96e1380bc154"
|
||||
integrity sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==
|
||||
dependencies:
|
||||
array-union "^2.1.0"
|
||||
dir-glob "^3.0.1"
|
||||
fast-glob "^3.1.1"
|
||||
ignore "^5.1.4"
|
||||
merge2 "^1.3.0"
|
||||
slash "^3.0.0"
|
||||
|
||||
globby@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
|
||||
|
@ -4356,6 +4433,11 @@ ignore@^4.0.6:
|
|||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
||||
|
||||
ignore@^5.1.4:
|
||||
version "5.1.4"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
|
||||
integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
|
||||
|
||||
import-fresh@^3.0.0:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
|
||||
|
@ -4694,6 +4776,11 @@ is-number@^3.0.0:
|
|||
dependencies:
|
||||
kind-of "^3.0.2"
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
is-path-cwd@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
|
||||
|
@ -5747,6 +5834,11 @@ merge-stream@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||
|
||||
merge2@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
|
||||
integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
|
||||
|
||||
methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
|
@ -5771,6 +5863,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
|
|||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.2"
|
||||
|
||||
micromatch@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
|
||||
integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
|
||||
dependencies:
|
||||
braces "^3.0.1"
|
||||
picomatch "^2.0.5"
|
||||
|
||||
miller-rabin@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
|
||||
|
@ -6606,6 +6706,11 @@ path-type@^3.0.0:
|
|||
dependencies:
|
||||
pify "^3.0.0"
|
||||
|
||||
path-type@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||
|
||||
pbkdf2@^3.0.3:
|
||||
version "3.0.17"
|
||||
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
|
||||
|
@ -6622,6 +6727,11 @@ performance-now@^2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
picomatch@^2.0.5:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a"
|
||||
integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==
|
||||
|
||||
pify@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
|
@ -7524,6 +7634,11 @@ retry@^0.12.0:
|
|||
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
|
||||
integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
|
||||
|
||||
reusify@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||
|
||||
rimraf@2.6.3:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||
|
@ -7573,6 +7688,11 @@ run-async@^2.2.0:
|
|||
dependencies:
|
||||
is-promise "^2.1.0"
|
||||
|
||||
run-parallel@^1.1.9:
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
|
||||
integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
|
||||
|
||||
run-queue@^1.0.0, run-queue@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
|
||||
|
@ -7825,6 +7945,11 @@ slash@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
|
||||
integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
|
||||
|
||||
slash@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||
|
||||
slice-ansi@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
|
||||
|
@ -8409,6 +8534,13 @@ to-regex-range@^2.1.0:
|
|||
is-number "^3.0.0"
|
||||
repeat-string "^1.6.1"
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
to-regex@^3.0.1, to-regex@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
|
||||
|
|
Loading…
Reference in New Issue