ext: ci command

This commit is contained in:
João Moreno 2021-02-01 17:08:49 +01:00
parent 03da2de889
commit 76962b2583
4 changed files with 398 additions and 34 deletions

View file

@ -23,39 +23,41 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getExtensions = void 0;
const fs_1 = require("fs");
const path = require("path");
const cp = require("child_process");
const commander_1 = require("commander");
const root = path.resolve(path.join(__dirname, '..'));
const storage_blob_1 = require("@azure/storage-blob");
const mkdirp = require("mkdirp");
const plimit = require("p-limit");
const rootPath = path.resolve(path.join(__dirname, '..'));
const vsixsPath = path.join(rootPath, '.build', 'vsix');
var ExtensionType;
(function (ExtensionType) {
ExtensionType["Grammar"] = "grammar";
ExtensionType["Theme"] = "theme";
ExtensionType["Misc"] = "misc";
})(ExtensionType || (ExtensionType = {}));
// const exists = (path) => fs.stat(path).then(() => true, () => false);
// const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json');
// async function readControlFile() {
// try {
// return JSON.parse(await fs.readFile(controlFilePath, 'utf8'));
// } catch (err) {
// return {};
// }
// }
// async function writeControlFile(control) {
// await mkdirp(path.dirname(controlFilePath));
// await fs.writeFile(controlFilePath, JSON.stringify(control, null, ' '));
// }
async function exec(cmd, args, opts = {}) {
async function spawn(cmd, argsOrOpts, opts = {}) {
return new Promise((c, e) => {
const child = cp.spawn(cmd, args, Object.assign({ stdio: 'inherit', env: process.env }, opts));
const child = Array.isArray(argsOrOpts)
? cp.spawn(cmd, argsOrOpts, Object.assign({ stdio: 'inherit', env: process.env }, opts))
: cp.spawn(cmd, Object.assign({ stdio: 'inherit', env: process.env }, argsOrOpts));
child.on('close', code => code === 0 ? c() : e(`Returned ${code}`));
});
}
async function exec(cmd, opts = {}) {
return new Promise((c, e) => {
cp.exec(cmd, Object.assign({ env: process.env }, opts), (err, stdout) => err ? e(err) : c(opts.trim ? stdout.trim() : stdout));
});
}
function getExtensionType(packageJson) {
var _a, _b, _c;
if (((_a = packageJson.contributes) === null || _a === void 0 ? void 0 : _a.themes) || ((_b = packageJson.contributes) === null || _b === void 0 ? void 0 : _b.iconThemes)) {
if (packageJson.main) {
return "misc" /* Misc */;
}
else if (((_a = packageJson.contributes) === null || _a === void 0 ? void 0 : _a.themes) || ((_b = packageJson.contributes) === null || _b === void 0 ? void 0 : _b.iconThemes)) {
return "theme" /* Theme */;
}
else if ((_c = packageJson.contributes) === null || _c === void 0 ? void 0 : _c.grammars) {
@ -69,19 +71,27 @@ async function getExtension(extensionPath) {
const packageJsonPath = path.join(extensionPath, 'package.json');
const packageJson = JSON.parse(await fs_1.promises.readFile(packageJsonPath, 'utf8'));
const type = getExtensionType(packageJson);
const { name, version } = packageJson;
const vsixName = `${name}-${version}.vsix`;
return {
name: packageJson.name,
name,
version,
path: extensionPath,
type
type,
vsixPath: path.join(vsixsPath, vsixName)
};
}
function getExtensions() {
return __asyncGenerator(this, arguments, function* getExtensions_1() {
const extensionsPath = path.join(root, 'extensions');
const extensionsPath = path.join(rootPath, 'extensions');
const children = yield __await(fs_1.promises.readdir(extensionsPath));
for (const child of children) {
try {
yield yield __await(yield __await(getExtension(path.join(extensionsPath, child))));
const extension = yield __await(getExtension(path.join(extensionsPath, child)));
if (extension.type !== "theme" /* Theme */ && extension.type !== "grammar" /* Grammar */) {
continue;
}
yield yield __await(extension);
}
catch (err) {
if (/ENOENT|ENOTDIR/.test(err.message)) {
@ -92,6 +102,7 @@ function getExtensions() {
}
});
}
exports.getExtensions = getExtensions;
async function each([cmd, ...args], opts) {
var e_1, _a;
try {
@ -101,7 +112,7 @@ async function each([cmd, ...args], opts) {
continue;
}
console.log(`👉 ${extension.name}`);
await exec(cmd, args, { cwd: extension.path });
await spawn(cmd, args, { cwd: extension.path });
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
@ -112,6 +123,61 @@ async function each([cmd, ...args], opts) {
finally { if (e_1) throw e_1.error; }
}
}
async function runExtensionCI(extension, opts) {
const vsixName = `${extension.name}-${extension.version}.vsix`;
const commit = await exec(`git log -1 --format="%H" -- ${extension.path}`, { trim: true });
const creds = new storage_blob_1.StorageSharedKeyCredential(opts.account, opts.key);
const service = new storage_blob_1.BlobServiceClient(`https://${opts.account}.blob.core.windows.net`, creds);
const container = service.getContainerClient('extensions');
const blobName = `${commit}/${vsixName}`;
const blob = container.getBlobClient(blobName);
try {
await blob.downloadToFile(extension.vsixPath);
console.log(`📦 [${extension.name}] Downloaded from cache (${blobName})`);
return;
}
catch (err) {
if (err.statusCode !== 404) {
throw err;
}
}
console.log(`📦 [${extension.name}] Cache miss (${blobName})`);
console.log(`📦 [${extension.name}] Building...`);
await spawn(`yarn`, { shell: true, cwd: extension.path });
await spawn(`vsce package --yarn -o ${vsixsPath}`, { shell: true, cwd: extension.path });
const blockBlob = await blob.getBlockBlobClient();
await blockBlob.uploadFile(extension.vsixPath);
}
async function ci() {
var e_2, _a;
const { 'AZURE_STORAGE_ACCOUNT_2': account, 'AZURE_STORAGE_KEY_2': key } = process.env;
if (!account) {
throw new Error('Missing env: AZURE_STORAGE_ACCOUNT_2');
}
else if (!key) {
throw new Error('Missing env: AZURE_STORAGE_KEY_2');
}
await mkdirp(vsixsPath);
const limit = plimit(10);
const promises = [];
try {
for (var _b = __asyncValues(getExtensions()), _c; _c = await _b.next(), !_c.done;) {
const extension = _c.value;
if (extension.type !== "theme" /* Theme */ && extension.type !== "grammar" /* Grammar */) {
continue;
}
promises.push(limit(() => runExtensionCI(extension, { account, key })));
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) await _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
await Promise.all(promises);
}
if (require.main === module) {
commander_1.program.version('0.0.1');
commander_1.program
@ -120,6 +186,10 @@ if (require.main === module) {
.description('Run a command in each extension repository')
.allowUnknownOption()
.action(each);
commander_1.program
.command('ci')
.description('Run CI build steps for extensions')
.action(ci);
commander_1.program.parseAsync(process.argv).catch(err => {
console.error(err);
process.exit(1);

View file

@ -7,8 +7,12 @@ import { promises as fs } from 'fs';
import * as path from 'path';
import * as cp from 'child_process';
import { program } from 'commander';
import { BlobServiceClient, StorageSharedKeyCredential } from '@azure/storage-blob';
import * as mkdirp from 'mkdirp';
import * as plimit from 'p-limit';
const root = path.resolve(path.join(__dirname, '..'));
const rootPath = path.resolve(path.join(__dirname, '..'));
const vsixsPath = path.join(rootPath, '.build', 'vsix');
const enum ExtensionType {
Grammar = 'grammar',
@ -18,8 +22,10 @@ const enum ExtensionType {
interface IExtension {
readonly name: string;
readonly version: string;
readonly path: string;
readonly type: ExtensionType;
readonly vsixPath: string;
}
// const exists = (path) => fs.stat(path).then(() => true, () => false);
@ -39,15 +45,28 @@ interface IExtension {
// await fs.writeFile(controlFilePath, JSON.stringify(control, null, ' '));
// }
async function exec(cmd: string, args: string[], opts: cp.SpawnOptions = {}): Promise<void> {
async function spawn(cmd: string, opts?: cp.SpawnOptions): Promise<void>;
async function spawn(cmd: string, args: string[], opts?: cp.SpawnOptions): Promise<void>;
async function spawn(cmd: string, argsOrOpts?: cp.SpawnOptions | string[], opts: cp.SpawnOptions = {}): Promise<void> {
return new Promise((c, e) => {
const child = cp.spawn(cmd, args, { stdio: 'inherit', env: process.env, ...opts });
const child = Array.isArray(argsOrOpts)
? cp.spawn(cmd, argsOrOpts, { stdio: 'inherit', env: process.env, ...opts })
: cp.spawn(cmd, { stdio: 'inherit', env: process.env, ...argsOrOpts });
child.on('close', code => code === 0 ? c() : e(`Returned ${code}`));
});
}
async function exec(cmd: string, opts: (cp.ExecOptions & { trim?: boolean }) = {}): Promise<string> {
return new Promise((c, e) => {
cp.exec(cmd, { env: process.env, ...opts }, (err, stdout) => err ? e(err) : c(opts.trim ? stdout.trim() : stdout));
});
}
function getExtensionType(packageJson: any): ExtensionType {
if (packageJson.contributes?.themes || packageJson.contributes?.iconThemes) {
if (packageJson.main) {
return ExtensionType.Misc;
} else if (packageJson.contributes?.themes || packageJson.contributes?.iconThemes) {
return ExtensionType.Theme;
} else if (packageJson.contributes?.grammars) {
return ExtensionType.Grammar;
@ -60,21 +79,31 @@ async function getExtension(extensionPath: string): Promise<IExtension> {
const packageJsonPath = path.join(extensionPath, 'package.json');
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
const type = getExtensionType(packageJson);
const { name, version } = packageJson;
const vsixName = `${name}-${version}.vsix`;
return {
name: packageJson.name,
name,
version,
path: extensionPath,
type
type,
vsixPath: path.join(vsixsPath, vsixName)
};
}
async function* getExtensions(): AsyncGenerator<IExtension, void, any> {
const extensionsPath = path.join(root, 'extensions');
export async function* getExtensions(): AsyncGenerator<IExtension, void, any> {
const extensionsPath = path.join(rootPath, 'extensions');
const children = await fs.readdir(extensionsPath);
for (const child of children) {
try {
yield await getExtension(path.join(extensionsPath, child));
const extension = await getExtension(path.join(extensionsPath, child));
if (extension.type !== ExtensionType.Theme && extension.type !== ExtensionType.Grammar) {
continue;
}
yield extension;
} catch (err) {
if (/ENOENT|ENOTDIR/.test(err.message)) {
continue;
@ -92,10 +121,63 @@ async function each([cmd, ...args]: string[], opts: { type?: string }) {
}
console.log(`👉 ${extension.name}`);
await exec(cmd, args, { cwd: extension.path });
await spawn(cmd, args, { cwd: extension.path });
}
}
async function runExtensionCI(extension: IExtension, opts: { account: string, key: string }): Promise<void> {
const vsixName = `${extension.name}-${extension.version}.vsix`;
const commit = await exec(`git log -1 --format="%H" -- ${extension.path}`, { trim: true });
const creds = new StorageSharedKeyCredential(opts.account, opts.key);
const service = new BlobServiceClient(`https://${opts.account}.blob.core.windows.net`, creds);
const container = service.getContainerClient('extensions');
const blobName = `${commit}/${vsixName}`;
const blob = container.getBlobClient(blobName);
try {
await blob.downloadToFile(extension.vsixPath);
console.log(`📦 [${extension.name}] Downloaded from cache (${blobName})`);
return;
} catch (err) {
if (err.statusCode !== 404) {
throw err;
}
}
console.log(`📦 [${extension.name}] Cache miss (${blobName})`);
console.log(`📦 [${extension.name}] Building...`);
await spawn(`yarn`, { shell: true, cwd: extension.path });
await spawn(`vsce package --yarn -o ${vsixsPath}`, { shell: true, cwd: extension.path });
const blockBlob = await blob.getBlockBlobClient();
await blockBlob.uploadFile(extension.vsixPath);
}
async function ci(): Promise<void> {
const { 'AZURE_STORAGE_ACCOUNT_2': account, 'AZURE_STORAGE_KEY_2': key } = process.env;
if (!account) {
throw new Error('Missing env: AZURE_STORAGE_ACCOUNT_2');
} else if (!key) {
throw new Error('Missing env: AZURE_STORAGE_KEY_2');
}
await mkdirp(vsixsPath);
const limit = plimit(10);
const promises = [];
for await (const extension of getExtensions()) {
if (extension.type !== ExtensionType.Theme && extension.type !== ExtensionType.Grammar) {
continue;
}
promises.push(limit(() => runExtensionCI(extension, { account, key })));
}
await Promise.all(promises);
}
if (require.main === module) {
program.version('0.0.1');
@ -106,6 +188,11 @@ if (require.main === module) {
.allowUnknownOption()
.action(each);
program
.command('ci')
.description('Run CI build steps for extensions')
.action(ci);
program.parseAsync(process.argv).catch(err => {
console.error(err);
process.exit(1);

View file

@ -4,6 +4,7 @@
"license": "MIT",
"devDependencies": {
"@azure/cosmos": "^3.9.3",
"@azure/storage-blob": "^12.4.0",
"@types/ansi-colors": "^3.2.0",
"@types/azure": "0.9.19",
"@types/debounce": "^1.0.0",
@ -20,8 +21,10 @@
"@types/mime": "0.0.29",
"@types/minimatch": "^3.0.3",
"@types/minimist": "^1.2.1",
"@types/mkdirp": "^1.0.1",
"@types/mocha": "^8.2.0",
"@types/node": "^12.19.9",
"@types/p-limit": "^2.2.0",
"@types/plist": "^3.0.2",
"@types/pump": "^1.0.1",
"@types/request": "^2.47.0",
@ -42,6 +45,7 @@
"jsonc-parser": "^2.3.0",
"mime": "^1.4.1",
"mkdirp": "^1.0.4",
"p-limit": "^3.1.0",
"plist": "^3.0.1",
"source-map": "0.6.1",
"typescript": "4.2.0-dev.20201207",

View file

@ -2,6 +2,73 @@
# yarn lockfile v1
"@azure/abort-controller@^1.0.0":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.2.tgz#822405c966b2aec16fb62c1b19d37eaccf231995"
integrity sha512-XUyTo+bcyxHEf+jlN2MXA7YU9nxVehaubngHV1MIZZaqYmZqykkoeAz/JMMEeR7t3TcyDwbFa3Zw8BZywmIx4g==
dependencies:
tslib "^2.0.0"
"@azure/core-asynciterator-polyfill@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz#dcccebb88406e5c76e0e1d52e8cc4c43a68b3ee7"
integrity sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg==
"@azure/core-auth@^1.1.3":
version "1.1.4"
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.1.4.tgz#af9a334acf3cb9c49e6013e6caf6dc9d43476030"
integrity sha512-+j1embyH1jqf04AIfJPdLafd5SC1y6z1Jz4i+USR1XkTp6KM8P5u4/AjmWMVoEQdM/M29PJcRDZcCEWjK9S1bw==
dependencies:
"@azure/abort-controller" "^1.0.0"
tslib "^2.0.0"
"@azure/core-http@^1.2.0":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-1.2.2.tgz#a6f7717184fd2657d3acabd1d64dfdc0bd531ce3"
integrity sha512-9eu2OcbR7e44gqBy4U1Uv8NTWgLIMwKXMEGgO2MahsJy5rdTiAhs5fJHQffPq8uX2MFh21iBODwO9R/Xlov88A==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-auth" "^1.1.3"
"@azure/core-tracing" "1.0.0-preview.9"
"@azure/logger" "^1.0.0"
"@opentelemetry/api" "^0.10.2"
"@types/node-fetch" "^2.5.0"
"@types/tunnel" "^0.0.1"
form-data "^3.0.0"
node-fetch "^2.6.0"
process "^0.11.10"
tough-cookie "^4.0.0"
tslib "^2.0.0"
tunnel "^0.0.6"
uuid "^8.3.0"
xml2js "^0.4.19"
"@azure/core-lro@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@azure/core-lro/-/core-lro-1.0.3.tgz#1ddfb4ecdb81ce87b5f5d972ffe2acbbc46e524e"
integrity sha512-Py2crJ84qx1rXkzIwfKw5Ni4WJuzVU7KAF6i1yP3ce8fbynUeu8eEWS4JGtSQgU7xv02G55iPDROifmSDbxeHA==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-http" "^1.2.0"
events "^3.0.0"
tslib "^2.0.0"
"@azure/core-paging@^1.1.1":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.1.3.tgz#3587c9898a0530cacb64bab216d7318468aa5efc"
integrity sha512-his7Ah40ThEYORSpIAwuh6B8wkGwO/zG7gqVtmSE4WAJ46e36zUDXTKReUCLBDc6HmjjApQQxxcRFy5FruG79A==
dependencies:
"@azure/core-asynciterator-polyfill" "^1.0.0"
"@azure/core-tracing@1.0.0-preview.9":
version "1.0.0-preview.9"
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.9.tgz#84f3b85572013f9d9b85e1e5d89787aa180787eb"
integrity sha512-zczolCLJ5QG42AEPQ+Qg9SRYNUyB+yZ5dzof4YEc+dyWczO9G2sBqbAjLB7IqrsdHN2apkiB2oXeDKCsq48jug==
dependencies:
"@opencensus/web-types" "0.0.7"
"@opentelemetry/api" "^0.10.2"
tslib "^2.0.0"
"@azure/cosmos@^3.9.3":
version "3.9.3"
resolved "https://registry.yarnpkg.com/@azure/cosmos/-/cosmos-3.9.3.tgz#7e95ff92e5c3e9da7e8316bc50c9cc928be6c1d6"
@ -19,6 +86,28 @@
universal-user-agent "^6.0.0"
uuid "^8.3.0"
"@azure/logger@^1.0.0":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.1.tgz#19b333203d1b2931353d8879e814b64a7274837a"
integrity sha512-QYQeaJ+A5x6aMNu8BG5qdsVBnYBop9UMwgUvGihSjf1PdZZXB+c/oMdM2ajKwzobLBh9e9QuMQkN9iL+IxLBLA==
dependencies:
tslib "^2.0.0"
"@azure/storage-blob@^12.4.0":
version "12.4.0"
resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.4.0.tgz#7127ddd9f413105e2c3688691bc4c6245d0806b3"
integrity sha512-OnhVSoKD1HzBB79/rFzPbC4w9TdzFXeoOwkX+aIu3rb8qvN0VaqvUqZXSrBCyG2LcLyVkY4MPCJQBrmEUm9kvw==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-http" "^1.2.0"
"@azure/core-lro" "^1.0.2"
"@azure/core-paging" "^1.1.1"
"@azure/core-tracing" "1.0.0-preview.9"
"@azure/logger" "^1.0.0"
"@opentelemetry/api" "^0.10.2"
events "^3.0.0"
tslib "^2.0.0"
"@malept/cross-spawn-promise@^1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d"
@ -26,6 +115,23 @@
dependencies:
cross-spawn "^7.0.1"
"@opencensus/web-types@0.0.7":
version "0.0.7"
resolved "https://registry.yarnpkg.com/@opencensus/web-types/-/web-types-0.0.7.tgz#4426de1fe5aa8f624db395d2152b902874f0570a"
integrity sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g==
"@opentelemetry/api@^0.10.2":
version "0.10.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.10.2.tgz#9647b881f3e1654089ff7ea59d587b2d35060654"
integrity sha512-GtpMGd6vkzDMYcpu2t9LlhEgMy/SzBwRnz48EejlRArYqZzqSzAsKmegUK7zHgl+EOIaK9mKHhnRaQu3qw20cA==
dependencies:
"@opentelemetry/context-base" "^0.10.2"
"@opentelemetry/context-base@^0.10.2":
version "0.10.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.10.2.tgz#55bea904b2b91aa8a8675df9eaba5961bddb1def"
integrity sha512-hZNKjKOYsckoOEgBziGMnBcX0M7EtstnCmwz5jZUOUYwlZ+/xxX6z3jPu1XVO2Jivk0eLfuP9GP+vFD49CMetw==
"@types/ansi-colors@^3.2.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@types/ansi-colors/-/ansi-colors-3.2.0.tgz#3e4fe85d9131ce1c6994f3040bd0b25306c16a6e"
@ -199,11 +305,26 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
"@types/mkdirp@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.1.tgz#0930b948914a78587de35458b86c907b6e98bbf6"
integrity sha512-HkGSK7CGAXncr8Qn/0VqNtExEE+PHMWb+qlR1faHMao7ng6P3tAaoWWBMdva0gL5h4zprjIO89GJOLXsMcDm1Q==
dependencies:
"@types/node" "*"
"@types/mocha@^8.2.0":
version "8.2.0"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.0.tgz#3eb56d13a1de1d347ecb1957c6860c911704bc44"
integrity sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==
"@types/node-fetch@^2.5.0":
version "2.5.8"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.8.tgz#e199c835d234c7eb0846f6618012e558544ee2fb"
integrity sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw==
dependencies:
"@types/node" "*"
form-data "^3.0.0"
"@types/node@*":
version "8.0.51"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
@ -219,6 +340,13 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18"
integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==
"@types/p-limit@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@types/p-limit/-/p-limit-2.2.0.tgz#94a608e9b258a6c6156a13d1a14fd720dba70b97"
integrity sha512-fGFbybl1r0oE9mqgfc2EHHUin9ZL5rbQIexWI6jYRU1ADVn4I3LHzT+g/kpPpZsfp8PB94CQ655pfAjNF8LP6A==
dependencies:
p-limit "*"
"@types/plist@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01"
@ -271,6 +399,13 @@
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.2.tgz#e0d481d8bb282ad8a8c9e100ceb72c995fb5e709"
integrity sha512-vOVmaruQG5EatOU/jM6yU2uCp3Lz6mK1P5Ztu4iJjfM4SVHU9XYktPUQtKlIXuahqXHdEyUarMrBEwg5Cwu+bA==
"@types/tunnel@^0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.1.tgz#0d72774768b73df26f25df9184273a42da72b19c"
integrity sha512-AOqu6bQu5MSWwYvehMXLukFHnupHrpZ8nvgae5Ggie9UwzDR1CCwoXgSSWNZJuyOlCdfdsWMA5F2LlmvyoTv8A==
dependencies:
"@types/node" "*"
"@types/underscore@^1.8.9":
version "1.8.9"
resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.8.9.tgz#fef41f800cd23db1b4f262ddefe49cd952d82323"
@ -563,7 +698,7 @@ colors@1.0.3:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
combined-stream@^1.0.6, combined-stream@~1.0.6:
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
@ -792,6 +927,11 @@ estraverse@^4.1.0, estraverse@^4.1.1:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
events@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==
extend@^3.0.2, extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
@ -829,6 +969,15 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
@ -1214,6 +1363,13 @@ osenv@^0.1.3:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-limit@*, p-limit@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
dependencies:
yocto-queue "^0.1.0"
parse-semver@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/parse-semver/-/parse-semver-1.1.1.tgz#9a4afd6df063dc4826f93fba4a99cf223f666cb8"
@ -1267,7 +1423,12 @@ process-nextick-args@~1.0.6:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=
psl@^1.1.28:
process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
psl@^1.1.28, psl@^1.1.33:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
@ -1370,6 +1531,11 @@ sax@0.5.x:
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=
sax@>=0.6.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
semaphore@^1.0.5:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
@ -1448,6 +1614,15 @@ tmp@0.0.29:
dependencies:
os-tmpdir "~1.0.1"
tough-cookie@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==
dependencies:
psl "^1.1.33"
punycode "^2.1.1"
universalify "^0.1.2"
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
@ -1485,6 +1660,11 @@ tunnel@0.0.4:
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.4.tgz#2d3785a158c174c9a16dc2c046ec5fc5f1742213"
integrity sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@ -1528,6 +1708,11 @@ universal-user-agent@^6.0.0:
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
@ -1640,6 +1825,14 @@ xml2js@0.2.8:
dependencies:
sax "0.5.x"
xml2js@^0.4.19:
version "0.4.23"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
dependencies:
sax ">=0.6.0"
xmlbuilder "~11.0.0"
xmlbuilder@>=11.0.1:
version "15.1.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5"
@ -1650,6 +1843,11 @@ xmlbuilder@^9.0.7:
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
xmlbuilder@~11.0.0:
version "11.0.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
xmldom@0.1.x:
version "0.1.31"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff"
@ -1675,6 +1873,11 @@ yazl@^2.2.2:
dependencies:
buffer-crc32 "~0.2.3"
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zone.js@0.7.6:
version "0.7.6"
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009"