diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..981995b5 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,22 @@ +{ + "extends": [ + "axway/env-node", + "axway/+mocha", + "axway/+chai", + "axway/+typescript" + ], + "rules": { + "no-confusing-arrow": "off", + "no-ex-assign": "off", + "node/no-unsupported-features/es-syntax": "off", + "node/no-unsupported-features/node-builtins": [ + "warn", + { + "version": ">=14.15.0" + } + ], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-expressions": "off", + "@typescript-eslint/no-empty-function": "off" + } +} diff --git a/.gitattributes b/.gitattributes index 7d8aff32..59b9af54 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ *.js text eol=lf +*.md text eol=lf *.mustache text eol=lf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 70648e1e..42543be5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,16 +7,16 @@ jobs: Lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v3 with: - node-version: '12.x' + node-version: '16.x' - name: Install dependencies run: yarn - name: Lint - run: yarn run gulp lint + run: yarn run lint Test: needs: Lint @@ -25,13 +25,13 @@ jobs: strategy: fail-fast: false matrix: - nodeVersion: [ '12.18.0', '14.15.1', '16.8.0' ] + nodeVersion: [ '14.19.3', '16.15.1', '18.4.0' ] os: [ macos-latest, ubuntu-latest, windows-latest ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v3 with: node-version: ${{ matrix.nodeVersion }} - name: Install dependencies diff --git a/.gitignore b/.gitignore index 483f550f..37f2f461 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,10 @@ .DS_Store* .npm-info .nyc_output -/coverage +.turbo +coverage/** +build/** +dist gulpfile.tmp.* junit.xml lerna-debug.log diff --git a/Jenkinsfile b/Jenkinsfile index f341bd36..0092b237 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -2,7 +2,7 @@ library 'pipeline-library' runNPMPackage { - nodeVersions = [ '12.18.0', '14.15.1' ] + nodeVersions = [ '14.15.1' ] packageJsonPath = 'packages/axway-cli/package.json' platforms = [ 'linux', 'osx' ] publish = false diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 47fc23e2..00000000 --- a/gulpfile.js +++ /dev/null @@ -1,504 +0,0 @@ -'use strict'; - -const ansiColors = require('ansi-colors'); -const chug = require('gulp-chug'); -const debug = require('gulp-debug'); -const fs = require('fs-extra'); -const gulp = require('gulp'); -const log = require('fancy-log'); -const path = require('path'); -const plumber = require('gulp-plumber'); -const semver = require('semver'); -const spawnSync = require('child_process').spawnSync; -const tmp = require('tmp'); - -const { series } = gulp; -const { red, yellow, green, cyan, magenta, gray } = ansiColors; - -const nodeInfo = exports['node-info'] = async function nodeInfo() { - log(`Node.js ${process.version} (${process.platform})`); - log(process.env); -}; - -// checks to see if a package requires a node version that is less than a dependencies node requirement -exports['check-engines'] = async function checkEngines() { - const cache = {}; - const issues = []; - - const checkPackage = (pkgPath, depth = 0) => { - const pkgJsonPath = path.join(pkgPath, 'package.json'); - if (!fs.existsSync(pkgJsonPath)) { - return false; - } - - if (cache[pkgPath]) { - return cache[pkgPath]; - } - - const pkgJson = require(pkgJsonPath); - const info = pkgJson.engines && pkgJson.engines.node && semver.coerce(pkgJson.engines.node); - const node = cache[pkgPath] = info ? info.version : null; - - // console.log(`${' '.repeat(depth)}${green(pkgJson.name)}${node ? ` (${node})` : ''}`); - - if (pkgJson.dependencies) { - for (const dep of Object.keys(pkgJson.dependencies)) { - for (let wd = pkgPath; true; wd = path.dirname(wd)) { - const depNode = checkPackage(path.join(wd, 'node_modules', dep), depth + 1); - if (!cache[pkgPath] || (depNode && semver.gt(depNode, cache[pkgPath]))) { - cache[pkgPath] = depNode; - } - if (/^@axway/.test(pkgJson.name) && node && depNode && semver.lt(node, depNode)) { - issues.push({ - name: pkgJson.name, - node, - dep, - depNode - }); - break; - } - if (depNode !== false) { - // depNode is null (no node version) or a string - break; - } - if (wd === __dirname) { - throw new Error(`Unable to find dependency "${dep}"`); - } - } - } - } - - return cache[pkgPath]; - }; - - const nodeVer = checkPackage(`${__dirname}/packages/axway-cli`); - console.log(`\nMinimum Node version should be ${cyan(nodeVer)}\n`); - - if (issues.length) { - console.log(`Found ${issues.length} issue${issues.length === 1 ? '' : 's'}`); - console.log(issues.map(({ name, node, dep, depNode }) => ` ${green(name)} requires ${node}\n ${cyan(dep)} requires ${depNode}`).join('\n') + '\n'); - } -}; - -/* - * lint tasks - */ -exports.lint = function lint() { - return gulp - .src([ - path.join(__dirname, 'packages/*/gulpfile.js') - ]) - .pipe(debug({ title: 'Linting project:' })) - .pipe(plumber()) - .pipe(chug({ tasks: [ 'lint' ] })); -}; - -/* - * build tasks - */ -const build = exports.build = async function build() { - return runLernaBuild(); -}; - -/* - * test tasks - */ -let origHomeDir = process.env.HOME; -let tmpHomeDir = null; - -async function runTests(cover, all) { - try { - await fs.remove(path.join(__dirname, '.nyc_output')); - await fs.remove(path.join(__dirname, 'coverage')); - - if (all) { - process.env.AXWAY_TEST = '1'; // allow telemetry tests to run - } - process.env.AXWAY_TEST_GLOBAL_PACKAGE_DIR = path.join(__dirname, 'packages'); - process.env.SPAWN_WRAP_SHIM_ROOT = origHomeDir; - process.env.NODE_ENV = 'test'; // disables the update check - // process.env.SNOOPLOGG = '*'; - - tmpHomeDir = tmp.dirSync({ - mode: '755', - prefix: 'axway-cli-test-home-', - unsafeCleanup: true - }).name; - - log(`Protecting home directory, overriding HOME with temp dir: ${cyan(tmpHomeDir)}`); - process.env.HOME = process.env.USERPROFILE = tmpHomeDir; - if (process.platform === 'win32') { - process.env.HOMEDRIVE = path.parse(tmpHomeDir).root.replace(/[\\/]/g, ''); - process.env.HOMEPATH = tmpHomeDir.replace(process.env.HOMEDRIVE, ''); - } - - const runner = require('@axway/gulp-tasks/src/test-runner'); - await runner.runTests({ - all, - cover, - projectDir: __dirname, - root: __dirname, - slow: 15000, - timeout: 40000 - }); - } finally { - // restore home directory so that we can delete the temp one - if (tmpHomeDir) { - log(`Removing temp home directory: ${cyan(tmpHomeDir)}`); - try { - fs.removeSync(tmpHomeDir); - } catch (err) { - log(`Failed to remove temp home directory: ${err.toString()}`); - } - } - - log(`Restoring home directory: ${cyan(origHomeDir)}`); - process.env.HOME = origHomeDir; - } -} - -exports.integration = series(nodeInfo, build, function test() { return runTests(true); }); -exports['integration-only'] = series(nodeInfo, function test() { return runTests(true); }); -exports.test = series(nodeInfo, build, function coverage() { return runTests(true, true); }); - -/* - * watch task - */ -exports.watch = series(build, async function watch() { - const srcWatcher = gulp - .watch(`${__dirname}/packages/*/src/**/*.js`) - .on('all', (type, path) => { - // FIXME: There's almost certainly a better way of doing this than replacing \\ with / - path = path.replace(/\\/g, '/'); - const m = path.match(new RegExp(`^(${__dirname.replace(/\\/g, '/')}/(packages/([^\/]+)))`)); - if (m) { - log(`Detected change: ${cyan(path)}`); - const pkgJson = path.join(m[1], 'package.json'); - - try { - runLernaBuild(JSON.parse(fs.readFileSync(pkgJson)).name); - } catch (e) { - log(`Failed to read/parse ${pkgJson}: ${e.toString()}`); - } - } - }); - - let stopping = false; - - return new Promise(resolve => { - process.on('SIGINT', () => { - if (!stopping) { - stopping = true; - srcWatcher.close(); - resolve(); - } - }); - }); -}); - -async function runLernaBuild(scope) { - let { execPath } = process; - const args = [ './node_modules/.bin/lerna', 'run', 'build', '--parallel' ]; - - if (process.platform === 'win32') { - args.shift(); - execPath = path.join(__dirname, 'node_modules', '.bin', 'lerna.cmd'); - } - - if (scope) { - args.push('--scope', scope); - } - - log(`Running ${execPath} ${args.join(' ')}`); - const { status } = spawnSync(execPath, args, { stdio: 'inherit' }); - if (status) { - throw new Error(`lerna build failed ${scope ? `for ${scope}` : ''}`); - } -} - -exports['release-notes'] = async function releaseNotes() { - const { cyan } = require('ansi-colors'); - const https = require('https'); - const semver = require('semver'); - const tar = require('tar-stream'); - const zlib = require('zlib'); - - const packages = {}; - const re = /^@axway\//; - const tempDir = tmp.dirSync({ - mode: '755', - prefix: 'axway-cli-release-notes-', - unsafeCleanup: true - }).name; - const cacheDir = path.join(__dirname, '.npm-info'); - - await fs.mkdirs(cacheDir); - - const fetch = async name => { - const cacheFile = path.join(cacheDir, `${name}.json`); - await fs.mkdirs(path.dirname(cacheFile)); - let info; - - if (fs.existsSync(cacheFile)) { - log(`Fetching ${cyan(name)} from cache`); - const s = fs.readFileSync(cacheFile, 'utf8'); - info = s ? JSON.parse(s) : null; - } else { - log(`Fetching ${cyan(name)}`); - const { status, stdout, stderr } = spawnSync('npm', [ 'view', name, '--json' ]); - if (status) { - console.error('Failed to get package info:'); - console.error(stdout.toString()); - console.error(stderr.toString()); - process.exit(1); - } - const s = stdout.toString(); - fs.writeFileSync(cacheFile, s); - - info = s ? JSON.parse(s) : null; - } - - // if more than one is returned, get the latest - if (Array.isArray(info)) { - let pkg; - for (const i of info) { - if (!pkg || semver.gt(i.version, pkg.version)) { - pkg = i; - } - } - info = pkg; - } - - return info; - }; - - const getPackageInfo = async (name, ver) => { - const info = await fetch(`${name}@${ver}`); - if (!info || packages[name]) { - return info; - } - - ver = info.version; - - log(`Initializing new package ${name}`); - packages[name] = { latest: null, versions: {} }; - - log(` Versions: ${info.versions.join(', ')}`); - for (const version of info.versions) { - if (!packages[name].versions[version] && semver.valid(version) && semver.gt(version, '0.0.0')) { - const { prerelease } = semver.parse(version); - if (!prerelease || !prerelease.length) { - log(` Initializing pacakge ${name}@${version}`); - const verInfo = await fetch(`${name}@${version}`); - if (verInfo) { - packages[name].versions[version] = { changelog: null, ts: info.time[version], version }; - for (const type of [ 'dependencies', 'devDependencies' ]) { - if (verInfo[type]) { - for (const [ dep, range ] of Object.entries(verInfo[type])) { - if (re.test(dep)) { - await getPackageInfo(dep, range); - } - } - } - } - } - } - } - } - - return info; - }; - - const processChangelog = (name, changelog) => { - const changes = changelog.split('\n\n#').map((s, i) => `${i ? '#' : ''}${s}`.trim()); - for (const chunk of changes) { - const m = chunk.match(/^# v?([^\s\n]*)[^\n]*\n+(.+)$/s); - if (!m) { - continue; - } - - const { version } = semver.coerce(m[1]); - - if (packages[name].versions[m[1]]) { - packages[name].versions[m[1]].changelog = m[2]; - } else if (packages[name].versions[version]) { - packages[name].versions[version].changelog = m[2]; - } else { - log(red(`Package ${name} does not have a version ${m[1]}! (${Object.keys(packages[name].versions).join(', ')})`)); - } - } - }; - - try { - // Step 1: get all the `axway` releases and their `@axway/*` dependencies - const { versions } = await fetch('axway'); - for (const ver of versions) { - if (semver.valid(ver) && semver.gt(ver, '0.0.0')) { - const { prerelease } = semver.parse(ver); - if (!prerelease || !prerelease.length) { - await getPackageInfo('axway', ver); - } - } - } - - // Step 2: add in the local packages - const local = {}; - for (const subdir of fs.readdirSync(path.join(__dirname, 'packages'))) { - try { - const pkgJson = fs.readJsonSync(path.join(__dirname, 'packages', subdir, 'package.json')); - let { name, version } = pkgJson; - local[name] = pkgJson; - const changelogFile = path.join(__dirname, 'packages', subdir, 'CHANGELOG.md'); - const changelog = fs.existsSync(changelogFile) ? fs.readFileSync(changelogFile, 'utf8') : null; - let ts = null; - - const m = changelog && changelog.match(/^# v([^\s]+)/); - if (m && m[1] !== version) { - // set release timestamp to now unless package is axway, then make it 10 seconds older - ts = new Date(Date.now() + (name === 'axway' || name === '@axway/amplify-cli' ? 10000 : 0)); - pkgJson.version = version = m[1]; - } - - // TEMP: another v2 prerelease hack - version = semver.coerce(version).version; - if (name === '@axway/amplify-cli') { - name = 'axway'; - } - - if (!packages[name]) { - packages[name] = { latest: null, versions: {} }; - } - - if (!packages[name] || !packages[name].versions[version]) { - packages[name].local = true; - packages[name].versions[version] = { changelog: null, local: true, ts, version }; - } - - if (changelog) { - processChangelog(name, changelog); - } - } catch (e) {} - } - - // Step 3: for each non-local package, fetch the latest npm package and extract the changelog - for (const [ pkg, info ] of Object.entries(packages)) { - if (!packages[pkg].latest) { - packages[pkg].latest = Object.keys(info.versions).sort(semver.compare).pop(); - } - - if (info.local) { - continue; - } - - const changelogFile = path.join(cacheDir, `${pkg}@${info.latest}_CHANGELOG.md`); - if (fs.existsSync(changelogFile)) { - processChangelog(pkg, fs.readFileSync(changelogFile, 'utf8')); - } else { - const url = `https://registry.npmjs.org/${pkg}/-/${path.basename(pkg)}-${info.latest}.tgz`; - const file = path.join(tempDir, `${path.basename(pkg)}-${info.latest}.tgz`); - - await new Promise((resolve, reject) => { - const dest = fs.createWriteStream(file); - dest.on('finish', () => dest.close(resolve)); - log(`Downloading ${cyan(url)}`); - https.get(url, response => response.pipe(dest)) - .on('error', reject); - }); - - await new Promise((resolve, reject) => { - const gunzip = zlib.createGunzip(); - const extract = tar.extract(); - - extract.on('entry', (header, stream, next) => { - if (header.name !== 'package/CHANGELOG.md') { - stream.resume(); - return next(); - } - - let changelog = ''; - stream - .on('data', chunk => changelog += chunk) - .on('end', () => { - fs.writeFileSync(changelogFile, changelog, 'utf8'); - processChangelog(pkg, changelog); - next(); - }) - .on('error', reject) - .resume(); - }); - - extract.on('finish', resolve); - extract.on('error', reject); - - log(`Extract changelog from ${cyan(file)}`); - fs.createReadStream(file).pipe(gunzip).pipe(extract); - }); - } - } - } finally { - fs.removeSync(tempDir); - } - - const axwayCli = packages['axway']; - delete packages['axway']; - const pkgs = Object.keys(packages).sort(); - - // Step 4: loop over every `axway` release and generate the changelog - for (const ver of Object.keys(axwayCli.versions).sort(semver.compare)) { - const { raw } = semver.coerce(ver); - if (semver.lte(raw, '2.0.0')) { - continue; - } - const { major, minor, patch } = semver.parse(ver); - const cleanVersion = `${major}.${minor}.${patch}`; - const dest = path.join(__dirname, 'docs', 'Release Notes', `Axway CLI ${raw}.md`); - const { changelog, local, ts } = axwayCli.versions[ver]; - const dt = ts ? new Date(ts) : new Date(); - const rd = ts && dt.toDateString().split(' ').slice(1); - let s = `# Axway CLI ${raw}\n\n## ${local ? 'Unreleased' : `${rd[0]} ${rd[1]}, ${rd[2]}`}\n\n`; - - if (patch === 0) { - if (minor === 0) { - s += 'This is a major release with breaking changes, new features, bug fixes, and dependency updates.\n\n'; - } else { - s += 'This is a minor release with new features, bug fixes, and dependency updates.\n\n'; - } - } else { - s += 'This is a patch release with bug fixes and minor dependency updates.\n\n'; - } - s += `### Installation\n\n\`\`\`\nnpm i -g axway@${cleanVersion}\n\`\`\`\n\n` - if (changelog) { - s += '### axway\n\n'; - s += ` * **v${cleanVersion}**${ts ? ` - ${dt.toLocaleDateString()}` : ''}\n\n`; - s += `${changelog.split('\n').map(s => ` ${s}`).join('\n')}\n\n`; - } - - for (const pkg of pkgs) { - // the AMPLIFY CLI and Auth SDK are deprecated, so ignore them - if (pkg === '@axway/amplify-cli' || pkg === '@axway/amplify-auth-sdk') { - continue; - } - - const vers = Object.keys(packages[pkg].versions).filter(ver => { - const { ts } = packages[pkg].versions[ver]; - return !ts || new Date(ts) < dt; - }).sort(semver.rcompare); - - let vs = ''; - for (const v of vers) { - if (packages[pkg].versions[v].changelog) { - const pts = new Date(packages[pkg].versions[v].ts); - vs += ` * **v${v}** - ${pts.toLocaleDateString()}\n\n`; - vs += `${packages[pkg].versions[v].changelog.split('\n').map(s => ` ${s}`).join('\n')}\n\n`; - } - delete packages[pkg].versions[v]; - } - if (vs) { - s += `### ${pkg.replace(/@.+\//, '')}\n\n${vs}`; - } - } - - log(`Writing release notes ${cyan(dest)}`); - fs.outputFileSync(dest, s.trim()); - } -}; diff --git a/package.json b/package.json index 5ede9884..c39bf054 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,66 @@ { "name": "amplify-tooling", "version": "0.0.0", + "type": "module", "private": true, "dependencies": { - "@axway/gulp-tasks": "^4.1.4", - "@koa/router": "^10.1.1", - "ansi-colors": "^4.1.1", - "caller-path": "^3.0.1", + "@koa/router": "^11.0.1", + "@types/chai": "^4.3.1", + "@types/chai-as-promised": "^7.1.5", + "@types/cross-spawn": "^6.0.2", + "@types/ejs": "^3.1.1", + "@types/fs-extra": "^9.0.13", + "@types/jws": "^3.2.4", + "@types/koa": "^2.13.4", + "@types/koa-bodyparser": "^4.3.7", + "@types/koa-session": "^5.10.6", + "@types/koa__router": "^8.0.11", + "@types/libnpmsearch": "^2.0.3", + "@types/lodash.get": "^4.4.7", + "@types/lodash.set": "^4.3.7", + "@types/mocha": "^9.1.1", + "@types/node": "^18.0.3", + "@types/npm-package-arg": "^6.1.1", + "@types/pacote": "^11.1.5", + "@types/pluralize": "^0.0.29", + "@types/semver": "^7.3.10", + "@types/set-cookie-parser": "^2.4.2", + "@types/tmp": "^0.2.3", + "@types/uuid": "^8.3.4", + "@types/which": "^2.0.1", + "@typescript-eslint/eslint-plugin": "^5.30.5", + "@typescript-eslint/parser": "^5.30.5", + "c8": "^7.11.3", + "caller-path": "^4.0.0", "chai": "^4.3.6", - "chalk": "^4.1.2", + "chai-as-promised": "^7.1.1", + "chalk": "^5.0.1", + "concurrently": "^7.2.2", + "eslint": "^8.19.0", + "eslint-config-axway": "^7.0.1", + "eslint-plugin-chai-friendly": "^0.7.2", + "eslint-plugin-mocha": "^10.0.5", + "find-up": "^6.3.0", "fs-extra": "^10.1.0", - "got": "^11.8.3", - "gulp": "^4.0.2", - "gulp-chug": "^0.5.1", - "gulp-debug": "^4.0.0", - "gulp-plumber": "^1.2.1", + "got": "^12.1.0", "jws": "^4.0.0", "koa": "^2.13.4", "koa-bodyparser": "^4.3.0", - "lerna": "^4.0.0", - "mocha": "^9.2.2", + "lerna": "^5.1.8", + "mocha": "^10.0.0", "mustache": "^4.2.0", - "pretty-log": "^0.1.0", "semver": "^7.3.7", + "snooplogg": "^5.0.0", "tar-stream": "^2.2.0", + "ts-mocha": "^10.0.0", + "ts-node": "^10.8.2", + "turbo": "^1.3.1", + "typescript": "^4.7.4", "uuid": "^8.3.2" }, "scripts": { - "build": "lerna exec gulp build", - "test": "yarn run gulp test" + "build": "turbo run build", + "test": "turbo run build && node scripts/run-tests.js --all --coverage" }, "workspaces": { "packages": [ diff --git a/packages/amplify-cli-utils/.gitignore b/packages/amplify-cli-utils/.gitignore deleted file mode 100644 index b3a1d215..00000000 --- a/packages/amplify-cli-utils/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -._* -.DS_Store* -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log -yarn-error.log diff --git a/packages/amplify-cli-utils/CHANGELOG.md b/packages/amplify-cli-utils/CHANGELOG.md index 982bf92e..01b7373c 100644 --- a/packages/amplify-cli-utils/CHANGELOG.md +++ b/packages/amplify-cli-utils/CHANGELOG.md @@ -1,3 +1,8 @@ +# v6.0.0 + +- BREAKING CHANGE: Dropped support for Node.js 12 and older. +- chore: Updated dependencies. + # v5.0.11 (Jul 7, 2022) - chore: Updated dependencies. diff --git a/packages/amplify-cli-utils/gulpfile.js b/packages/amplify-cli-utils/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/amplify-cli-utils/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/amplify-cli-utils/package.json b/packages/amplify-cli-utils/package.json index d14a45ab..60b8c6b5 100644 --- a/packages/amplify-cli-utils/package.json +++ b/packages/amplify-cli-utils/package.json @@ -5,6 +5,9 @@ "access": "public" }, "description": "Common utils for Axway CLI packages", + "type": "module", + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", "author": "Axway, Inc. ", "maintainers": [ "Ewan Harris ", @@ -15,34 +18,29 @@ "axway", "amplify" ], - "main": "./dist/index", "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "c8 npm run test", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:test npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:test": "eslint --parser-options=project:'test/tsconfig.json' test/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "ts-mocha -n loader=ts-node/esm test/**/test-*.ts --require ../../test/setup.js --reporter spec" }, "dependencies": { "@axway/amplify-config": "^4.0.9", "@axway/amplify-request": "^3.0.10", - "@axway/amplify-sdk": "^3.2.7", - "boxen": "^5.1.2", - "check-kit": "^1.2.1", - "cli-kit": "^1.16.0", + "@axway/amplify-sdk": "^3.2.6", + "cli-kit": "^2.0.2", "cli-table3": "^0.6.2", "fs-extra": "^10.1.0", - "snooplogg": "^3.0.2", - "source-map-support": "^0.5.21" - }, - "devDependencies": { - "@axway/gulp-tasks": "^4.1.4" + "snooplogg": "^5.0.0" }, "homepage": "https://github.com/appcelerator/amplify-tooling#readme", "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/amplify-cli-utils", "engines": { - "node": ">=12.13.0" - }, - "gitHead": "9cc288d8ee067fb3444920aad11c53899455ad9c" + "node": ">=14.15.0" + } } diff --git a/packages/amplify-cli-utils/src/environments.js b/packages/amplify-cli-utils/src/environments.js deleted file mode 100644 index 5da803ed..00000000 --- a/packages/amplify-cli-utils/src/environments.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Environment specific settings. - * - * @type {Object} - */ -export const environments = { - dev: { - auth: { - clientId: 'cli-test-public', - realm: 'Broker' - }, - registry: { - url: 'http://localhost:8082' - }, - title: 'Development' - }, - staging: { - auth: { - clientId: 'amplify-cli', - realm: 'Broker' - }, - registry: { - url: 'https://registry.axwaytest.net' - }, - title: 'Staging' - }, - prod: { - auth: { - clientId: 'amplify-cli', - realm: 'Broker' - }, - registry: { - url: 'https://registry.platform.axway.com' - }, - title: 'Production' - } -}; - -const mapping = { - development: 'dev', - preprod: 'staging', - preproduction: 'staging', - 'pre-production': 'staging', - production: 'prod', - test: 'staging' -}; - -export function resolve(env) { - let environment = 'prod'; - if (env) { - if (typeof env !== 'string') { - throw new TypeError('Expected environment to be a string'); - } - environment = env.toLowerCase(); - environment = mapping[environment] || environment; - if (!environments[environment]) { - throw new Error(`Invalid environment "${env}"`); - } - } - - return { - name: environment, - ...environments[environment] - }; -} diff --git a/packages/amplify-cli-utils/src/environments.ts b/packages/amplify-cli-utils/src/environments.ts new file mode 100644 index 00000000..7678c317 --- /dev/null +++ b/packages/amplify-cli-utils/src/environments.ts @@ -0,0 +1,81 @@ +import { Environment } from './types.js'; + +interface EnvironmentDefaults { + auth: { + clientId: string, + realm: string + }, + title: string +} + +interface EnvironmentDefaultsMap { + dev: EnvironmentDefaults, + staging: EnvironmentDefaults, + prod: EnvironmentDefaults +} + +/** + * Environment specific settings. + * + * @type {Object} + */ +export const environments: EnvironmentDefaultsMap = { + dev: { + auth: { + clientId: 'cli-test-public', + realm: 'Broker' + }, + title: 'Development' + }, + staging: { + auth: { + clientId: 'amplify-cli', + realm: 'Broker' + }, + title: 'Staging' + }, + prod: { + auth: { + clientId: 'amplify-cli', + realm: 'Broker' + }, + title: 'Production' + } +}; + +interface EnvironmentMapping { + development: string, + preprod: string, + preproduction: string, + 'pre-production': string, + production: string, + test: string, +} + +const mapping: EnvironmentMapping = { + development: 'dev', + preprod: 'staging', + preproduction: 'staging', + 'pre-production': 'staging', + production: 'prod', + test: 'staging' +}; + +export function resolve(env: string): Environment { + let environment = 'prod'; + if (env) { + if (typeof env !== 'string') { + throw new TypeError('Expected environment to be a string'); + } + environment = env.toLowerCase(); + environment = mapping[environment as keyof EnvironmentMapping] || environment; + if (!environments[environment as keyof EnvironmentDefaultsMap]) { + throw new Error(`Invalid environment "${env}"`); + } + } + + return { + name: environment, + ...environments[environment as keyof EnvironmentDefaultsMap] + } as Environment; +} diff --git a/packages/amplify-cli-utils/src/index.js b/packages/amplify-cli-utils/src/index.ts similarity index 59% rename from packages/amplify-cli-utils/src/index.js rename to packages/amplify-cli-utils/src/index.ts index 34ea4e91..cadb121f 100644 --- a/packages/amplify-cli-utils/src/index.js +++ b/packages/amplify-cli-utils/src/index.ts @@ -1,20 +1,21 @@ -/* istanbul ignore if */ -if (!Error.prepareStackTrace) { - require('source-map-support/register'); -} - -import AmplifySDK, { Telemetry } from '@axway/amplify-sdk'; -import boxen from 'boxen'; -import check from 'check-kit'; +import AmplifySDK, { AmplifySDKOptions, Telemetry } from '@axway/amplify-sdk'; import fs from 'fs'; import loadConfig, { Config } from '@axway/amplify-config'; +import Table from 'cli-table3'; import snooplogg from 'snooplogg'; import { ansi } from 'cli-kit'; -import { createNPMRequestArgs, createRequestClient, createRequestOptions } from './request'; -import * as environments from './environments'; -import * as locations from './locations'; +import { + AxwayCLIContext, + AxwayCLIOptionCallbackState, + AxwayCLIState, + BuildAuthParamsOptions, + InitPlatformAccountResult +} from './types.js'; +import { createNPMRequestArgs, createRequestClient, createRequestOptions } from './request.js'; +import * as environments from './environments.js'; +import * as locations from './locations.js'; import * as request from '@axway/amplify-request'; -import * as telemetry from './telemetry'; +import * as telemetry from './telemetry.js'; export { AmplifySDK, @@ -30,8 +31,16 @@ export { telemetry }; +export type { + AxwayCLIContext, + AxwayCLIOptionCallbackState, + AxwayCLIState, + BuildAuthParamsOptions, + InitPlatformAccountResult +}; + const { warn } = snooplogg('amplify-cli-utils'); -const { cyan, gray, green } = snooplogg.chalk; +const { green } = snooplogg.chalk; /** * Constructs a parameters object to pass into an Auth instance. @@ -40,20 +49,20 @@ const { cyan, gray, green } = snooplogg.chalk; * @param {Config} [config] - The Amplify config object. * @returns {Object} */ -export function buildAuthParams(opts = {}, config) { +export async function buildAuthParams(opts: BuildAuthParamsOptions = {}, config?: Config): Promise { if (!opts || typeof opts !== 'object') { throw new Error('Expected options to be an object'); } if (!config) { - config = loadConfig(); + config = await loadConfig(); } const env = environments.resolve(opts.env || config.get('env')); const { clientId, realm } = env.auth; - const params = {}; - const props = { + const params: AmplifySDKOptions = {}; + const props: BuildAuthParamsOptions = { baseUrl: undefined, clientId, clientSecret: undefined, @@ -76,7 +85,9 @@ export function buildAuthParams(opts = {}, config) { }; for (const prop of Object.keys(props)) { - params[prop] = opts[prop] !== undefined ? opts[prop] : config.get(`auth.${prop}`, props[prop]); + params[prop as keyof AmplifySDKOptions] = opts[prop as keyof BuildAuthParamsOptions] !== undefined + ? opts[prop as keyof BuildAuthParamsOptions] + : config.get(`auth.${prop}`, props[prop as keyof BuildAuthParamsOptions]); } // detect if we're headless and default token store type to `file` @@ -85,12 +96,12 @@ export function buildAuthParams(opts = {}, config) { config.set('auth.tokenStoreType', 'file'); try { config.save(); - } catch (err) { + } catch (err: any) { warn(err); } } - params.requestOptions = createRequestOptions(opts, config); + params.requestOptions = await createRequestOptions(opts.requestOptions, config); return params; } @@ -99,50 +110,6 @@ export function buildAuthParams(opts = {}, config) { // maintain backwards compatibility export { buildAuthParams as buildParams }; -/** - * Checks if a new version of an npm package is available and returns a string with the formatted - * update message. - * - * @param {Object} [opts] - Check update and request configuration options. - * @param {Number} [opts.checkInterval=3600000] - The amount of time in milliseconds before - * checking for an update. Defaults to 1 hour. - * @param {String} [opts.cwd] - The current working directory used to locate the `package.json` if - * `pkg` is not specified. - * @param {String} [opts.distTag='latest'] - The tag to check for the latest version. - * @param {Boolean} [opts.force=false] - Forces an update check. - * @param {String} [opts.metaDir] - The directory to store package update information. - * @param {Object|String} [opts.pkg] - The parsed `package.json`, path to the package.json file, or - * falsey and it will scan parent directories looking for a package.json. - * @param {String} [opts.registryUrl] - The npm registry URL. By default, it will autodetect the - * URL based on the package name/scope. - * @param {Number} [opts.timeout=1000] - The number of milliseconds to wait to query npm before - * timing out. - * @param {Config} [config] - An Amplify Config instance. If not specified, the config is loaded - * from disk. - * @returns {String} - */ -export async function checkForUpdate(opts, config) { - opts = createRequestOptions(opts, config || loadConfig()); - - const { - current, - latest, - name, - updateAvailable - } = await check(opts); - - if (updateAvailable) { - const msg = `Update available ${gray(current)} → ${green(latest)}\nRun ${cyan(`npm i -g ${name}`)} to update`; - return boxen(msg, { - align: 'center', - borderColor: 'yellow', - borderStyle: 'round', - margin: { bottom: 1, left: 4, right: 4, top: 1 }, - padding: { bottom: 1, left: 4, right: 4, top: 1 } - }); - } -} - /** * Creates a table with default styles and padding. * @@ -150,8 +117,7 @@ export async function checkForUpdate(opts, config) { * @param {Number} [indent] - The number of spaces to indent the table. * @returns {Table} */ -export function createTable(head, indent = 0) { - const Table = require('cli-table3'); +export function createTable(head?: string[], indent = 0) { return new Table({ chars: { bottom: '', 'bottom-left': '', 'bottom-mid': '', 'bottom-right': '', @@ -180,7 +146,7 @@ export function createTable(head, indent = 0) { * @example * config.get(`${getAuthConfigEnvSpecifier(sdk.env.name)}.defaultAccount`); */ -export function getAuthConfigEnvSpecifier(env) { +export function getAuthConfigEnvSpecifier(env: string): string { return !env || env === 'prod' ? 'auth' : `auth.environment.${env}`; } @@ -191,22 +157,21 @@ export function getAuthConfigEnvSpecifier(env) { * @param {String} fromVer - The current version. * @returns {String} */ -export function hlVer(toVer, fromVer) { - const { green } = snooplogg.styles; +export function hlVer(toVer: string, fromVer: string): string { const version = []; - let [ from, fromTag ] = fromVer.split(/-(.+)/); - from = from.replace(/[^.\d]/g, '').split('.').map(x => parseInt(x)); + const [ from, fromTag ] = fromVer.split(/-(.+)/); + const fromArr = from.replace(/[^.\d]/g, '').split('.').map(x => parseInt(x)); - let [ to, toTag ] = toVer.split(/-(.+)/); + const [ to, toTag ] = toVer.split(/-(.+)/); const toMatch = to.match(/^([^\d]+)?(.+)$/); - to = (toMatch ? toMatch[2] : to).split('.').map(x => parseInt(x)); + const toArr = (toMatch ? toMatch[2] : to).split('.').map(x => parseInt(x)); - const tag = () => { + const tag = (): string => { if (toTag) { const toNum = toTag.match(/\d+$/); const fromNum = fromTag && fromTag.match(/\d+$/); - if (fromNum && parseInt(fromNum[0]) >= parseInt(toNum)) { + if (fromNum && toNum && parseInt(fromNum[0]) >= parseInt(toNum[0])) { return `-${toTag}`; } else { return green(`-${toTag}`); @@ -215,15 +180,15 @@ export function hlVer(toVer, fromVer) { return ''; }; - while (to.length) { - if (to[0] > from[0]) { + while (toArr.length) { + if (toArr[0] > fromArr[0]) { if (version.length) { - return (toMatch && toMatch[1] || '') + version.concat(green(to.join('.') + tag())).join('.'); + return (toMatch && toMatch[1] || '') + [ ...version, green(toArr.join('.') + tag()) ].join('.'); } - return green((toMatch && toMatch[1] || '') + to.join('.') + tag()); + return green((toMatch && toMatch[1] || '') + toArr.join('.') + tag()); } - version.push(to.shift()); - from.shift(); + version.push(toArr.shift()); + fromArr.shift(); } return (toMatch && toMatch[1] || '') + version.join('.') + tag(); @@ -237,8 +202,8 @@ export function hlVer(toVer, fromVer) { * @param {String} [env] - The environment name. * @returns {Promise} */ -export async function initPlatformAccount(accountName, org, env) { - const { config, sdk } = initSDK({ env }); +export async function initPlatformAccount(accountName?: string, org?: string, env?: string): Promise { + const { config, sdk } = await initSDK({ env }); const authConfigEnvSpecifier = getAuthConfigEnvSpecifier(sdk.env.name); const account = await sdk.auth.find(accountName || config.get(`${authConfigEnvSpecifier}.defaultAccount`)); @@ -252,22 +217,23 @@ export async function initPlatformAccount(accountName, org, env) { throw new Error('You must be logged into a platform account\n\nTo login, run: axway auth login'); } + let orgObj = null; if (org) { - org = await sdk.org.find(account, org); + orgObj = await sdk.org.find(account, org); } else { try { // check the config for a default org for this account - org = await sdk.org.find(account, config.get(`${authConfigEnvSpecifier}.defaultOrg.${account.hash}`)); - } catch (err) { + orgObj = await sdk.org.find(account, config.get(`${authConfigEnvSpecifier}.defaultOrg.${account.hash}`)); + } catch (err: any) { // default org was stale, auto detect the default from the account orgs - org = await sdk.org.find(account); + orgObj = await sdk.org.find(account); } } return { account, config, - org, + org: orgObj, sdk }; } @@ -280,14 +246,14 @@ export async function initPlatformAccount(accountName, org, env) { * @returns {Object} Returns an object containing the Axway CLI config and an initialized * Amplify SDK instance. */ -export function initSDK(opts = {}, config) { +export async function initSDK(opts: BuildAuthParamsOptions = {}, config?: Config): Promise<{ config: Config, sdk: AmplifySDK }> { if (!config) { - config = loadConfig(); + config = await loadConfig(); } return { config, - sdk: new AmplifySDK(buildAuthParams(opts, config)) + sdk: new AmplifySDK(await buildAuthParams(opts, config)) }; } @@ -296,7 +262,7 @@ export function initSDK(opts = {}, config) { * * @returns {Boolean} */ -export function isHeadless() { +export function isHeadless(): boolean { try { if (process.platform === 'linux' && (process.env.SSH_TTY || !process.env.DISPLAY || /docker|lxc/.test(fs.readFileSync('/proc/1/cgroup', 'utf8')))) { return true; @@ -304,7 +270,7 @@ export function isHeadless() { if (process.platform === 'darwin' && process.env.SSH_TTY) { return true; } - } catch (e) { + } catch (e: any) { // do nothing } diff --git a/packages/amplify-cli-utils/src/locations.js b/packages/amplify-cli-utils/src/locations.js deleted file mode 100644 index 76fb1df2..00000000 --- a/packages/amplify-cli-utils/src/locations.js +++ /dev/null @@ -1,8 +0,0 @@ -import os from 'os'; -import path from 'path'; - -// Directories -export const axwayHome = path.join(os.homedir(), '.axway'); - -// Files -export const configFile = path.join(axwayHome, 'axway-cli', 'config.json'); diff --git a/packages/amplify-cli-utils/src/locations.ts b/packages/amplify-cli-utils/src/locations.ts new file mode 100644 index 00000000..bf789915 --- /dev/null +++ b/packages/amplify-cli-utils/src/locations.ts @@ -0,0 +1,8 @@ +import os from 'os'; +import path from 'path'; + +// Directories +export const axwayHome: string = path.join(os.homedir(), '.axway'); + +// Files +export const configFile: string = path.join(axwayHome, 'axway-cli', 'config.json'); diff --git a/packages/amplify-cli-utils/src/request.js b/packages/amplify-cli-utils/src/request.ts similarity index 64% rename from packages/amplify-cli-utils/src/request.js rename to packages/amplify-cli-utils/src/request.ts index 810bd08a..01acee5b 100644 --- a/packages/amplify-cli-utils/src/request.js +++ b/packages/amplify-cli-utils/src/request.ts @@ -1,5 +1,7 @@ import fs from 'fs'; import loadConfig, { Config } from '@axway/amplify-config'; +import { GotReturn } from 'got'; +import { RequestOptions } from '@axway/amplify-request'; import * as request from '@axway/amplify-request'; /** @@ -12,8 +14,8 @@ import * as request from '@axway/amplify-request'; * from disk. * @returns {Array.} */ -export function createNPMRequestArgs(opts, config) { - const { ca, cert, key, proxy, strictSSL } = createRequestOptions(opts, config); +export async function createNPMRequestArgs(opts?: RequestOptions, config?: Config): Promise { + const { ca, cert, key, proxy, strictSSL } = await createRequestOptions(opts, config); const args = []; if (ca) { @@ -42,8 +44,8 @@ export function createNPMRequestArgs(opts, config) { * from disk. * @returns {Function} */ -export function createRequestClient(opts, config) { - opts = createRequestOptions(opts, config); +export async function createRequestClient(opts: RequestOptions = {}, config?: Config): Promise { + opts = await createRequestOptions(opts, config); return request.init({ ...opts, https: { @@ -64,47 +66,47 @@ export function createRequestClient(opts, config) { * from disk. * @returns {Object} */ -export function createRequestOptions(opts = {}, config) { +export async function createRequestOptions(opts: RequestOptions | Config = {}, config?: Config): Promise { + let reqOpts: RequestOptions = {}; if (opts instanceof Config) { config = opts; - opts = {}; } else if (!opts && typeof opts !== 'object') { throw new TypeError('Expected options to be an object'); } else { - opts = { ...opts }; + reqOpts = { ...opts }; } if (config && !(config instanceof Config)) { throw new TypeError('Expected config to be an Amplify Config instance'); } - const load = (src, dest) => { - if (opts[dest] !== undefined) { + const load = async (src: string, dest: string) => { + if (reqOpts[dest as keyof RequestOptions] !== undefined) { return; } if (!config) { - config = loadConfig(); + config = await loadConfig(); } const value = config.get(src); if (value === undefined) { return; } if (dest === 'proxy') { - opts[dest] = value; + reqOpts.proxy = value; } else if (dest === 'strictSSL') { - opts[dest] = !!value !== false; + reqOpts.strictSSL = !!value !== false; } else { - opts[dest] = fs.readFileSync(value); + reqOpts[dest as keyof RequestOptions] = fs.readFileSync(value, 'utf-8') as any; } }; - load('network.caFile', 'ca'); - load('network.certFile', 'cert'); - load('network.keyFile', 'key'); - load('network.proxy', 'proxy'); - load('network.httpsProxy', 'proxy'); - load('network.httpProxy', 'proxy'); - load('network.strictSSL', 'strictSSL'); + await load('network.caFile', 'ca'); + await load('network.certFile', 'cert'); + await load('network.keyFile', 'key'); + await load('network.proxy', 'proxy'); + await load('network.httpsProxy', 'proxy'); + await load('network.httpProxy', 'proxy'); + await load('network.strictSSL', 'strictSSL'); - return opts; + return reqOpts; } diff --git a/packages/amplify-cli-utils/src/telemetry.js b/packages/amplify-cli-utils/src/telemetry.ts similarity index 56% rename from packages/amplify-cli-utils/src/telemetry.js rename to packages/amplify-cli-utils/src/telemetry.ts index 3dbda594..03c425d4 100644 --- a/packages/amplify-cli-utils/src/telemetry.js +++ b/packages/amplify-cli-utils/src/telemetry.ts @@ -2,14 +2,28 @@ import fs from 'fs-extra'; import loadConfig from '@axway/amplify-config'; import path from 'path'; import snooplogg from 'snooplogg'; -import { createRequestOptions } from './request'; -import { Telemetry } from '@axway/amplify-sdk'; -import * as environments from './environments'; -import * as locations from './locations'; +import { CrashPayload, EventPayload, Telemetry } from '@axway/amplify-sdk'; +import { createRequestOptions } from './request.js'; +import { Environment } from './types.js'; +import * as environments from './environments.js'; +import * as locations from './locations.js'; const { warn } = snooplogg('amplify-cli-utils:telemetry'); const telemetryCacheDir = path.join(locations.axwayHome, 'axway-cli', 'telemetry'); -let telemetryInst = null; + +/** + * The cached telemetry instance. + * @type {Telemetry} + */ +let telemetryInst: Telemetry | null = null; + +interface InitOptions { + appGuid: string, + appVersion: string, + config?: Config + env?: string, + url?: string +} /** * If telemetry is enabled, writes the anonymous event data to disk where it will eventually be @@ -18,9 +32,9 @@ let telemetryInst = null; * @param {Object} payload - the telemetry event payload. * @param {Object} [opts] - Various options to pass into the `Telemetry` instance. */ -export function addEvent(payload, opts) { +export async function addEvent(payload: EventPayload, opts?: InitOptions): Promise { // eslint-disable-next-line no-unused-expressions - init(opts)?.addEvent(payload); + (await init(opts))?.addEvent(payload); } /** @@ -30,59 +44,63 @@ export function addEvent(payload, opts) { * @param {Object} payload - the telemetry event payload. * @param {Object} [opts] - Various options to pass into the `Telemetry` instance. */ -export function addCrash(payload, opts) { +export async function addCrash(payload: CrashPayload, opts?: InitOptions): Promise { // eslint-disable-next-line no-unused-expressions - init(opts)?.addCrash(payload); + (await init(opts))?.addCrash(payload); } /** * Checks if telemetry is enabled, then if it is, creates the telemetry instance and registers the * send handler. * - * @param {Object} [opts] - Various options. - * @param {String} [opts.appGuid] - The platform registered app guid. - * @param {String} [opts.appVersion] - The app version. + * @param {Object} opts - Various options. + * @param {String} opts.appGuid - The platform registered app guid. + * @param {String} opts.appVersion - The app version. * @param {Config} [opts.config] - The Axway CLI config object. * @param {String} [opts.env] - The environment name. * @param {String} [opts.url] - The platform analytics endpoint URL. * @returns {Telemetry} */ -export function init(opts = {}) { +export async function init(opts?: InitOptions): Promise { try { if (telemetryInst) { return telemetryInst; } - const config = opts.config || loadConfig(); + const config = opts?.config || await loadConfig(); if (!config.get('telemetry.enabled')) { return; } + if (!opts || typeof opts !== 'object') { + throw new TypeError('Expected telemetry init options to be an object'); + } + if (!opts.appGuid || typeof opts.appGuid !== 'string') { throw new Error('Expected telemetry app guid to be a non-empty string'); } - const env = environments.resolve(opts.env || config.get('env')); + const env: Environment = environments.resolve(opts.env || config.get('env')); telemetryInst = new Telemetry({ appGuid: opts.appGuid, appVersion: opts.appVersion, cacheDir: telemetryCacheDir, - environment: env === 'staging' ? 'preproduction' : 'production', - requestOptions: createRequestOptions(config), + environment: env.name === 'staging' ? 'preproduction' : 'production', + requestOptions: await createRequestOptions(config), url: opts.url }); process.on('exit', () => { try { - telemetryInst.send(); - } catch (err) { + telemetryInst?.send(); + } catch (err: any) { warn(err); } }); return telemetryInst; - } catch (err) { + } catch (err: any) { telemetryInst = null; warn(err); } @@ -93,8 +111,9 @@ export function init(opts = {}) { * * @returns {Boolean} */ -export function isEnabled() { - return !!loadConfig().get('telemetry.enabled'); +export async function isEnabled(): Promise { + const cfg = await loadConfig(); + return !!cfg.get('telemetry.enabled'); } /** diff --git a/packages/amplify-cli-utils/src/types.ts b/packages/amplify-cli-utils/src/types.ts new file mode 100644 index 00000000..3608e27b --- /dev/null +++ b/packages/amplify-cli-utils/src/types.ts @@ -0,0 +1,58 @@ +import AmplifySDK, { Account, Org, TokenStore } from '@axway/amplify-sdk'; +import { + CLIContext, + CLIOptionCallbackState, + CLIState +} from 'cli-kit'; +import { RequestOptions } from '@axway/amplify-request'; + +export interface AxwayCLIContext extends CLIContext { + jsonMode?: boolean; +} + +export interface AxwayCLIOptionCallbackState extends CLIOptionCallbackState { + ctx: AxwayCLIContext; +} + +export interface AxwayCLIState extends CLIState { + startTime: number; +} + +export interface BuildAuthParamsOptions extends RequestOptions { + baseUrl?: string, + clientId?: string, + clientSecret?: string, + env?: string, + interactiveLoginTimeout?: number, + homeDir?: string, + password?: string, + persistSecrets?: boolean, + platformUrl?: string, + realm?: string + requestOptions?: RequestOptions, + secretFile?: string + serverHost?: string + serverPort?: number, + serviceAccount?: boolean, + tokenRefreshThreshold?: number, + tokenStore?: TokenStore, + tokenStoreDir?: string, + tokenStoreType?: string, + username?: string +} + +export interface Environment { + auth: { + clientId: string, + realm: string + }, + name: string, + title: string +} + +export interface InitPlatformAccountResult { + account: Account, + config: Config, + org: Org, + sdk: AmplifySDK +} diff --git a/packages/amplify-cli-utils/test/test-auth.js b/packages/amplify-cli-utils/test/test-auth.ts similarity index 68% rename from packages/amplify-cli-utils/test/test-auth.js rename to packages/amplify-cli-utils/test/test-auth.ts index f28aa0ef..114b5abb 100644 --- a/packages/amplify-cli-utils/test/test-auth.js +++ b/packages/amplify-cli-utils/test/test-auth.ts @@ -1,15 +1,16 @@ import http from 'http'; - +import { Account, MemoryStore } from '@axway/amplify-sdk'; import { Config } from '@axway/amplify-config'; -import { initSDK } from '../dist/index'; -import { MemoryStore } from '@axway/amplify-sdk'; +import { expect } from 'chai'; +import { initSDK } from '../src/index.js'; +import { Socket } from 'net'; describe('auth', () => { before(async function () { this.timeout(5000); - this.server = http.createServer((req, res) => { - const url = new URL(req.url, 'http://127.0.0.1:1337'); + this.server = http.createServer((req: http.IncomingMessage, res: http.ServerResponse) => { + const url = new URL(req.url as string, 'http://127.0.0.1:1337'); switch (url.pathname) { case '/auth/realms/AppcID/protocol/openid-connect/userinfo': case '/auth/realms/Axway/protocol/openid-connect/userinfo': @@ -26,8 +27,18 @@ describe('auth', () => { res.end(JSON.stringify({ result: { org: { + guid: '123', org_id: 123, - name: 'foo org' + name: 'foo org', + subscriptions: [], + users: [ + { + firstname: 'foo', + guid: 'def456', + lastname: 'bar', + name: 'foo bar' + } + ] }, orgs: [ { @@ -68,6 +79,20 @@ describe('auth', () => { })); break; + case '/api/v1/org/123/user': + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ + result: [ + { + firstname: 'foo', + guid: 'def456', + lastname: 'bar', + name: 'foo bar' + } + ] + })); + break; + case '/success': res.writeHead(200, { 'Content-Type': 'text/html' }); res.end('Test successful!

Test successful!

You can close this browser window

'); @@ -84,7 +109,7 @@ describe('auth', () => { await new Promise((resolve, reject) => { this.server .on('listening', resolve) - .on('connection', conn => { + .on('connection', (conn: Socket) => { const key = `${conn.remoteAddress}:${conn.remotePort}`; this.connections[key] = conn; conn.on('close', () => { @@ -97,10 +122,11 @@ describe('auth', () => { }); after(function () { - return Promise.all([ - new Promise(resolve => this.server.close(resolve)), - new Promise(resolve => { - for (const conn of Object.values(this.connections)) { + return Promise.all([ + new Promise(resolve => this.server.close(() => resolve())), + new Promise(resolve => { + const connections: { [key: string]: Socket } = this.connections; + for (const conn of Object.values(connections)) { conn.destroy(); } resolve(); @@ -123,22 +149,25 @@ describe('auth', () => { access_token: 'foo' } }, - hash: 'test:85e0419f4473118bf2bc8a8bba9f6abc', + hash: 'test:c40c30ec385cb552cb1f4b4600116bce', name: 'bar' }; const tokenStore = new MemoryStore(); - await tokenStore.set(token); + await tokenStore.set(token as Account); - const { sdk } = initSDK({ + const { sdk } = await initSDK({ baseUrl: 'http://127.0.0.1:1337/', clientId: 'test', clientSecret: 'shhhh', - orgSelectUrl: 'http://127.0.0.1:1337/auth/org.select', platformUrl: 'http://127.0.0.1:1337/', realm: 'baz', tokenStore - }, new Config({ env: 'preprod' })); + }, await new Config().init({ + data: { + env: 'preprod' + } + })); const account = await sdk.auth.find(); expect(account).to.deep.equal(token); @@ -164,31 +193,30 @@ describe('auth', () => { }; const tokenStore = new MemoryStore(); - await tokenStore.set(token); + await tokenStore.set(token as Account); - const { sdk } = initSDK({ + const { sdk } = await initSDK({ clientId: 'test', env: 'preprod', baseUrl: 'http://127.0.0.1:1337/', - orgSelectUrl: 'http://127.0.0.1:1337/auth/org.select', platformUrl: 'http://127.0.0.1:1337/', realm: 'baz', tokenStore - }, new Config()); + }, await new Config().init()); const account = await sdk.auth.find('test:acbba128ef48ea3cb8c122225f095eb1'); expect(account).to.deep.equal(token); }); it('should not find an access token by auth params', async () => { - const { sdk } = initSDK({ tokenStore: new MemoryStore() }, new Config()); + const { sdk } = await initSDK({ tokenStore: new MemoryStore() }, await new Config().init()); const account = await sdk.auth.find(); - expect(account).to.equal(null); + expect(account).to.equal(undefined); }); it('should not find an access token by id', async () => { - const { sdk } = initSDK({ tokenStore: new MemoryStore() }, new Config()); + const { sdk } = await initSDK({ tokenStore: new MemoryStore() }, await new Config().init()); const account = await sdk.auth.find('foo'); - expect(account).to.equal(null); + expect(account).to.equal(undefined); }); }); diff --git a/packages/amplify-cli-utils/test/test-config.js b/packages/amplify-cli-utils/test/test-config.ts similarity index 74% rename from packages/amplify-cli-utils/test/test-config.js rename to packages/amplify-cli-utils/test/test-config.ts index 5a4ddbd3..5f18af38 100644 --- a/packages/amplify-cli-utils/test/test-config.js +++ b/packages/amplify-cli-utils/test/test-config.ts @@ -1,9 +1,11 @@ -import path from 'path'; import fs from 'fs-extra'; - +import path from 'path'; import { Config } from '@axway/amplify-config'; -import { loadConfig, locations } from '../dist/index'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; +import { loadConfig, locations } from '../src/index.js'; +const __dirname = fileURLToPath(new URL('.', import.meta.url)); const { configFile } = locations; const fixturesDir = path.join(__dirname, 'fixtures', 'config'); const temp = path.join(__dirname, 'fixtures', 'axway-config.json'); @@ -37,15 +39,15 @@ describe('config', () => { done(); }); - it('should default to loading amplify config', () => { + it('should default to loading amplify config', async () => { fs.copySync(path.join(fixturesDir, 'existing-file.json'), configFile, { overwrite: true }); - const cfg = loadConfig(); + const cfg = await loadConfig(); expect(cfg.data(Config.Base)).to.deep.equal({ existing: true }); }); - it('should allow a custom userConfig to be passed in', () => { + it('should allow a custom userConfig to be passed in', async () => { const configFile = path.join(fixturesDir, 'my-own-config.json'); - const cfg = loadConfig({ configFile }); + const cfg = await loadConfig({ configFile }); expect(cfg.data(Config.Base)).to.deep.equal({ ownConfig: true }); }); }); diff --git a/packages/amplify-cli-utils/test/tsconfig.json b/packages/amplify-cli-utils/test/tsconfig.json new file mode 100644 index 00000000..40f5a110 --- /dev/null +++ b/packages/amplify-cli-utils/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": ".." + }, + "include": [ "./**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-cli-utils/tsconfig.json b/packages/amplify-cli-utils/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/amplify-cli-utils/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-config/.gitignore b/packages/amplify-config/.gitignore deleted file mode 100644 index b3a1d215..00000000 --- a/packages/amplify-config/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -._* -.DS_Store* -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log -yarn-error.log diff --git a/packages/amplify-config/CHANGELOG.md b/packages/amplify-config/CHANGELOG.md index 159c5724..b007fa4f 100644 --- a/packages/amplify-config/CHANGELOG.md +++ b/packages/amplify-config/CHANGELOG.md @@ -1,3 +1,7 @@ +# v5.0.0 + + * BREAKING CHANGE: Dropped support for Node.js 12 and older. + # v4.0.9 (May 11, 2022) * chore: Updated dependencies. diff --git a/packages/amplify-config/gulpfile.js b/packages/amplify-config/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/amplify-config/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/amplify-config/package.json b/packages/amplify-config/package.json index d44e4af1..bbec31cf 100644 --- a/packages/amplify-config/package.json +++ b/packages/amplify-config/package.json @@ -5,6 +5,9 @@ "access": "public" }, "description": "Configuration helper for the Axway CLI.", + "type": "module", + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", "author": "Axway, Inc. ", "maintainers": [ "Ewan Harris ", @@ -15,28 +18,26 @@ "axway", "amplify" ], - "main": "./dist/index", "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "c8 npm run test", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:test npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:test": "eslint --parser-options=project:'test/tsconfig.json' test/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "ts-mocha -n loader=ts-node/esm test/**/test-*.ts --require ../../test/setup.js --reporter spec" }, "dependencies": { "@axway/amplify-utils": "^1.0.9", - "config-kit": "^1.7.2", + "config-kit": "^2.1.0", "fs-extra": "^10.1.0", "source-map-support": "^0.5.21" }, - "devDependencies": { - "@axway/gulp-tasks": "^4.1.4" - }, "homepage": "https://github.com/appcelerator/amplify-tooling#readme", "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/amplify-config", "engines": { - "node": ">=12.13.0" - }, - "gitHead": "9cc288d8ee067fb3444920aad11c53899455ad9c" + "node": ">=14.15.0" + } } diff --git a/packages/amplify-config/src/index.js b/packages/amplify-config/src/index.ts similarity index 89% rename from packages/amplify-config/src/index.js rename to packages/amplify-config/src/index.ts index 7a27a10d..c99331be 100644 --- a/packages/amplify-config/src/index.js +++ b/packages/amplify-config/src/index.ts @@ -1,8 +1,3 @@ -/* istanbul ignore if */ -if (!Error.prepareStackTrace) { - require('source-map-support/register'); -} - import Config from 'config-kit'; import fs from 'fs-extra'; import os from 'os'; @@ -13,6 +8,11 @@ const axwayHome = path.join(os.homedir(), '.axway'); export const configFile = path.join(axwayHome, 'axway-cli', 'config.json'); +interface LoadConfigOptions { + config?: any, + configFile?: string +} + /** * Load a users config, if no userConfig is given then the default Axway CLI config will be * loaded. @@ -23,7 +23,7 @@ export const configFile = path.join(axwayHome, 'axway-cli', 'config.json'); * @param {String} [opts.configFile] - The path to a .js or .json config file to load. * @returns {Config} */ -export function loadConfig(opts = {}) { +export async function loadConfig(opts: LoadConfigOptions = {}): Promise { // validate the config options if (opts.config && (typeof opts.config !== 'object' || Array.isArray(opts.config))) { throw new TypeError('Expected config to be an object'); @@ -42,7 +42,7 @@ export function loadConfig(opts = {}) { writeFileSync(configFile, JSON.stringify(json, null, 2)); } - return new Config({ + return await new Config().init({ data: opts.config, file: expandPath(opts.configFile || configFile) }); diff --git a/packages/amplify-config/test/test-config.js b/packages/amplify-config/test/test-config.ts similarity index 71% rename from packages/amplify-config/test/test-config.js rename to packages/amplify-config/test/test-config.ts index ff41a072..69889449 100644 --- a/packages/amplify-config/test/test-config.js +++ b/packages/amplify-config/test/test-config.ts @@ -1,8 +1,10 @@ -import path from 'path'; import fs from 'fs-extra'; +import loadConfig, { Config, configFile } from '../src/index.js'; +import path from 'path'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; -import loadConfig, { Config, configFile } from '../dist/index'; - +const __dirname = fileURLToPath(new URL('.', import.meta.url)); const fixturesDir = path.join(__dirname, 'fixtures', 'config'); const temp = path.join(__dirname, 'fixtures', 'axway-config.json'); @@ -32,15 +34,15 @@ describe('config', () => { } }); - it('should default to loading amplify config', () => { + it('should default to loading amplify config', async () => { fs.copySync(path.join(fixturesDir, 'existing-file.json'), configFile, { overwrite: true }); - const cfg = loadConfig(); + const cfg = await loadConfig(); expect(cfg.data(Config.Base)).to.deep.equal({ existing: true }); }); - it('should allow a custom userConfig to be passed in', () => { + it('should allow a custom userConfig to be passed in', async () => { const configFile = path.join(fixturesDir, 'my-own-config.json'); - const cfg = loadConfig({ configFile }); + const cfg = await loadConfig({ configFile }); expect(cfg.data(Config.Base)).to.deep.equal({ ownConfig: true }); }); }); diff --git a/packages/amplify-config/test/tsconfig.json b/packages/amplify-config/test/tsconfig.json new file mode 100644 index 00000000..40f5a110 --- /dev/null +++ b/packages/amplify-config/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": ".." + }, + "include": [ "./**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-config/tsconfig.json b/packages/amplify-config/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/amplify-config/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-request/.eslintrc b/packages/amplify-request/.eslintrc deleted file mode 100644 index ab0aad7f..00000000 --- a/packages/amplify-request/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-confusing-arrow": "off" - } -} diff --git a/packages/amplify-request/.gitignore b/packages/amplify-request/.gitignore deleted file mode 100644 index b3a1d215..00000000 --- a/packages/amplify-request/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -._* -.DS_Store* -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log -yarn-error.log diff --git a/packages/amplify-request/.npmignore b/packages/amplify-request/.npmignore index a3dc90cb..31e4a680 100644 --- a/packages/amplify-request/.npmignore +++ b/packages/amplify-request/.npmignore @@ -11,6 +11,9 @@ gulpfile.js junit.xml node_modules npm-debug.log +retire_output.json +tsconfig.json +yarn.lock yarn-error.log /src /test diff --git a/packages/amplify-request/CHANGELOG.md b/packages/amplify-request/CHANGELOG.md index 5e3abd25..539005f6 100644 --- a/packages/amplify-request/CHANGELOG.md +++ b/packages/amplify-request/CHANGELOG.md @@ -1,3 +1,8 @@ +# v4.0.0 + + * BREAKING CHANGE: Dropped support for Node.js 12 and older. + * chore: Updated dependencies. + # v3.0.10 (Jun 30, 2022) * chore: Updated dependencies. diff --git a/packages/amplify-request/gulpfile.js b/packages/amplify-request/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/amplify-request/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/amplify-request/package.json b/packages/amplify-request/package.json index 02744577..ca069159 100644 --- a/packages/amplify-request/package.json +++ b/packages/amplify-request/package.json @@ -5,6 +5,9 @@ "access": "public" }, "description": "HTTP request library for Axway CLI packages", + "type": "module", + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", "author": "Axway, Inc. ", "maintainers": [ "Chris Barber " @@ -19,30 +22,28 @@ "https", "proxy" ], - "main": "./dist/index", "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "c8 npm run test", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:test npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:test": "eslint --parser-options=project:'test/tsconfig.json' test/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "ts-mocha -n loader=ts-node/esm test/**/test-*.ts --require ../../test/setup.js --reporter spec" }, "dependencies": { "@axway/amplify-utils": "^1.0.9", - "got": "^11.8.5", + "got": "^12.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", - "pretty-bytes": "^5.6.0", - "snooplogg": "^3.0.2", - "source-map-support": "^0.5.21" - }, - "devDependencies": { - "@axway/gulp-tasks": "^4.1.4" + "pretty-bytes": "^6.0.0", + "snooplogg": "^5.0.0" }, "homepage": "https://github.com/appcelerator/amplify-tooling#readme", "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/amplify-request", "engines": { - "node": ">=12.13.0" + "node": ">=14.15.0" } } diff --git a/packages/amplify-request/src/index.js b/packages/amplify-request/src/index.ts similarity index 71% rename from packages/amplify-request/src/index.js rename to packages/amplify-request/src/index.ts index 048d5d2e..ea9cc968 100644 --- a/packages/amplify-request/src/index.js +++ b/packages/amplify-request/src/index.ts @@ -1,10 +1,5 @@ -/* istanbul ignore if */ -if (!Error.prepareStackTrace) { - require('source-map-support/register'); -} - import fs from 'fs'; -import got from 'got'; +import got, { Got, ExtendOptions } from 'got'; import HttpProxyAgent from 'http-proxy-agent'; import HttpsProxyAgent from 'https-proxy-agent'; import prettyBytes from 'pretty-bytes'; @@ -12,10 +7,46 @@ import snooplogg from 'snooplogg'; import { mergeDeep } from '@axway/amplify-utils'; const { log } = snooplogg('amplify-request'); -const { alert, highlight, magenta, ok, note } = snooplogg.styles; +const { alert, highlight, magenta, note, ok } = snooplogg.styles; export { got }; +interface GotHooks { + afterResponse: [ + (response: any) => any + ] +} + +interface HttpsOptions { + certificate?: Buffer | string, + certificateAuthority?: Buffer, + key?: Buffer | string, + rejectUnauthorized?: boolean +} + +export interface RequestTimeout { + request: number +} + +export interface RequestOptions { + agent?: { + http?: HttpProxyAgent.HttpProxyAgent, + https?: HttpsProxyAgent.HttpsProxyAgent + }, + ca?: Buffer | string, + caFile?: string, + cert?: Buffer | string, + certFile?: string, + defaults?: RequestOptions, + hooks?: GotHooks, + https?: HttpsOptions, + key?: Buffer | string, + keyFile?: string, + proxy?: string, + strictSSL?: boolean, + timeout?: number | RequestTimeout +} + /** * Creates an options object for use with `got`. * @@ -33,7 +64,7 @@ export { got }; * for both `https` destinations and `https` proxy servers. * @returns {Promise} Resolves `got` options object. */ -export function options(opts = {}) { +export function options(opts: RequestOptions = {}): ExtendOptions { if (!opts || typeof opts !== 'object') { throw new TypeError('Expected options to be an object'); } @@ -62,11 +93,15 @@ export function options(opts = {}) { delete opts.proxy; delete opts.strictSSL; - const load = it => Buffer.isBuffer(it) ? it : typeof it === 'string' ? fs.readFileSync(it) : undefined; + if (typeof opts.timeout === 'number') { + opts.timeout = { request: opts.timeout }; + } + + const load = (it: Buffer | string | undefined) => Buffer.isBuffer(it) ? it : typeof it === 'string' ? fs.readFileSync(it) : undefined; opts.hooks = mergeDeep(opts.hooks, { afterResponse: [ - response => { + (response: any) => { const { headers, request, statusCode, url } = response; log([ request.options.method, @@ -80,7 +115,7 @@ export function options(opts = {}) { ] }); - opts.https = mergeDeep(opts.https, { + const https: HttpsOptions = opts.https = mergeDeep(opts.https, { certificate: load(opts.https?.certificate || cert || certFile), certificateAuthority: load(opts.https?.certificateAuthority || ca || caFile), key: load(opts.https?.key || key || keyFile), @@ -90,25 +125,25 @@ export function options(opts = {}) { if (proxy) { const { hostname: host, pathname: path, port, protocol } = new URL(proxy); const agentOpts = { - ca: opts.https.certificateAuthority, - cert: opts.https.certificate, + ca: https.certificateAuthority, + cert: https.certificate, host, - key: opts.https.key, + key: https.key, path, port, protocol, - rejectUnauthorized: opts.https.rejectUnauthorized + rejectUnauthorized: https.rejectUnauthorized }; // console.log(agentOpts); opts.agent = { ...opts.agent, - http: opts.agent?.http || new HttpProxyAgent(agentOpts), - https: opts.agent?.https || new HttpsProxyAgent(agentOpts) + http: opts.agent?.http || new HttpProxyAgent.HttpProxyAgent(agentOpts), + https: opts.agent?.https || new HttpsProxyAgent.HttpsProxyAgent(agentOpts) }; } // console.log(opts); - return opts; + return opts as ExtendOptions; } /** @@ -127,7 +162,7 @@ export function options(opts = {}) { * for both `https` destinations and `https` proxy servers. * @returns {Function} A `got` instance. */ -export function init(opts = {}) { +export function init(opts: RequestOptions = {}): Got { return got.extend(options(opts)); } diff --git a/packages/amplify-request/test/test-request.js b/packages/amplify-request/test/test-request.ts similarity index 85% rename from packages/amplify-request/test/test-request.js rename to packages/amplify-request/test/test-request.ts index 2ca715ac..b083e858 100644 --- a/packages/amplify-request/test/test-request.js +++ b/packages/amplify-request/test/test-request.ts @@ -1,11 +1,22 @@ import fs from 'fs'; import http from 'http'; import https from 'https'; -import init from '../dist'; +import init from '../src/index.js'; import path from 'path'; +import tls from 'tls'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; +const __dirname = fileURLToPath(new URL('.', import.meta.url)); const sslDir = path.join(__dirname, 'fixtures', 'ssl'); +interface IncomingMessageWithClient extends http.IncomingMessage { + client?: { + authorized: boolean + }; + connection: tls.TLSSocket +} + describe('init', () => { beforeEach(function () { this.server = null; @@ -27,7 +38,7 @@ describe('init', () => { }); it('should error if params is not an object', () => { - expect(() => init('foo')).to.throw(TypeError, 'Expected options to be an object'); + expect(() => init('foo' as any)).to.throw(TypeError, 'Expected options to be an object'); }); it('should make http request', async function () { @@ -45,7 +56,7 @@ describe('init', () => { try { await init()('http://127.0.0.1:1337'); - } catch (err) { + } catch (err: any) { expect(err.code).to.equal('ECONNREFUSED'); return; } @@ -63,7 +74,7 @@ describe('init', () => { try { await init()('http://127.0.0.1:1337'); - } catch (err) { + } catch (err: any) { expect(err.response.statusCode).to.equal(404); expect(err.response.body).to.equal('Not Found'); } @@ -74,7 +85,7 @@ describe('init', () => { try { await init()({ url: 'http://127.0.0.1:1336' }); - } catch (err) { + } catch (err: any) { expect(err.code).to.equal('ECONNREFUSED'); expect(err.message).to.equal('connect ECONNREFUSED 127.0.0.1:1336'); return; @@ -93,7 +104,7 @@ describe('init', () => { try { await init()('http://127.0.0.1:1337', { responseType: 'json' }); - } catch (err) { + } catch (err: any) { expect(err.message).to.include('Unexpected token { in JSON'); return; } @@ -113,12 +124,12 @@ describe('init', () => { await new Promise(resolve => this.server.listen(1337, '127.0.0.1', resolve)); const response = await init()({ - strictSSL: false, + // strictSSL: false, url: 'https://127.0.0.1:1337' }); expect(response.statusCode).to.equal(200); - expect(parseInt(response.headers['content-length'])).to.equal(4); + expect(parseInt(response.headers['content-length'] as string)).to.equal(4); expect(response.body).to.equal('foo!'); }); @@ -134,7 +145,7 @@ describe('init', () => { try { await init({ strictSSL: true })('https://127.0.0.1:1337'); - } catch (err) { + } catch (err: any) { expect(err.message).to.match(/self signed/); return; } @@ -150,13 +161,16 @@ describe('init', () => { key: fs.readFileSync(path.join(sslDir, 'server.key.pem')), requestCert: true }, (req, res) => { - if (!req.client.authorized) { + const r = req as IncomingMessageWithClient; + + if (!r.client?.authorized) { res.writeHead(401, { 'Content-Type': 'text/plain' }); res.end('Client cert required'); return; } - let cert = req.connection.getPeerCertificate(); + const conn = r.connection as tls.TLSSocket; + const cert = conn.getPeerCertificate(); if (!cert || !Object.keys(cert).length) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Client cert was authenticated, but no cert!'); @@ -180,7 +194,7 @@ describe('init', () => { const response = await got('https://127.0.0.1:1337'); expect(response.statusCode).to.equal(200); - expect(parseInt(response.headers['content-length'])).to.equal(4); + expect(parseInt(response.headers['content-length'] as string)).to.equal(4); expect(response.body).to.equal('foo!'); }); @@ -204,7 +218,7 @@ describe('init', () => { const response = await got('http://127.0.0.1:1338'); expect(response.statusCode).to.equal(200); - expect(parseInt(response.headers['content-length'])).to.equal(4); + expect(parseInt(response.headers['content-length'] as string)).to.equal(4); expect(response.body).to.equal('foo!'); }); }); diff --git a/packages/amplify-request/test/tsconfig.json b/packages/amplify-request/test/tsconfig.json new file mode 100644 index 00000000..40f5a110 --- /dev/null +++ b/packages/amplify-request/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": ".." + }, + "include": [ "./**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-request/tsconfig.json b/packages/amplify-request/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/amplify-request/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-sdk/.eslintrc b/packages/amplify-sdk/.eslintrc deleted file mode 100644 index 10273734..00000000 --- a/packages/amplify-sdk/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "node/no-unsupported-features/node-builtins": [ "warn", { "version": ">=12.13.0" } ] - } -} diff --git a/packages/amplify-sdk/.gitignore b/packages/amplify-sdk/.gitignore deleted file mode 100644 index 5882231e..00000000 --- a/packages/amplify-sdk/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.DS_Store -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log diff --git a/packages/amplify-sdk/CHANGELOG.md b/packages/amplify-sdk/CHANGELOG.md index 5eb67e22..124ce575 100644 --- a/packages/amplify-sdk/CHANGELOG.md +++ b/packages/amplify-sdk/CHANGELOG.md @@ -1,3 +1,13 @@ +# v4.0.0 + +- BREAKING CHANGE: Dropped support for Node.js 12 and older. +- BREAKING CHANGE: Removed `sdk.org.family()` from AmplifySDK. +- BREAKING CHANGE: Removed deprecated `childOrgs` and `parentOrg` properties from the organization + object. +- BREAKING CHANGE: All `sdk.*.user.()` functions have been renamed to + `sdk.*.user()`. +- chore: Updated dependencies. + # v3.2.7 (Jul 7, 2022) - chore: Updated readme. diff --git a/packages/amplify-sdk/README.md b/packages/amplify-sdk/README.md index 41b023d9..e29858bd 100644 --- a/packages/amplify-sdk/README.md +++ b/packages/amplify-sdk/README.md @@ -1,4 +1,4 @@ -# Amplify SDK. +# Amplify SDK The Amplify SDK for Node.js is a set of APIs for authenticating, switching selected organization, creating MBS apps and users, and Titanium SDK support. @@ -107,9 +107,12 @@ const { from, to, events } = await sdk.org.activity(account, "org name/id/guid", // as 'production' and 'development' const envs = await sdk.org.getEnvironments(account); +<<<<<<< HEAD +======= // get org family including child orgs const family = await sdk.org.family(account, "org name/id/guid"); +>>>>>>> master // rename an org await sdk.org.rename(account, "org name/id/guid", "new org name"); @@ -206,9 +209,14 @@ const activity = await sdk.user.activity(account, { // update user info const { changes, user } = await sdk.user.update(account, { +<<<<<<< HEAD + firstname: 'Elite', + lastname: 'Coder' +======= firstname: "Elite", lastname: "Coder", phone: "555-1212", +>>>>>>> master }); ``` @@ -245,7 +253,7 @@ account: { name: 'amplify-cli:user@domain.com', org: { guid: '', - id: 12345, + org_id: 12345, name: 'Example Org' }, orgs: [ @@ -253,13 +261,11 @@ account: { { /* org */ } ], user: { - axwayId: '', email: '', - firstName: '', + firstname: '', guid: '', - lastName: '', - organization: '', - is2FAEnabled: true + lastname: '', + organization: '' }, sid: '' } diff --git a/packages/amplify-sdk/gulpfile.js b/packages/amplify-sdk/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/amplify-sdk/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/amplify-sdk/package.json b/packages/amplify-sdk/package.json index 4899792d..34f2045f 100644 --- a/packages/amplify-sdk/package.json +++ b/packages/amplify-sdk/package.json @@ -5,6 +5,9 @@ "access": "public" }, "description": "Axway Amplify SDK for Node.js", + "type": "module", + "exports": "./dist/index.js", + "types": "./dist/index.d.ts", "author": "Axway, Inc. ", "maintainers": [ "Chris Barber " @@ -14,35 +17,36 @@ "axway", "amplify" ], - "main": "./dist/index", "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "c8 npm run test", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:test npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:test": "eslint --parser-options=project:'test/tsconfig.json' test/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "concurrently -s all -m 1 npm:build npm:test:mocha", + "test:mocha": "ts-mocha -n loader=ts-node/esm test/**/test-*.ts --require ../../test/setup.js --reporter spec" }, "dependencies": { "@axway/amplify-request": "^3.0.10", "@axway/amplify-utils": "^1.0.9", - "ci-info": "^3.3.1", - "ejs": "^3.1.7", + "ci-info": "^3.3.2", + "ejs": "^3.1.8", "fs-extra": "^10.1.0", - "get-port": "^5.1.1", + "get-port": "^6.1.2", "jws": "^4.0.0", "keytar": "7.9.0", "open": "^8.4.0", "pluralize": "^8.0.0", - "serialize-error": "^8.1.0", - "set-cookie-parser": "^2.4.8", - "snooplogg": "^3.0.2", - "source-map-support": "^0.5.21", + "serialize-error": "^11.0.0", + "set-cookie-parser": "^2.5.0", + "snooplogg": "^5.0.0", "tmp": "^0.2.1", "uuid": "^8.3.2" }, "devDependencies": { - "@axway/gulp-tasks": "^4.1.4", - "@koa/router": "^10.1.1", + "@koa/router": "^11.0.1", "koa": "^2.13.4", "koa-bodyparser": "^4.3.0", "koa-session": "^6.2.0" @@ -51,7 +55,6 @@ "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/amplify-sdk", "engines": { - "node": ">=12.13.0" - }, - "gitHead": "9cc288d8ee067fb3444920aad11c53899455ad9c" + "node": ">=14.15.0" + } } diff --git a/packages/amplify-sdk/src/amplify-sdk.js b/packages/amplify-sdk/src/amplify-sdk.js deleted file mode 100644 index 5fb61ff9..00000000 --- a/packages/amplify-sdk/src/amplify-sdk.js +++ /dev/null @@ -1,2051 +0,0 @@ -/* eslint-disable promise/no-nesting */ - -import Auth from './auth'; -import crypto from 'crypto'; -import E from './errors'; -import fs from 'fs-extra'; -import getEndpoints from './endpoints'; -import open from 'open'; -import path from 'path'; -import Server from './server'; -import setCookie from 'set-cookie-parser'; -import snooplogg from 'snooplogg'; -import * as environments from './environments'; -import * as request from '@axway/amplify-request'; -import { createURL } from './util'; -import { promisify } from 'util'; -import { redact } from '@axway/amplify-utils'; - -const { error, log, warn } = snooplogg('amplify-sdk'); -const { highlight, note } = snooplogg.styles; - -/** - * An SDK for accessing Amplify API's. - */ -export default class AmplifySDK { - /** - * Initializes the environment and SDK's API. - * - * @param {Object} opts - Authentication options. - * @param {Object} [opts.env=prod] - The environment name. - * @param {Object} [opts.requestOptions] - HTTP request options with proxy settings and such to - * create a `got` HTTP client. - * @access public - */ - constructor(opts = {}) { - if (typeof opts !== 'object') { - throw E.INVALID_ARGUMENT('Expected options to be an object'); - } - - /** - * Authentication options including baseURL, clientID, env, realm, and token store settings. - * @type {Object} - */ - this.opts = { ...opts }; - delete this.opts.username; - delete this.opts.password; - - /** - * Resolved environment-specific settings. - * @type {Object} - */ - this.env = environments.resolve(opts.env); - - // set the defaults based on the environment - for (const prop of [ 'baseUrl', 'platformUrl', 'realm' ]) { - if (!opts[prop]) { - opts[prop] = this.env[prop]; - } - } - - /** - * The `got` HTTP client. - * @type {Function} - */ - this.got = request.init(opts.requestOptions); - if (!opts.got) { - opts.got = this.got; - } - - /** - * The base Axway ID URL. - * @type {String} - */ - this.baseUrl = opts.baseUrl ? opts.baseUrl.replace(/\/$/, '') : null; - - /** - * The platform URL. - * @type {String} - */ - this.platformUrl = opts.platformUrl ? opts.platformUrl.replace(/\/$/, '') : null; - - /** - * The Axway ID realm. - * @type {String} - */ - this.realm = opts.realm; - - const { version } = fs.readJsonSync(path.resolve(__dirname, '../package.json')); - - /** - * The Axway ID realm. - * - * IMPORTANT! Platform explicitly checks this user agent, so do NOT change the name or case. - * - * @type {String} - */ - this.userAgent = `AMPLIFY SDK/${version} (${process.platform}; ${process.arch}; node:${process.versions.node})${process.env.AXWAY_CLI ? ` Axway CLI/${process.env.AXWAY_CLI}` : ''}`; - - this.auth = { - /** - * Finds an authenticated account or `null` if not found. If the account is found and - * the access token is expired yet the refresh token is still valid, it will - * automatically get a valid access token. - * @param {String} accountName - The name of the account including the client id prefix. - * @param {Object} [defaultTeams] - A map of account hashes to their selected team guid. - * @returns {Promise} Resolves the account info object. - */ - find: async (accountName, defaultTeams) => { - const account = await this.authClient.find(accountName); - return account ? await this.auth.loadSession(account, defaultTeams) : null; - }, - - /** - * Retrieves platform session information such as the organizations, then mutates the - * account object and returns it. - * @param {Object} account - The account object. - * @param {Object} [defaultTeams] - A map of account hashes to their selected team guid. - * @returns {Promise} Resolves the original account info object. - */ - findSession: async (account, defaultTeams) => { - if (defaultTeams && typeof defaultTeams !== 'object') { - throw E.INVALID_ARGUMENT('Expected default teams to be an object'); - } - - const result = await this.request('/api/v1/auth/findSession', account, { - errorMsg: 'Failed to find session' - }); - account.isPlatform = !!result; - - const populateOrgs = (org, orgs) => { - account.org = { - entitlements: Object - .entries(org.entitlements || {}) - .reduce((obj, [ name, value ]) => { - if (name[0] !== '_') { - obj[name] = value; - } - return obj; - }, {}), - guid: org.guid, - id: org.org_id, - name: org.name, - region: org.region, - subscriptions: org.subscriptions || [], - teams: [] - }; - - account.orgs = orgs.map(({ guid, name, org_id }) => ({ - default: org_id === org.org_id, - guid, - id: org_id, - name - })); - }; - - if (result) { - const { org, orgs, role, roles, user } = result; - populateOrgs(org, orgs); - - account.role = role; - account.roles = roles; - - account.user = Object.assign({}, account.user, { - axwayId: user.axway_id, - dateJoined: user.date_activated, - email: user.email, - firstname: user.firstname, - guid: user.guid, - lastname: user.lastname, - organization: user.organization, - phone: user.phone - }); - } else if (account.org?.id) { - const org = await this.org.find(account, account.org.guid); - org.org_id = org.org_id || org.id; - populateOrgs(org, [ org ]); - } - - account.team = undefined; - - if (account.user.guid) { - const { teams } = await this.team.list(account, account.org?.id, account.user.guid); - account.org.teams = teams; - - const selectedTeamGuid = defaultTeams?.[account.hash]; - - if (teams.length) { - const team = teams.find(t => (selectedTeamGuid && t.guid === selectedTeamGuid) || (!selectedTeamGuid && t.default)) || teams[0]; - account.team = { - default: team.default, - guid: team.guid, - name: team.name, - roles: account.user.guid && team.users?.find(u => u.guid === account.user.guid)?.roles || [], - tags: team.tags - }; - } - } - - return account; - }, - - /** - * Returns a list of all authenticated accounts. - * @param {Object} [opts] - Various options. - * @param {Object} [opts.defaultTeams] - A map of account hashes to their selected team guid. - * @param {Array.} [opts.skip] - A list of accounts to skip validation for. - * @param {Boolean} [opts.validate] - When `true`, checks to see if each account has an - * active access token and session. - * @returns {Promise} - */ - list: async (opts = {}) => { - if (!opts || typeof opts !== 'object') { - throw E.INVALID_ARGUMENT('Expected options to be an object'); - } - - return this.authClient.list() - .then(accounts => accounts.reduce((promise, account) => { - return promise.then(async list => { - if (opts.validate && (!opts.skip || !opts.skip.includes(account.name))) { - try { - account = await this.auth.find(account.name, opts.defaultTeams); - } catch (err) { - warn(`Failed to load session for account "${account.name}": ${err.toString()}`); - } - } - if (account?.auth) { - delete account.auth.clientSecret; - delete account.auth.password; - delete account.auth.secret; - delete account.auth.username; - list.push(account); - } - return list; - }); - }, Promise.resolve([]))) - .then(list => list.sort((a, b) => a.name.localeCompare(b.name))); - }, - - /** - * Populates the specified account info object with a dashboard session id and org - * information. - * @param {Object} account - The account object. - * @param {Object} [defaultTeams] - A map of account hashes to their selected team guid. - * @returns {Promise} Resolves the original account info object. - */ - loadSession: async (account, defaultTeams) => { - try { - // grab the org guid before findSession clobbers it - const { guid } = account.org; - - account = await this.auth.findSession(account, defaultTeams); - - // validate the service account - if (account.isPlatformTooling) { - const filteredOrgs = account.orgs.filter(o => o.guid === guid); - if (!filteredOrgs.length) { - error(`Service account belongs to org "${guid}", but platform account belongs to:\n${account.orgs.map(o => ` "${o.guid}"`).join('\n')}`); - throw new Error('The service account\'s organization does not match the specified platform account\'s organizations'); - } - account.orgs = filteredOrgs; - } - } catch (err) { - if (err.code === 'ERR_SESSION_INVALIDATED') { - warn(`Detected invalidated session, purging account ${highlight(account.name)}`); - await this.authClient.logout({ - accounts: [ account.name ], - baseUrl: this.baseUrl - }); - return null; - } - throw err; - } - - await this.authClient.updateAccount(account); - - if (account.isPlatform) { - log(`Current org: ${highlight(account.org.name)} ${note(`(${account.org.guid})`)}`); - log('Available orgs:'); - for (const org of account.orgs) { - log(` ${highlight(org.name)} ${note(`(${org.guid})`)}`); - } - } - - delete account.auth.clientSecret; - delete account.auth.password; - delete account.auth.secret; - delete account.auth.username; - - return account; - }, - - /** - * Authenticates a user, retrieves the access tokens, populates the session id and - * org info, and returns it. - * @param {Object} opts - Various authentication options to override the defaults set - * via the `Auth` constructor. - * @param {String} [opts.password] - The platform tooling password used to - * authenticate. Requires a `username` and `clientSecret` or `secretFile`. - * @param {String} [opts.secretFile] - The path to the PEM formatted private key used - * to sign the JWT. - * @param {String} [opts.username] - The platform tooling username used to - * authenticate. Requires a `password` and `clientSecret` or `secretFile`. - * @returns {Promise} Resolves the account info object. - */ - login: async (opts = {}) => { - let account; - - // validate the username/password - const { password, username } = opts; - if (username || password) { - const clientSecret = opts.clientSecret || this.opts.clientSecret; - const secretFile = opts.secretFile || this.opts.secretFile; - if (!clientSecret && !secretFile) { - throw new Error('Username/password can only be specified when using client secret or secret file'); - } - if (!username || typeof username !== 'string') { - throw new TypeError('Expected username to be an email address'); - } - if (!password || typeof password !== 'string') { - throw new TypeError('Expected password to be a non-empty string'); - } - delete opts.username; - delete opts.password; - } - - // check if already logged in - if (!opts?.force) { - account = await this.authClient.find(opts); - if (account && !account.auth.expired) { - warn(`Account ${highlight(account.name)} is already authenticated`); - const err = new Error('Account already authenticated'); - err.account = account; - try { - err.account = await this.auth.loadSession(account); - } catch (e) { - warn(e); - } - err.code = 'EAUTHENTICATED'; - throw err; - } - } - - // do the login - account = await this.authClient.login(opts); - - // if we're in manual mode (e.g. --no-launch-browser), then return now - if (opts.manual) { - // account is actually an object containing `cancel`, `promise`, and `url` - return account; - } - - try { - // upgrade the service account with the platform tooling account - if (username && password) { - // request() will set the sid and update the account in the token store - await this.request('/api/v1/auth/login', account, { - errorMsg: 'Failed to authenticate', - isToolingAuth: true, - json: { - from: 'cli', - username, - password - } - }); - - account.isPlatformTooling = true; - } - - return await this.auth.loadSession(account); - } catch (err) { - // something happened, revoke the access tokens we just got and rethrow - await this.authClient.logout({ - accounts: [ account.name ], - baseUrl: this.baseUrl - }); - throw err; - } - }, - - /** - * Discards an access token and notifies AxwayID to revoke the access token. - * @param {Object} opts - Various authentication options to override the defaults set - * via the `Auth` constructor. - * @param {Array.} opts.accounts - A list of accounts names. - * @param {Boolean} opts.all - When `true`, revokes all accounts. - * @param {String} [opts.baseUrl] - The base URL used to filter accounts. - * @param {Function} [opts.onOpenBrowser] - A callback when the web browser is about to - * be launched. - * @returns {Promise} Resolves a list of revoked credentials. - */ - logout: async ({ accounts, all, baseUrl = this.baseUrl } = {}) => { - if (all) { - accounts = await this.authClient.list(); - } else { - if (!Array.isArray(accounts)) { - throw E.INVALID_ARGUMENT('Expected accounts to be a list of accounts'); - } - if (!accounts.length) { - return []; - } - accounts = (await this.authClient.list()).filter(account => accounts.includes(account.name)); - } - - for (const account of accounts) { - if (account.isPlatform && !account.isPlatformTooling) { - // note: there should only be 1 platform account in the accounts list - const { platformUrl } = environments.resolve(account.auth.env); - const { logout } = getEndpoints({ baseUrl: account.auth.baseUrl, realm: account.auth.realm }); - const redirect = `${logout}?redirect_uri=${platformUrl}/signed.out?msg=signout`; - const url = `${platformUrl}/api/v1/auth/logout?redirect=${encodeURIComponent(redirect)}`; - if (typeof opts.onOpenBrowser === 'function') { - await opts.onOpenBrowser({ url }); - } - try { - await open(url); - } catch (err) { - const m = err.message.match(/Exited with code (\d+)/i); - throw m ? new Error(`Failed to open web browser (code ${m[1]})`) : err; - } - } - } - - return await this.authClient.logout({ accounts: accounts.map(account => account.hash), baseUrl }); - }, - - /** - * Returns AxwayID server information. - * @param {Object} opts - Various authentication options to override the defaults set - * via the `Auth` constructor. - * @returns {Promise} - */ - serverInfo: opts => this.authClient.serverInfo(opts), - - /** - * Switches your current organization. - * @param {Object} [account] - The account object. Note that this object reference will - * be updated with new org info. - * @param {Object|String|Number} [org] - The organization object, name, guid, or id. - * @param {Object} [opts] - Various options. - * @param {Function} [opts.onOpenBrowser] - A callback when the web browser is about to - * be launched. - * @returns {Promise} Resolves the updated account object. - */ - switchOrg: async (account, org, opts = {}) => { - if (!account || account.auth.expired) { - log(`${account ? 'Account is expired' : 'No account specified'}, doing login`); - account = await this.authClient.login(); - } else { - try { - org = this.resolvePlatformOrg(account, org); - } catch (err) { - if (err.code !== 'ERR_INVALID_ACCOUNT' && err.code !== 'ERR_INVALID_PLATFORM_ACCOUNT' && err.code !== 'ERR_INVALID_ARGUMENT') { - // probably org not found - throw err; - } - org = undefined; - } - - log(`Switching ${highlight(account.name)} to org ${highlight(org.name)} (${org.guid})`); - - const server = new Server(); - const { start, url: redirect } = await server.createCallback((req, res) => { - log(`Telling browser to redirect to ${highlight(this.platformUrl)}`); - res.writeHead(302, { - Location: this.platformUrl - }); - res.end(); - }); - - try { - const url = createURL(`${this.platformUrl}/#/auth/org.select`, { - org_id: org?.id, - redirect - }); - log(`Launching default web browser: ${highlight(url)}`); - if (typeof opts.onOpenBrowser === 'function') { - await opts.onOpenBrowser({ url }); - } - try { - await open(url); - } catch (err) { - const m = err.message.match(/Exited with code (\d+)/i); - throw m ? new Error(`Failed to open web browser (code ${m[1]})`) : err; - } - - log(`Waiting for browser to be redirected to: ${highlight(redirect)}`); - await start(); - } finally { - await server.stop(); - } - } - - try { - log('Refreshing the account session...'); - if (account.sid) { - log(`Deleting sid ${account.sid}`); - delete account.sid; - } - return await this.auth.loadSession(account); - } catch (e) { - // squelch - log(e); - } - - throw new Error('Failed to switch organization'); - } - }; - - this.client = { - /** - * Creates a new service account. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {Object} opts - Various options. - * @param {String} [opts.desc] - The service account description. - * @param {String} opts.name - The display name. - * @param {String} [opts.publicKey] - A PEM formatted public key. - * @param {Array} [opts.roles] - A list of roles to assign to the service account. - * @param {String} [opts.secret] - A client secret key. - * @param {Array} [opts.teams] - A list of objects containing `guid` and `roles` - * properties. - * @returns {Promise} - */ - create: async (account, org, opts = {}) => { - org = this.resolvePlatformOrg(account, org); - - if (!opts || typeof opts !== 'object') { - throw E.INVALID_ARGUMENT('Expected options to be an object'); - } - - if (!opts.name || typeof opts.name !== 'string') { - throw E.INVALID_ARGUMENT('Expected name to be a non-empty string'); - } - - if (opts.desc && typeof opts.desc !== 'string') { - throw E.INVALID_ARGUMENT('Expected description to be a string'); - } - - const data = { - name: opts.name, - description: opts.desc || '', - org_guid: org.guid - }; - - if (opts.publicKey) { - if (typeof opts.publicKey !== 'string') { - throw E.INVALID_ARGUMENT('Expected public key to be a string'); - } - if (!opts.publicKey.startsWith('-----BEGIN PUBLIC KEY-----')) { - throw new Error('Expected public key to be PEM formatted'); - } - data.type = 'certificate'; - data.publicKey = opts.publicKey; - } else if (opts.secret) { - if (typeof opts.secret !== 'string') { - throw E.INVALID_ARGUMENT('Expected secret to be a string'); - } - data.type = 'secret'; - data.secret = opts.secret; - } else { - throw new Error('Expected public key or secret'); - } - - if (opts.roles) { - data.roles = await this.role.resolve(account, opts.roles, { client: true, org }); - } - - if (opts.teams) { - data.teams = await this.client.resolveTeams(account, org, opts.teams); - } - - return { - org, - client: await this.request('/api/v1/client', account, { - errorMsg: 'Failed to create service account', - json: data - }) - }; - }, - - /** - * Finds a service account by client id. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} clientId - The service account's client id. - * @returns {Promise} - */ - find: async (account, org, clientId) => { - assertPlatformAccount(account); - - const { clients } = await this.client.list(account, org); - - // first try to find the service account by guid, then client id, then name - let client = clients.find(c => c.guid === clientId); - if (!client) { - client = clients.find(c => c.client_id === clientId); - } - if (!client) { - client = clients.find(c => c.name === clientId); - } - - // if still not found, error - if (!client) { - throw new Error(`Service account "${clientId}" not found`); - } - - // get service account description - const { description } = await this.request(`/api/v1/client/${client.client_id}`, account, { - errorMsg: 'Failed to get service account' - }); - - client.description = description; - - const { teams } = await this.team.list(account, client.org_guid); - client.teams = []; - for (const team of teams) { - const user = team.users.find(u => u.type === 'client' && u.guid === client.guid); - if (user) { - client.teams.push({ - ...team, - roles: user.roles - }); - } - } - - return { - org: await this.org.find(account, client.org_guid), - client - }; - }, - - /** - * Generates a new public/private key pair. - * @returns {Promise} Resolves an object with `publicKey` and `privateKey` properties. - */ - async generateKeyPair() { - return await promisify(crypto.generateKeyPair)('rsa', { - modulusLength: 2048, - publicKeyEncoding: { type: 'spki', format: 'pem' }, - privateKeyEncoding: { type: 'pkcs8', format: 'pem' } - }); - }, - - /** - * Retrieves a list of all service accounts for the given org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @returns {Promise} Resolves the service account that was removed. - */ - list: async (account, org) => { - org = this.resolvePlatformOrg(account, org); - const clients = await this.request(`/api/v1/client?org_id=${org.id}`, account, { - errorMsg: 'Failed to get service accounts' - }); - - return { - org, - clients: clients - .map(c => { - c.method = this.client.resolveType(c.type); - return c; - }) - .sort((a, b) => a.name.localeCompare(b.name)) - }; - }, - - /** - * Removes a service account. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {Object|String} client - The service account object or client id. - * @returns {Promise} Resolves the service account that was removed. - */ - remove: async (account, org, client) => { - client = await this.client.resolveClient(account, org, client); - - await this.request(`/api/v1/client/${client.client_id}`, account, { - errorMsg: 'Failed to remove service account', - method: 'delete' - }); - - return { client, org }; - }, - - /** - * Resolves an org by name, id, org guid using the specified account. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, guid, or id. - * @param {Object|String} client - The service account object or client id. - * @returns {Promise} - */ - resolveClient: async (account, org, client) => { - if (client && typeof client === 'object' && client.client_id) { - return client; - } - - if (client && typeof client === 'string') { - return (await this.client.find(account, org, client)).client; - } - - throw E.INVALID_ARGUMENT('Expected client to be an object or client id'); - }, - - /** - * Validates a list of teams for the given org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {Array} [teams] - A list of objects containing `guid` and `roles` - * properties. - * @returns {Array} An aray of team guids. - */ - resolveTeams: async (account, org, teams) => { - if (!Array.isArray(teams)) { - throw E.INVALID_ARGUMENT('Expected teams to be an array'); - } - - if (!teams.length) { - return; - } - - const { teams: availableTeams } = await this.team.list(account, org); - const teamRoles = await this.role.list(account, { team: true, org }); - const guids = {}; - const resolvedTeams = []; - - for (const team of teams) { - if (!team || typeof team !== 'object' || !team.guid || typeof team.guid !== 'string' || !team.roles || !Array.isArray(team.roles) || !team.roles.length) { - throw E.INVALID_ARGUMENT('Expected team to be an object containing a guid and array of roles'); - } - - // find the team by name or guid - const lt = team.guid.toLowerCase().trim(); - const found = availableTeams.find(t => t.guid === lt || t.name.toLowerCase() === lt); - if (!found) { - throw new Error(`Invalid team "${team.guid}"`); - } - - // validate roles - for (const role of team.roles) { - if (!teamRoles.find(r => r.id === role)) { - throw new Error(`Invalid team role "${role}"`); - } - } - - // dedupe - if (guids[found.guid]) { - continue; - } - guids[found.guid] = 1; - - resolvedTeams.push({ - guid: found.guid, - roles: team.roles - }); - } - - return resolvedTeams; - }, - - /** - * Returns the service account auth type label. - * @param {String} type - The auth type. - * @returns {String} - */ - resolveType(type) { - return type === 'secret' ? 'Client Secret' : type === 'certificate' ? 'Client Certificate' : 'Other'; - }, - - /** - * Updates an existing service account's information. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {Object} opts - Various options. - * @param {Object|String} opts.client - The service account object or client id. - * @param {String} [opts.desc] - The service account description. - * @param {String} [opts.name] - The display name. - * @param {String} [opts.publicKey] - A PEM formatted public key. - * @param {Array} [opts.roles] - A list of roles to assign to the service account. - * @param {String} [opts.secret] - A client secret key. - * @param {Array} [opts.teams] - A list of objects containing `guid` and `roles` - * properties. - * @returns {Promise} - */ - update: async (account, org, opts = {}) => { - org = this.resolvePlatformOrg(account, org); - - if (!opts || typeof opts !== 'object') { - throw E.INVALID_ARGUMENT('Expected options to be an object'); - } - - const client = await this.client.resolveClient(account, org, opts.client); - const data = {}; - - if (opts.name) { - if (typeof opts.name !== 'string') { - throw E.INVALID_ARGUMENT('Expected name to be a non-empty string'); - } - data.name = opts.name; - } - - if (opts.desc) { - if (typeof opts.desc !== 'string') { - throw E.INVALID_ARGUMENT('Expected description to be a string'); - } - data.description = opts.desc; - } - - if (opts.publicKey) { - if (typeof opts.publicKey !== 'string') { - throw E.INVALID_ARGUMENT('Expected public key to be a string'); - } - if (!opts.publicKey.startsWith('-----BEGIN PUBLIC KEY-----')) { - throw new Error('Expected public key to be PEM formatted'); - } - if (client.type !== 'certificate') { - throw new Error(`Service account "${client.name}" uses auth method "${this.client.resolveType(client.type)}" and cannot be changed to "${this.client.resolveType('certificate')}"`); - } - data.publicKey = opts.publicKey; - } else if (opts.secret) { - if (typeof opts.secret !== 'string') { - throw E.INVALID_ARGUMENT('Expected secret to be a string'); - } - if (client.type !== 'secret') { - throw new Error(`Service account "${client.name}" uses auth method "${this.client.resolveType(client.type)}" and cannot be changed to "${this.client.resolveType('secret')}"`); - } - data.secret = opts.secret; - } - - if (opts.roles !== undefined) { - data.roles = !opts.roles ? [] : await this.role.resolve(account, opts.roles, { client: true, org }); - } - - if (opts.teams !== undefined) { - data.teams = opts.teams && await this.client.resolveTeams(account, org, opts.teams) || []; - } - - return { - org, - client: await this.request(`/api/v1/client/${client.guid}`, account, { - errorMsg: 'Failed to update service account', - json: data, - method: 'put' - }) - }; - } - }; - - this.entitlement = { - /** - * Retrieves entitlement information for a specific entitlement metric. - * @param {Object} account - The account object. - * @param {String} metric - The entitlement metric name. - * @returns {Promise} - */ - find: (account, metric) => this.request(`/api/v1/entitlement/${metric}`, account, { - errorMsg: 'Failed to get entitlement info' - }) - }; - - /** - * Retrieves activity for an organization or user. - * @param {Object} account - The account object. - * @param {Object} [params] - Various parameters. - * @param {String} [params.from] - The start date in ISO format. - * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and `from`. - * If `true`, uses current month. - * @param {Object|String|Number} [params.org] - The organization object, name, guid, or id. - * @param {String} [params.to] - The end date in ISO format. - * @param {String} [params.userGuid] - The user guid. - * @returns {Promise} - */ - const getActivity = async (account, params = {}) => { - assertPlatformAccount(account); - - if (params.month !== undefined) { - Object.assign(params, resovleMonthRange(params.month)); - } - - let { from, to } = resolveDateRange(params.from, params.to); - let url = '/api/v1/activity?data=true'; - - if (params.org) { - const { id } = this.resolvePlatformOrg(account, params.org); - url += `&org_id=${id}`; - } - - if (params.userGuid) { - url += `&user_guid=${params.userGuid}`; - } - - if (from) { - url += `&from=${from.toISOString()}`; - } - - if (to) { - url += `&to=${to.toISOString()}`; - } - - return { - from, - to, - events: await this.request(url, account, { - errorMsg: 'Failed to get user activity' - }) - }; - }; - - this.org = { - /** - * Retieves organization activity. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, guid, or id. - * @param {Object} [params] - Various parameters. - * @param {String} [params.from] - The start date in ISO format. - * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and - * `from`. If `true`, uses current month. - * @param {String} [params.to] - The end date in ISO format. - * @returns {Promise} - */ - activity: (account, org, params) => getActivity(account, { - ...params, - org - }), - - /** - * Retrieves the list of environments associated to the user's org. - * @param {Object} account - The account object. - * @returns {Promise} - */ - environments: async account => { - assertPlatformAccount(account); - return await this.request('/api/v1/org/env', account, { - errorMsg: 'Failed to get organization environments' - }); - }, - - /** - * Retrieves the organization family used to determine the child orgs. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @returns {Promise} - */ - family: async (account, org) => { - const { id } = this.resolvePlatformOrg(account, org); - return await this.request(`/api/v1/org/${id}/family`, account, { - errorMsg: 'Failed to get organization family' - }); - }, - - /** - * Retrieves organization details for an account. - * @param {Object} account - The account object. - * @param {String} org - The organization object, name, id, or guid. - * @returns {Promise} - */ - find: async (account, org) => { - const { id } = this.resolveOrg(account, org); - org = await this.request(`/api/v1/org/${id}`, account, { - errorMsg: 'Failed to get organization' - }); - - const subscriptions = org.subscriptions.map(s => ({ - category: s.product, // TODO: Replace with annotated name - edition: s.plan, // TODO: Replace with annotated name - expired: !!s.expired, - governance: s.governance || 'SaaS', - startDate: s.start_date, - endDate: s.end_date, - tier: s.tier - })); - - const { teams } = await this.team.list(account, id); - - const result = { - active: org.active, - created: org.created, - childOrgs: null, // deprecated - guid: org.guid, - id: id, - name: org.name, - entitlements: org.entitlements, - parentOrg: null, // deprecated - region: org.region, - insightUserCount: ~~org.entitlements.limit_read_only_users, - seats: org.entitlements.limit_users === 10000 ? null : org.entitlements.limit_users, - subscriptions, - teams, - teamCount: teams.length, - userCount: org.users.length, - userRoles: org.users.find(u => u.guid === account.user.guid)?.roles || [] - }; - - if (org.entitlements?.partners) { - for (const partner of org.entitlements.partners) { - result[partner] = org[partner]; - } - } - - return result; - }, - - /** - * Retrieves the list of orgs from the specified account. - * @param {Object} account - The account object. - * @param {String} defaultOrg - The name, id, or guid of the default organization. - * @returns {Promise} - */ - list: async (account, defaultOrg) => { - assertPlatformAccount(account); - - const { guid } = this.resolvePlatformOrg(account, defaultOrg); - - return account.orgs.map(o => ({ - ...o, - default: o.guid === guid - })).sort((a, b) => a.name.localeCompare(b.name)); - }, - - user: { - /** - * Adds a user to an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} email - The user's email. - * @param {Array.} roles - One or more roles to assign. Must include a "default" role. - * @returns {Promise} - */ - add: async (account, org, email, roles) => { - org = this.resolvePlatformOrg(account, org); - const { guid } = await this.request(`/api/v1/org/${org.id}/user`, account, { - errorMsg: 'Failed to add user to organization', - json: { - email, - roles: await this.role.resolve(account, roles, { org, requireDefaultRole: true }) - } - }); - log(`User "${guid}" added to org ${org.name} (${org.guid})`); - return { - org, - user: await this.org.user.find(account, org, guid) - }; - }, - - /** - * Finds a user and returns their information. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} user - The user email or guid. - * @returns {Promise} - */ - find: async (account, org, user) => { - const { users } = await this.org.user.list(account, org); - user = user.toLowerCase(); - return users.find(m => String(m.email).toLowerCase() === user || String(m.guid).toLowerCase() === user); - }, - - /** - * Lists all users in an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @returns {Promise} - */ - list: async (account, org) => { - org = this.resolvePlatformOrg(account, org); - const users = await this.request(`/api/v1/org/${org.id}/user?clients=1`, account, { - errorMsg: 'Failed to get organization users' - }); - return { - org, - users: users.sort((a, b) => { - if ((a.client_id && !b.client_id) || (!a.client_id && b.client_id)) { - return !a.client_id ? -1 : a.client_id ? 1 : 0; - } - const aname = a.name || `${a.firstname} ${a.lastname}`.trim(); - const bname = b.name || `${b.firstname} ${b.lastname}`.trim(); - return aname.localeCompare(bname); - }) - }; - }, - - /** - * Removes an user from an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} user - The user email or guid. - * @returns {Promise} - */ - remove: async (account, org, user) => { - org = this.resolvePlatformOrg(account, org); - const found = await this.org.user.find(account, org.guid, user); - - if (!found) { - throw new Error(`Unable to find the user "${user}"`); - } - - return { - org, - user: found, - ...(await this.request(`/api/v1/org/${org.id}/user/${found.guid}`, account, { - errorMsg: 'Failed to remove user from organization', - method: 'delete' - })) - }; - }, - - /** - * Updates a users role in an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} user - The user email or guid. - * @param {Array.} roles - One or more roles to assign. Must include a "default" role. - * @returns {Promise} - */ - update: async (account, org, user, roles) => { - org = this.resolvePlatformOrg(account, org); - const found = await this.org.user.find(account, org.guid, user); - - if (!found) { - throw new Error(`Unable to find the user "${user}"`); - } - - roles = await this.role.resolve(account, roles, { org, requireDefaultRole: true }); - - return { - org: await this.request(`/api/v1/org/${org.id}/user/${found.guid}`, account, { - errorMsg: 'Failed to update user\'s organization roles', - json: { - roles - }, - method: 'put' - }), - roles, - user: await this.org.user.find(account, org, found.guid) - }; - } - }, - - /** - * Renames an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} name - The new organization name. - * @returns {Promise} - */ - rename: async (account, org, name) => { - const { id, name: oldName } = this.resolvePlatformOrg(account, org); - - if (typeof name !== 'string' || !(name = name.trim())) { - throw E.INVALID_ARGUMENT('Organization name must be a non-empty string'); - } - - return { - ...(await this.request(`/api/v1/org/${id}`, account, { - errorMsg: 'Failed to rename organization', - json: { name }, - method: 'put' - })), - oldName - }; - }, - - /** - * Renames an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {Object} [params] - Various parameters. - * @param {String} [params.from] - The start date in ISO format. - * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and - * `from`. If `true`, uses current month. - * @param {String} [params.to] - The end date in ISO format. - * @returns {Promise} - */ - usage: async (account, org, params = {}) => { - const { id } = this.resolvePlatformOrg(account, org); - - if (params.month !== undefined) { - Object.assign(params, resovleMonthRange(params.month)); - } - - const { from, to } = resolveDateRange(params.from, params.to); - - let url = `/api/v1/org/${id}/usage`; - if (from) { - url += `?from=${from.toISOString()}`; - } - if (to) { - url += `${from ? '&' : '?'}to=${to.toISOString()}`; - } - - const results = await this.request(url, account, { - errorMsg: 'Failed to get organization usage' - }); - - if (results.bundle?.metrics) { - for (const [ metric, info ] of Object.entries(results.bundle.metrics)) { - if (!info.name) { - info.name = (await this.entitlement.find(account, metric)).title; - } - } - } - - return { - ...results, - from, - to - }; - } - }; - - this.role = { - /** - * Get all roles. - * @param {Object} account - The account object. - * @param {Object} [params] - Various parameters. - * @param {Boolean} [params.client] - When `true`, returns client specific roles. - * @param {Boolean} [params.default] - When `true`, returns default roles only. - * @param {Object|String|Number} [params.org] - The organization object, name, id, or guid. - * @param {Boolean} [params.team] - When `true`, returns team specific roles. - * @returns {Promise} - */ - list: async (account, params = {}) => { - let roles = await this.request( - `/api/v1/role${params.team ? '?team=true' : ''}`, - account, - { errorMsg: 'Failed to get roles' } - ); - - let org = params.org || account.org?.guid; - if (org) { - org = await this.org.find(account, org); - const { entitlements, subscriptions } = org; - - roles = roles.filter(role => { - return role.org - && (!role.partner || (entitlements.partners || []).includes(role.partner) && org[role.partner]?.provisioned) - && (!role.entitlement || entitlements[role.entitlement]) - && (!role.subscription || subscriptions.find(sub => { - return new Date(sub.end_date) >= new Date() && role.subscription.includes(sub.product); - })); - }); - } - - if (params.client) { - roles = roles.filter(r => r.client); - } - - if (params.default) { - roles = roles.filter(r => r.default); - } - - if (params.team) { - roles = roles.filter(r => r.team); - } - - return roles; - }, - - /** - * Fetches roles for the given params, then validates the supplied list of roles. - * @param {Object} account - The account object. - * @param {Array.} roles - One or more roles to assign. - * @param {Object} [opts] - Various options. - * @param {Boolean} [opts.client] - When `true`, returns client specific roles. - * @param {Boolean} [opts.default] - When `true`, returns default roles only. - * @param {Object|String|Number} [opts.org] - The organization object, name, id, or guid. - * @param {Boolean} [opts.requireRoles] - When `true`, throws an error if roles is empty. - * @param {Boolean} [opts.requireDefaultRole] - When `true`, throws an error if roles is empty or if there are no default roles. - * @param {Boolean} [opts.team] - When `true`, validates team specific roles. - * @returns {Promise} - */ - resolve: async (account, roles, opts) => { - if (!Array.isArray(roles)) { - throw E.INVALID_ARGUMENT('Expected roles to be an array'); - } - - if (!roles.length && !opts.requireRoles && !opts.requireDefaultRole) { - return []; - } - - const allowedRoles = await this.role.list(account, { - client: opts.client, - default: opts.default, - org: opts.org, - team: opts.team - }); - const defaultRoles = allowedRoles.filter(r => r.default).map(r => r.id); - - if (!roles.length && opts.requireDefaultRole) { - throw new Error(`Expected at least one of the following roles: ${defaultRoles.join(', ')}`); - } - if (!roles.length && opts.requireRoles) { - throw new Error(`Expected at least one of the following roles: ${allowedRoles.join(', ')}`); - } - - roles = roles - .reduce((arr, role) => arr.concat(role.split(',')), []) - .map(role => { - const lr = role.toLowerCase().trim(); - const found = allowedRoles.find(ar => ar.id === lr || ar.name.toLowerCase() === lr); - if (!found) { - throw new Error(`Invalid role "${role}", expected one of the following: ${allowedRoles.map(r => r.id).join(', ')}`); - } - return found.id; - }); - - log(`Resolved roles: ${highlight(roles.join(', '))}`); - - if (opts.requireDefaultRole && !roles.some(r => defaultRoles.includes(r))) { - throw new Error(`You must specify a default role: ${defaultRoles.join(', ')}`); - } - - return roles; - } - }; - - /** - * Determines team info changes and prepares the team info to be sent. - * @param {Object} [info] - The new team info. - * @param {Object} [prev] - The previous team info. - * @returns {Promise} - */ - const prepareTeamInfo = (info = {}, prev) => { - if (!info || typeof info !== 'object') { - throw E.INVALID_ARGUMENT('Expected team info to be an object'); - } - - const changes = {}; - const data = {}; - - // populate data - if (info.default !== undefined) { - data.default = !!info.default; - } - if (info.desc !== undefined) { - data.desc = String(info.desc).trim(); - } - if (info.name !== undefined) { - data.name = String(info.name).trim(); - } - if (info.tags !== undefined) { - if (!Array.isArray(info.tags)) { - throw E.INVALID_ARGUMENT('Expected team tags to be an array of strings'); - } - data.tags = info.tags - .reduce((arr, tag) => arr.concat(tag.split(',')), []) - .map(tag => tag.trim()); - } - - // remove unchanged - if (prev) { - for (const key of Object.keys(data)) { - if (Array.isArray(data[key])) { - if (!(data[key] < prev[key] || data[key] > prev[key])) { - delete data[key]; - } - } else if (data[key] === prev[key]) { - delete data[key]; - } else { - changes[key] = { - v: data[key], - p: prev[key] - }; - } - } - } - - return { changes, data }; - }; - - this.team = { - /** - * Creates a team in an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} name - The name of the team. - * @param {Object} [info] - The team info. - * @param {String} [info.desc] - The team description. - * @param {Boolean} [info.default] - When `true`, makes this team the default. - * @param {Array.} [info.tags] - A list of tags. - * @returns {Promise} - */ - create: async (account, org, name, info) => { - org = this.resolvePlatformOrg(account, org); - - if (!name || typeof name !== 'string') { - throw E.INVALID_ARGUMENT('Expected name to be a non-empty string'); - } - - const { data } = prepareTeamInfo(info); - data.name = name; - data.org_guid = org.guid; - - return { - org, - team: await this.request('/api/v1/team', account, { - errorMsg: 'Failed to create team', - json: data - }) - }; - }, - - /** - * Find a team by name or guid. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team name or guid. - * @returns {Promise} - */ - find: async (account, org, team) => { - org = this.resolvePlatformOrg(account, org); - - if (!team || typeof team !== 'string') { - throw E.INVALID_ARGUMENT('Expected team to be a name or guid'); - } - - const origTeam = team; - const { teams } = await this.team.list(account, org); - team = team.toLowerCase(); - team = teams.find(t => t.name.toLowerCase() === team || t.guid === team); - - if (!team) { - throw new Error(`Unable to find team "${origTeam}" in the "${org.name}" organization`); - } - - return { org, team }; - }, - - /** - * List all teams in an org. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} [user] - A user guid to filter teams - * @returns {Promise} - */ - list: async (account, org, user) => { - org = org && this.resolveOrg(account, org); - let teams = await this.request(`/api/v1/team${org?.id ? `?org_id=${org.id}` : ''}`, account, { - errorMsg: 'Failed to get organization teams' - }); - - if (user) { - teams = teams.filter(team => { - return team.users?.find(u => u.guid === user); - }); - } - - return { - org, - teams: teams.sort((a, b) => a.name.localeCompare(b.name)) - }; - }, - - user: { - /** - * Adds a user to a team. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team or guid. - * @param {String} user - The user email or guid. - * @param {Array.} roles - One or more roles to assign. Must include a "default" role. - * @returns {Promise} - */ - add: async (account, org, team, user, roles) => { - ({ org, team } = await this.team.find(account, org, team)); - - const found = await this.org.user.find(account, org.guid, user); - if (!found) { - throw new Error(`Unable to find the user "${user}"`); - } - - return { - org, - team: await this.request(`/api/v1/team/${team.guid}/user/${found.guid}`, account, { - errorMsg: 'Failed to add user to organization', - json: { - roles: await this.role.resolve(account, roles, { org, requireRoles: true, team: true }), - type: found.client_id ? 'client' : 'user' - } - }), - user: found - }; - }, - - /** - * Finds a user in a team. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team or guid. - * @param {String} user - The user email or guid. - * @returns {Promise} - */ - find: async (account, org, team, user) => { - let users; - ({ team, users } = await this.team.user.list(account, org, team)); - user = user.toLowerCase(); - return { - org, - team, - user: users.find(m => String(m.email).toLowerCase() === user || String(m.guid).toLowerCase() === user) - }; - }, - - /** - * List all users of a team. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team or guid. - * @returns {Promise} - */ - list: async (account, org, team) => { - ({ team } = await this.team.find(account, org, team)); - const { users: orgUsers } = await this.org.user.list(account, org.guid); - const users = []; - - for (const user of team.users) { - if (user.type === 'client') { - const { client } = await this.client.find(account, org, user.guid); - users.push({ - ...client, - roles: user.roles, - teams: client.teams.length, - type: user.type - }); - } else { - const orgUser = orgUsers.find(v => v.guid === user.guid); - if (orgUser) { - users.push({ - ...orgUser, - name: `${orgUser.firstname} ${orgUser.lastname}`.trim(), - roles: user.roles, - type: user.type || 'user' - }); - } else { - warn(`Unknown team user "${user.guid}"`); - } - } - } - - return { - org, - team, - users: users.sort((a, b) => { - if (a.type !== b.type) { - return a.type === 'user' ? -1 : a.type === 'client' ? 1 : 0; - } - return a.name.localeCompare(b.name); - }) - }; - }, - - /** - * Removes a user from a team. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team or guid. - * @param {String} user - The user email or guid. - * @returns {Promise} - */ - remove: async (account, org, team, user) => { - let found; - ({ user: found, team } = await this.team.user.find(account, org, team, user)); - - if (!found) { - throw new Error(`Unable to find the user "${user}"`); - } - - await this.request(`/api/v1/team/${team.guid}/user/${found.guid}`, account, { - errorMsg: 'Failed to remove user from team', - method: 'delete' - }); - - return { - org, - team, - user: found - }; - }, - - /** - * Updates a user's role in a team. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team or guid. - * @param {String} user - The user email or guid. - * @param {Array.} roles - One or more roles to assign. Must include a "default" role. - * @returns {Promise} - */ - update: async (account, org, team, user, roles) => { - let found; - ({ user: found, team } = await this.team.user.find(account, org, team, user)); - - if (!found) { - throw new Error(`Unable to find the user "${user}"`); - } - - roles = await this.role.resolve(account, roles, { org, requireRoles: true, team: true }); - - team = await this.request(`/api/v1/team/${team.guid}/user/${found.guid}`, account, { - errorMsg: 'Failed to update user\'s organization roles', - json: { - roles - }, - method: 'put' - }); - - found.roles = team.users.reduce((v, u) => { - return u.guid === found.guid ? u.roles : v; - }, []); - - return { - org, - team, - user: found, - roles - }; - } - }, - - /** - * Removes a team from an organization. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team or guid. - * @returns {Promise} - */ - remove: async (account, org, team) => { - ({ org, team } = await this.team.find(account, org, team)); - - await this.request(`/api/v1/team/${team.guid}`, account, { - errorMsg: 'Failed to remove team', - method: 'delete' - }); - - return { org, team }; - }, - - /** - * Updates team information. - * @param {Object} account - The account object. - * @param {Object|String|Number} org - The organization object, name, id, or guid. - * @param {String} team - The team or guid. - * @param {Object} [info] - The team info. - * @param {String} [info.desc] - The team description. - * @param {Boolean} [info.default] - When `true`, makes this team the default. - * @param {Array.} [info.tags] - A list of tags. - * @returns {Promise} - */ - update: async (account, org, team, info) => { - ({ org, team } = await this.team.find(account, org, team)); - - const { changes, data } = prepareTeamInfo(info, team); - - if (Object.keys(data).length) { - team = await this.request(`/api/v1/team/${team.guid}`, account, { - errorMsg: 'Failed to update team', - json: data, - method: 'put' - }); - } - - return { - changes, - org, - team - }; - } - }; - - this.user = { - /** - * Retrieves an account's user's activity. - * @param {Object} account - The account object. - * @param {Object} [params] - Various parameters. - * @param {String} [params.from] - The start date in ISO format. - * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and - * `from`. If `true`, uses current month. - * @param {String} [params.to] - The end date in ISO format. - * @returns {Promise} - */ - activity: (account, params) => getActivity(account, { - ...params, - userGuid: account.user.guid - }), - - /** - * Retrieves a user's information. - * @param {Object} account - The account object. - * @param {String} user - The user email or guid. - * @returns {Promise} - */ - find: async (account, user) => { - if (typeof user === 'object' && user?.guid) { - return user; - } - - try { - if (!user.includes('@')) { - return await this.request(`/api/v1/user/${user}`, account, { - errorMsg: 'Failed to find user' - }); - } - - const users = await this.request(`/api/v1/user?term=${user}`, account, { - errorMsg: 'Failed to find user' - }); - - if (users.length > 0) { - return users[0]; - } - } catch (err) { - warn(err.toString()); - } - - throw new Error(`User "${user}" not found`); - }, - - /** - * Updates an account's user's information. - * @param {Object} account - The account object. - * @param {Object} [info] - Various user fields. - * @param {String} [info.firstname] - The user's first name. - * @param {String} [info.lastname] - The user's last name. - * @param {String} [info.phone] - The user's phone number. - * @returns {Promise} - */ - update: async (account, info = {}) => { - assertPlatformAccount(account); - - if (!info || typeof info !== 'object') { - throw E.INVALID_ARGUMENT('Expected user info to be an object'); - } - - const changes = {}; - const json = {}; - let { user } = account; - - // populate data - if (info.firstname !== undefined) { - json.firstname = String(info.firstname).trim(); - } - if (info.lastname !== undefined) { - json.lastname = String(info.lastname).trim(); - } - if (info.phone !== undefined) { - json.phone = String(info.phone).trim(); - } - - // remove unchanged - for (const key of Object.keys(json)) { - if (json[key] === user[key]) { - delete json[key]; - } else { - changes[key] = { - v: json[key], - p: user[key] - }; - } - } - - if (Object.keys(json).length) { - await this.request(`/api/v1/user/profile/${user.guid}`, account, { - errorMsg: 'Failed to update user information', - json, - method: 'put' - }); - - log('Refreshing account information...'); - ({ user } = await this.auth.loadSession(account)); - } - - return { - changes, - user - }; - } - }; - } - - /** - * Returns an Amplify Auth SDK client or creates one if it doesn't exist. - * @type {Auth} - * @access public - */ - get authClient() { - try { - if (!this._authClient) { - this._authClient = new Auth(this.opts); - } - return this._authClient; - } catch (err) { - if (err.code === 'ERR_SECURE_STORE_UNAVAILABLE') { - const isWin = process.platform === 'win32'; - err.message = `Secure token store is not available.\nPlease reinstall the Axway CLI by running:\n ${isWin ? '' : 'sudo '}npm install --global ${isWin ? '' : '--unsafe-perm '}axway`; - } - throw err; - } - } - - /** - * Makes an HTTP request. - * @param {String} path - The path to append to the URL. - * @param {Object} account - The account object. - * @param {Object} [opts] - Various options. - * @param {Boolean} [opts.isToolingAuth] - When `true`, bypasses the the no sid/token check. - * @param {Object} [opts.json] - A JSON payload to send. - * @param {String} [opts.method] - The HTTP method to use. If not set, then uses `post` if - * `opts.json` is set, otherwise `get`. - * @param {String} [opts.resultKey='result'] - The name of the property return from the response. - * @returns {Promise} Resolves the JSON-parsed result. - * @access private - */ - async request(path, account, { errorMsg, isToolingAuth, json, method, resultKey = 'result' } = {}) { - try { - if (!account || typeof account !== 'object') { - throw new TypeError('Account required'); - } - - const { sid } = account; - const token = account.auth?.tokens?.access_token; - if (!sid && !token && !isToolingAuth) { - throw new Error('Invalid/expired account'); - } - - const url = `${this.platformUrl || this.env.platformUrl}${path}`; - const headers = { - Accept: 'application/json', - 'User-Agent': this.userAgent - }; - - if (account.sid) { - headers.Cookie = `connect.sid=${account.sid}`; - } else if (token) { - headers.Authorization = `Bearer ${token}`; - } - - if (!method) { - method = json ? 'post' : 'get'; - } - - let response; - const opts = { - headers, - json: json ? JSON.parse(JSON.stringify(json)) : undefined, - responseType: 'json', - retry: 0 - }; - let error; - - try { - log(`${method.toUpperCase()} ${highlight(url)} ${note(`(${account.sid ? `sid ${account.sid}` : `token ${token}`})`)}`); - if (opts.json) { - log(redact(opts.json, { clone: true })); - } - response = await this.got[method](url, opts); - } catch (e) { - error = e; - warn(error); - if (error.response?.body) { - warn(error.response.body); - } - } - - if (error || (path === '/api/v1/auth/findSession' && response.body?.[resultKey] === null)) { - if ((!error || (error.code && error.code > 400)) && account.sid) { - // sid is probably bad, try again with the token - warn('Platform session was invalidated, trying again to reinitialize session with token'); - headers.Authorization = `Bearer ${token}`; - delete headers.Cookie; - log(`${method.toUpperCase()} ${highlight(url)} ${note(`(${account.sid ? `sid ${account.sid}` : `token ${token}`})`)}`); - try { - response = await this.got[method](url, opts); - } catch (err) { - // access token is invalid - throw E.SESSION_INVALIDATED('Platform session has been invalidated'); - } - } else if (error) { - throw error; - } - } - - const cookies = response.headers['set-cookie']; - const connectSid = cookies && setCookie.parse(cookies).find(c => c.name === 'connect.sid')?.value; - if (connectSid) { - log(`Setting sid: ${highlight(connectSid)}`); - account.sid = connectSid; - await this.authClient.updateAccount(account); - } - - return response.body?.[resultKey]; - } catch (err) { - const msg = err.response?.body?.message || err.response?.body?.description; - err.message = `${errorMsg ? `${errorMsg}: ` : ''}${msg || err.message}`; - if (err.response?.statusCode) { - err.message += ` (${err.response.statusCode})`; - } - - const code = err.response?.body?.code; - if (code) { - err.code = code; - } - - throw err; - } - } - - /** - * Resolves an org by name, id, org guid using the specified account. - * - * @param {Object} account - The account object. - * @param {Object|String|Number} [org] - The organization object, name, guid, or id. - * @returns {Promise} Resolves the org info from the account object. - * @access public - */ - resolveOrg(account, org) { - if (org && typeof org === 'object' && org.guid) { - return org; - } - - if (org === undefined) { - org = account.org.guid; - } - - if (typeof org !== 'string' && typeof org !== 'number') { - throw E.INVALID_ARGUMENT('Expected organization identifier'); - } - - const found = account.orgs.find(o => { - return o.guid?.toLowerCase() === String(org).toLowerCase() - || String(o.id) === String(org) - || o.name?.toLowerCase() === String(org).toLowerCase(); - }); - - if (!found) { - throw new Error(`Unable to find the organization "${org}"`); - } - - log(`Resolved org "${org}"${found.name ? ` as ${found.name}` : ''} (${found.id}) ${found.guid}`); - - return found; - } - - /** - * Asserts the account is a platform account, then resolves an org by name, id, org guid using - * the specified account. - * - * @param {Object} account - The account object. - * @param {Object|String|Number} [org] - The organization object, name, guid, or id. - * @returns {Promise} Resolves the org info from the account object. - * @access public - */ - resolvePlatformOrg(account, org) { - assertPlatformAccount(account); - return this.resolveOrg(account, org); - } -} - -/** - * Checks that the specified account is a platform account. - * - * @param {Object} account - The account object. - */ -function assertPlatformAccount(account) { - if (!account || typeof account !== 'object') { - throw E.INVALID_ACCOUNT('Account required'); - } - - if (!account.isPlatform) { - throw E.INVALID_PLATFORM_ACCOUNT('Account must be a platform account'); - } -} - -/** - * Takes two date strings in the format `YYYY-MM-DD` and returns them as date objects. - * - * @param {String} [from] - The range start date. - * @param {String} [to] - The range end date. - * @returns {Object} - */ -function resolveDateRange(from, to) { - const r = { - from: null, - to: null - }; - const tsRE = /^\d{4}-\d{2}-\d{2}$/; - let ts; - - if (from) { - if (!tsRE.test(from) || isNaN(ts = Date.parse(`${from} 00:00:00 GMT`))) { - throw new Error('Expected "from" date to be in the format YYYY-MM-DD'); - } - r.from = new Date(ts); - } else { - r.from = new Date(Date.now() - (14 * 24 * 60 * 60 * 1000)); // 14 days - } - - if (to) { - if (!tsRE.test(to) || isNaN(ts = Date.parse(`${to} 23:59:59 GMT`))) { - throw new Error('Expected "to" date to be in the format YYYY-MM-DD'); - } - r.to = new Date(ts); - } else { - r.to = new Date(); - } - - return r; -} - -/** - * Determines the from and to date range for the specified month or month/year. - * - * @param {String|Number|Boolean} month - The month, year and month, or `""`/`true` for current - * month, to create a date range from. - * @return {Object} - */ -export function resovleMonthRange(month) { - const now = new Date(); - let year = now.getUTCFullYear(); - let monthIdx = now.getUTCMonth(); - let monthInt = monthIdx + 1; - - if (typeof month === 'number') { - monthIdx = month - 1; - monthInt = month; - } else if (month !== true && month !== '') { - if (typeof month !== 'string') { - throw E.INVALID_ARGUMENT('Expected month to be in the format YYYY-MM or MM'); - } - - const m = month.match(/^(?:(\d{4})-)?(\d\d?)$/); - if (!m || !m[2]) { - throw E.INVALID_ARGUMENT('Expected month to be in the format YYYY-MM or MM'); - } - - if (m[1]) { - year = parseInt(m[1]); - } - monthInt = parseInt(m[2]); - monthIdx = monthInt - 1; - } - - const days = [ 31, year % 4 === 0 ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; - if (!days[monthIdx]) { - throw new RangeError(`Invalid month "${monthInt}"`); - } - - const monthStr = String(monthIdx + 1).padStart(2, '0'); - return { - from: `${year}-${monthStr}-01`, - to: `${year}-${monthStr}-${days[monthIdx]}` - }; -} diff --git a/packages/amplify-sdk/src/amplify-sdk.ts b/packages/amplify-sdk/src/amplify-sdk.ts new file mode 100644 index 00000000..b01eee67 --- /dev/null +++ b/packages/amplify-sdk/src/amplify-sdk.ts @@ -0,0 +1,229 @@ +/* eslint-disable promise/no-nesting */ + +import AmplifySDKActivity from './sdk/activity.js'; +import AmplifySDKAuth from './sdk/auth.js'; +import AmplifySDKClient from './sdk/client.js'; +import AmplifySDKEntitlement from './sdk/entitlement.js'; +import AmplifySDKOrg from './sdk/org.js'; +import AmplifySDKRole from './sdk/role.js'; +import AmplifySDKTeam from './sdk/team.js'; +import AmplifySDKUser from './sdk/user.js'; +import E from './errors.js'; +import fs from 'fs-extra'; +import path from 'path'; +import setCookie from 'set-cookie-parser'; +import snooplogg from 'snooplogg'; +import * as environments from './environments.js'; +import * as request from '@axway/amplify-request'; +import { Account, AmplifySDKOptions } from './types.js'; +import { fileURLToPath } from 'url'; +import { Got, HTTPAlias, OptionsOfJSONResponseBody } from 'got'; +import { redact } from '@axway/amplify-utils'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const { log, warn } = snooplogg('amplify-sdk'); +const { highlight, note } = snooplogg.styles; + +/** + * An SDK for accessing Amplify API's. + */ +export default class AmplifySDK { + activity: AmplifySDKActivity; + auth: AmplifySDKAuth; + client: AmplifySDKClient; + env: environments.EnvironmentInfo; + entitlement: AmplifySDKEntitlement; + got: Got; + opts: AmplifySDKOptions; + org: AmplifySDKOrg; + platformUrl?: string; + role: AmplifySDKRole; + team: AmplifySDKTeam; + user: AmplifySDKUser; + userAgent: string; + + /** + * Initializes the environment and SDK's API. + * + * @param {Object} opts - Authentication options. + * @param {Object} [opts.env=prod] - The environment name. + * @param {Object} [opts.requestOptions] - HTTP request options with proxy settings and such to + * create a `got` HTTP client. + * @access public + */ + constructor(opts: AmplifySDKOptions = {}) { + if (typeof opts !== 'object') { + throw E.INVALID_ARGUMENT('Expected options to be an object'); + } + + /** + * Authentication options including clientID, env, realm, and token store settings. + * @type {Object} + */ + this.opts = { ...opts }; + delete this.opts.username; + delete this.opts.password; + + /** + * Resolved environment-specific settings. + * @type {Object} + */ + this.env = environments.resolve(opts.env); + + /** + * The `got` HTTP client. + * @type {Function} + */ + this.got = request.init(opts.requestOptions) as any; + if (!opts.got) { + opts.got = this.got; + } + + /** + * The platform URL. + * @type {String} + */ + this.platformUrl = (opts.platformUrl || this.env.platformUrl || '').replace(/\/$/, '') || undefined; + + const { version } = fs.readJsonSync(path.resolve(__dirname, '../package.json')); + + /** + * The Axway ID realm. + * + * IMPORTANT! Platform explicitly checks this user agent, so do NOT change the name or case. + * + * @type {String} + */ + this.userAgent = `AMPLIFY SDK/${version} (${process.platform}; ${process.arch}; node:${process.versions.node})${process.env.AXWAY_CLI ? ` Axway CLI/${process.env.AXWAY_CLI}` : ''}`; + + this.activity = new AmplifySDKActivity(this); + this.auth = new AmplifySDKAuth(this, { + baseUrl: (opts.baseUrl || this.env.baseUrl || '').replace(/\/$/, '') || undefined, + platformUrl: this.platformUrl, + realm: opts.realm || this.env.realm + }); + this.client = new AmplifySDKClient(this); + this.entitlement = new AmplifySDKEntitlement(this); + this.org = new AmplifySDKOrg(this); + this.role = new AmplifySDKRole(this); + this.team = new AmplifySDKTeam(this); + this.user = new AmplifySDKUser(this); + } + + /** + * Makes an HTTP request. + * @param {String} path - The path to append to the URL. + * @param {Object} account - The account object. + * @param {Object} [opts] - Various options. + * @param {Boolean} [opts.isToolingAuth] - When `true`, bypasses the the no sid/token check. + * @param {Object} [opts.json] - A JSON payload to send. + * @param {String} [opts.method] - The HTTP method to use. If not set, then uses `post` if + * `opts.json` is set, otherwise `get`. + * @param {String} [opts.resultKey='result'] - The name of the property return from the response. + * @returns {Promise} Resolves the JSON-parsed result. + * @access private + */ + async request(path: string, account: Account, opts: { + errorMsg?: string, + isToolingAuth?: boolean, + json?: any, + method?: string, + resultKey?: string + } = {}) { + const { errorMsg, isToolingAuth, json, resultKey = 'result' } = opts; + let { method } = opts; + try { + if (!account || typeof account !== 'object') { + throw new TypeError('Account required'); + } + + const { sid } = account; + const token = account.auth?.tokens?.access_token; + if (!sid && !token && !isToolingAuth) { + throw new Error('Invalid/expired account'); + } + + const url = `${this.platformUrl || this.env.platformUrl}${path}`; + const headers: { [key: string]: string } = { + Accept: 'application/json', + 'User-Agent': this.userAgent + }; + + if (account.sid) { + headers.Cookie = `connect.sid=${account.sid}`; + } else if (token) { + headers.Authorization = `Bearer ${token}`; + } + + if (!method) { + method = json ? 'post' : 'get'; + } + + let response: any; + const opts = { + headers, + json: json ? JSON.parse(JSON.stringify(json)) : undefined, + responseType: 'json', + retry: { limit: 0 } + }; + let error; + + try { + log(`${method.toUpperCase()} ${highlight(url)} ${note(`(${account.sid ? `sid ${account.sid}` : `token ${token}`})`)}`); + if (json) { + log(redact(json, { clone: true })); + } + response = await this.got[method as HTTPAlias](url, opts as OptionsOfJSONResponseBody); + } catch (e: any) { + error = e; + warn(error); + if (error.response?.body) { + warn(error.response.body); + } + } + + if (error || (path === '/api/v1/auth/findSession' && response.body?.[resultKey] === null)) { + if ((!error || (error.code && error.code > 400)) && account.sid) { + // sid is probably bad, try again with the token + warn('Platform session was invalidated, trying again to reinitialize session with token'); + headers.Authorization = `Bearer ${token}`; + delete headers.Cookie; + log(`${method.toUpperCase()} ${highlight(url)} ${note(`(${account.sid ? `sid ${account.sid}` : `token ${token}`})`)}`); + try { + response = await this.got[method as HTTPAlias](url, opts as OptionsOfJSONResponseBody); + } catch (err: any) { + // access token is invalid + throw E.SESSION_INVALIDATED('Platform session has been invalidated'); + } + } else if (error) { + throw error; + } + } + + const cookies = response.headers['set-cookie']; + const connectSid = cookies && setCookie.parse(cookies).find(c => c.name === 'connect.sid')?.value; + if (connectSid) { + log(`Setting sid: ${highlight(connectSid)}`); + account.sid = connectSid; + await this.auth.client.updateAccount(account); + } + + return response.body?.[resultKey]; + } catch (err: any) { + const msg = err.response?.body?.message || err.response?.body?.description; + err.message = `${errorMsg ? `${errorMsg}: ` : ''}${msg || err.message}`; + if (err.response?.statusCode) { + err.statusCode = err.response.statusCode; + err.message += ` (${err.response.statusCode})`; + } + + const code = err.response?.body?.code; + if (code) { + err.code = code; + } + + throw err; + } + } +} diff --git a/packages/amplify-sdk/src/auth.js b/packages/amplify-sdk/src/auth.ts similarity index 80% rename from packages/amplify-sdk/src/auth.js rename to packages/amplify-sdk/src/auth.ts index d1790eec..f1f5456a 100644 --- a/packages/amplify-sdk/src/auth.js +++ b/packages/amplify-sdk/src/auth.ts @@ -1,29 +1,119 @@ -import E from './errors'; +import E from './errors.js'; -import Authenticator from './authenticators/authenticator'; -import ClientSecret from './authenticators/client-secret'; -import OwnerPassword from './authenticators/owner-password'; -import PKCE from './authenticators/pkce'; -import SignedJWT from './authenticators/signed-jwt'; +import Authenticator from './authenticators/authenticator.js'; +import ClientSecret, { ClientSecretOptions } from './authenticators/client-secret.js'; +import OwnerPassword, { OwnerPasswordOptions } from './authenticators/owner-password.js'; +import PKCE from './authenticators/pkce.js'; +import SignedJWT, { SignedJWTOptions } from './authenticators/signed-jwt.js'; -import FileStore from './stores/file-store'; -import MemoryStore from './stores/memory-store'; -import SecureStore from './stores/secure-store'; -import TokenStore from './stores/token-store'; +import FileStore from './stores/file-store.js'; +import MemoryStore from './stores/memory-store.js'; +import SecureStore from './stores/secure-store.js'; +import TokenStore from './stores/token-store.js'; -import getEndpoints from './endpoints'; +import getEndpoints from './endpoints.js'; import snooplogg from 'snooplogg'; -import * as environments from './environments'; +import * as environments from './environments.js'; import * as request from '@axway/amplify-request'; +import { Account, AccountAuthInfo, AuthenticatorOptions } from './types.js'; +import { Got } from 'got'; const { log, warn } = snooplogg('amplify-sdk:auth'); const { alert, highlight, magenta, note } = snooplogg.styles; +export interface AuthOptions { + baseUrl?: string, + clientId?: string, + clientSecret?: string, + env?: string, + got?: Got, + homeDir?: string, + interactiveLoginTimeout?: number, + password?: string, + persistSecrets?: boolean, + platformUrl?: string, + realm?: string, + requestOptions?: request.RequestOptions, + secretFile?: string, + secureServiceName?: string, + serviceAccount?: boolean, + tokenRefreshThreshold?: number, + tokenStore?: TokenStore, + tokenStoreDir?: string, + tokenStoreType?: 'auto' | 'secure' | 'file' | 'memory' | null, + username?: string +} + +export interface DefaultOptions { + accountName?: string, + app?: string | string[], + authenticator?: Authenticator, + baseUrl?: string, + clientId?: string, + clientSecret?: string, + code?: string, + env?: string, + got?: Got, + hash?: string, + interactiveLoginTimeout?: number, + manual?: boolean, + onOpenBrowser?: (p: { url: string }) => void, + password?: string, + persistSecrets?: boolean, + platformUrl?: string, + realm?: string, + secretFile?: string, + serviceAccount?: boolean, + timeout?: number, + username?: string +} + +export interface LogoutOptions { + accounts?: string | string[], + all?: boolean, + baseUrl?: string +} + +export interface ServerInfo { + [key: string]: string +} + +export interface ServerInfoOptions { + baseUrl?: string, + env?: string, + realm?: string, + url?: string +} + /** * Authenticates the machine and retreives the auth token. */ export default class Auth { + baseUrl?: string; + + clientId?: string; + + clientSecret?: string; + + env: string; + + got!: Got; + + interactiveLoginTimeout?: number; + + password?: string; + + persistSecrets?: boolean; + + platformUrl?: string; + + realm?: string; + + secretFile?: string; + + serviceAccount?: boolean; + /** * The number of seconds before the access token expires and should be refreshed. * @@ -38,7 +128,9 @@ export default class Auth { * @type {TokenStore} * @access private */ - tokenStore = null; + tokenStore: TokenStore | null = null; + + username?: string; /** * Initializes the authentication instance by setting the default settings and creating the @@ -72,7 +164,7 @@ export default class Auth { * using this library when using the "secure" token store. * @param {Boolean} [opts.serviceAccount=false] - When `true`, indicates authentication is being * requested by a service instead of a user. - * @param {Boolean} [opts.tokenRefreshThreshold=0] - The number of seconds before the access + * @param {number} [opts.tokenRefreshThreshold=0] - The number of seconds before the access * token expires and should be refreshed. * @param {TokenStore} [opts.tokenStore] - A token store instance for persisting the tokens. * @param {String} [opts.tokenStoreDir] - The directory where the token store is saved. Required @@ -84,13 +176,16 @@ export default class Auth { * @param {String} [opts.username] - The username used to authenticate. Requires a `password`. * @access public */ - constructor(opts = {}) { + constructor(opts: AuthOptions = {}) { if (!opts || typeof opts !== 'object') { throw E.INVALID_ARGUMENT('Expected options to be an object'); } if (opts.tokenRefreshThreshold !== undefined) { - const threshold = parseInt(opts.tokenRefreshThreshold, 10); + let threshold = opts.tokenRefreshThreshold; + if (typeof threshold === 'string') { + threshold = parseInt(threshold, 10); + } if (isNaN(threshold)) { throw E.INVALID_PARAMETER('Expected token refresh threshold to be a number of seconds'); } @@ -108,7 +203,6 @@ export default class Auth { clientSecret: { value: opts.clientSecret }, got: { value: opts.got || request.init(opts.requestOptions) }, interactiveLoginTimeout: { value: opts.interactiveLoginTimeout }, - messages: { value: opts.messages }, password: { value: opts.password }, realm: { value: opts.realm }, persistSecrets: { writable: true, value: opts.persistSecrets }, @@ -138,7 +232,7 @@ export default class Auth { this.persistSecrets = true; } break; - } catch (e) { + } catch (e: any) { /* istanbul ignore if */ if (tokenStoreType === 'auto') { // let 'auto' fall through @@ -153,7 +247,7 @@ export default class Auth { try { this.tokenStore = new FileStore(opts); break; - } catch (e) { + } catch (e: any) { /* istanbul ignore if */ if (tokenStoreType === 'auto' && e.code === 'ERR_MISSING_REQUIRED_PARAMETER') { // let 'auto' fall through @@ -182,7 +276,7 @@ export default class Auth { * @returns {Object} * @access private */ - applyDefaults(opts = {}) { + applyDefaults(opts: DefaultOptions = {}) { if (!opts || typeof opts !== 'object') { throw E.INVALID_ARGUMENT('Expected options to be an object'); } @@ -201,7 +295,6 @@ export default class Auth { clientSecret: opts.clientSecret || this.clientSecret, env: env.name, got: opts.got || this.got, - messages: opts.messages || this.messages, password: opts.password || this.password, persistSecrets: opts.persistSecrets !== undefined ? opts.persistSecrets : this.persistSecrets, platformUrl: opts.platformUrl || this.platformUrl, @@ -229,7 +322,7 @@ export default class Auth { * @returns {Authenticator} * @access public */ - createAuthenticator(opts = {}) { + createAuthenticator(opts: DefaultOptions = {}) { if (opts.authenticator) { if (!(opts.authenticator instanceof Authenticator)) { throw E.INVALID_ARUGMENT('Expected authenticator to be an Authenticator instance.'); @@ -244,21 +337,21 @@ export default class Auth { if (typeof opts.username === 'string' && opts.username && typeof opts.password === 'string') { log(`Creating ${highlight('OwnerPassword')} authenticator`); - return new OwnerPassword(opts); + return new OwnerPassword(opts as OwnerPasswordOptions); } if (typeof opts.clientSecret === 'string' && opts.clientSecret) { log(`Creating ${highlight('ClientSecret')} authenticator`); - return new ClientSecret(opts); + return new ClientSecret(opts as ClientSecretOptions); } if (typeof opts.secretFile === 'string' && opts.secretFile) { log(`Creating ${highlight('SignedJWT')} authenticator`); - return new SignedJWT(opts); + return new SignedJWT(opts as SignedJWTOptions); } log(`Creating ${highlight('PKCE')} authenticator`); - return new PKCE(opts); + return new PKCE(opts as AuthenticatorOptions); } /** @@ -286,7 +379,11 @@ export default class Auth { * @returns {Promise} * @access public */ - async find(opts = {}) { + async find(opts?: DefaultOptions | string) { + if (opts === undefined) { + opts = {}; + } + if (!this.tokenStore) { log('Cannot get account, no token store'); return null; @@ -303,16 +400,18 @@ export default class Auth { opts.hash = authenticator.hash; } - const account = await this.tokenStore.get(opts); + const account: Account | null = await this.tokenStore.get(opts); if (!account) { return; } // copy over the correct auth params for (const prop of [ 'baseUrl', 'clientId', 'realm', 'env', 'clientSecret', 'username', 'password', 'secret' ]) { - if (account.auth[prop] && opts[prop] !== account.auth[prop]) { - log(`Overriding "${prop}" auth param with account's: ${opts[prop]} -> ${account.auth[prop]}`); - opts[prop] = account.auth[prop]; + if (account.auth[prop as keyof AccountAuthInfo] + && opts[prop as keyof DefaultOptions] !== account.auth[prop as keyof AccountAuthInfo]) { + + log(`Overriding "${prop}" auth param with account's: ${opts[prop as keyof DefaultOptions]} -> ${account.auth[prop as keyof AccountAuthInfo]}`); + opts[prop as keyof DefaultOptions] = account.auth[prop as keyof AccountAuthInfo] as any; } } authenticator = this.createAuthenticator(opts); @@ -339,7 +438,7 @@ export default class Auth { try { log(`Refreshing access token for account ${highlight(account.name || account.hash)}`); return await authenticator.getToken(null, null, true); - } catch (err) { + } catch (err: any) { if (err.code !== 'EINVALIDGRANT') { throw err; } @@ -356,7 +455,7 @@ export default class Auth { try { return await authenticator.getInfo(account); - } catch (err) { + } catch (err: any) { if (err.statusCode === 401) { warn(`Removing invalid account ${highlight(account.name || account.hash)} due to stale token`); await this.tokenStore.delete(account.name, opts.baseUrl); @@ -376,7 +475,7 @@ export default class Auth { * @returns {Promise} * @access public */ - async list() { + async list(): Promise { if (this.tokenStore) { return (await this.tokenStore.list()) .filter(account => (account.auth.env || 'prod') === this.env); @@ -407,7 +506,7 @@ export default class Auth { * user info. * @access public */ - async login(opts = {}) { + async login(opts: DefaultOptions = {}) { opts = this.applyDefaults(opts); const authenticator = this.createAuthenticator(opts); return await authenticator.login(opts); @@ -416,27 +515,31 @@ export default class Auth { /** * Revokes all or specific authenticated accounts. * - * @param {Object} opts - Required options. - * @param {Array.} opts.accounts - A list of accounts names or hashes. + * @param {Object} [opts] - Required options. + * @param {Array.} [opts.accounts] - A list of accounts names or hashes. * @param {Boolean} [opts.all] - When `true`, revokes all accounts. * @param {String} [opts.baseUrl] - The base URL used to filter accounts. * @returns {Promise} Resolves a list of revoked credentials. * @access public */ - async logout({ accounts, all, baseUrl } = {}) { + async logout(opts: LogoutOptions = {}): Promise { if (!this.tokenStore) { log('No token store, returning empty array'); return []; } + const { all, baseUrl } = opts || {}; + let accounts: string[] = []; + if (!all) { - if (!accounts) { + if (!opts.accounts) { throw E.INVALID_ARGUMENT('Expected accounts to be a list of accounts'); } - if (typeof accounts === 'string') { - accounts = [ accounts ]; - } - if (!Array.isArray(accounts)) { + if (typeof opts.accounts === 'string') { + accounts = [ opts.accounts ]; + } else if (Array.isArray(opts.accounts)) { + accounts = opts.accounts; + } else { throw E.INVALID_ARGUMENT('Expected accounts to be a list of accounts'); } if (!accounts.length) { @@ -457,9 +560,9 @@ export default class Auth { if (!entry.isPlatform) { const url = `${getEndpoints(entry.auth).logout}?id_token_hint=${entry.auth.tokens.id_token}`; try { - const { statusCode } = await this.got(url, { responseType: 'json', retry: 0 }); + const { statusCode } = await this.got(url, { responseType: 'json', retry: { limit: 0 } }); log(`Successfully logged out ${highlight(entry.name)} ${magenta(statusCode)} ${note(`(${entry.auth.baseUrl}, ${entry.auth.realm})`)}`); - } catch (err) { + } catch (err: any) { log(`Failed to log out ${highlight(entry.name)} ${alert(err.status)} ${note(`(${entry.auth.baseUrl}, ${entry.auth.realm})`)}`); } } @@ -481,7 +584,7 @@ export default class Auth { * @returns {Promise} * @access public */ - async serverInfo(opts = {}) { + async serverInfo(opts: ServerInfoOptions | undefined = {}): Promise { opts = this.applyDefaults(opts); let { url } = opts; @@ -496,8 +599,8 @@ export default class Auth { try { log(`Fetching server info: ${highlight(url)}...`); - return (await this.got(url, { responseType: 'json', retry: 0 })).body; - } catch (err) { + return (await this.got(url, { responseType: 'json', retry: { limit: 0 } })).body as ServerInfo; + } catch (err: any) { if (err.name !== 'ParseError') { err.message = `Failed to get server info (status ${err.response.statusCode})`; } @@ -512,7 +615,7 @@ export default class Auth { * @returns {Promise} * @access public */ - async updateAccount(account) { + async updateAccount(account: Account) { if (this.tokenStore) { await this.tokenStore.set(account); } diff --git a/packages/amplify-sdk/src/authenticators/authenticator.js b/packages/amplify-sdk/src/authenticators/authenticator.ts similarity index 77% rename from packages/amplify-sdk/src/authenticators/authenticator.js rename to packages/amplify-sdk/src/authenticators/authenticator.ts index 2863a7fe..f0209d35 100644 --- a/packages/amplify-sdk/src/authenticators/authenticator.js +++ b/packages/amplify-sdk/src/authenticators/authenticator.ts @@ -1,22 +1,42 @@ -import E from '../errors'; +import E from '../errors.js'; import ejs from 'ejs'; import fs from 'fs-extra'; -import getEndpoints from '../endpoints'; +import getEndpoints, { Endpoints } from '../endpoints.js'; +import http from 'http'; import jws from 'jws'; import open from 'open'; import path from 'path'; +import Server, { CallbackHandle } from '../server.js'; import snooplogg from 'snooplogg'; -import TokenStore from '../stores/token-store'; +import TokenStore from '../stores/token-store.js'; -import * as environments from '../environments'; +import * as environments from '../environments.js'; import * as request from '@axway/amplify-request'; -import Server from '../server'; -import { createURL, md5, prepareForm } from '../util'; +import { Account, AuthenticatorOptions, ManualLoginResult, Org, User } from '../types.js'; +import { createURL, md5, prepareForm } from '../util.js'; +import { fileURLToPath } from 'url'; +import { Got } from 'got'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const { log, warn } = snooplogg('amplify-auth:authenticator'); const { green, highlight, red, note } = snooplogg.styles; +export type AuthenticatorParamsResult = { [key: string]: string } | null; +export type AuthorizationUrlParamsResult = { [key: string]: string } | null; +export type HashParamsResult = { [key: string]: string } | null; +export type TokenParamsResult = { [key: string]: string } | null; +export type RefreshTokenParamsResult = { [key: string]: string } | null; + +interface LoginOptions { + app?: string | string[], + code?: string, + manual?: boolean, + onOpenBrowser?: (p: { url: string }) => void, + timeout?: number +} + /** * Orchestrates authentication and token management. */ @@ -83,7 +103,21 @@ export default class Authenticator { * @type {TokenStore} * @access private */ - tokenStore = null; + tokenStore: TokenStore | null = null; + + baseUrl = ''; + + clientId = ''; + + endpoints: Endpoints; + + env: environments.EnvironmentInfo; + + got: Got; + + platformUrl: string; + + realm = ''; /** * Initializes the authenticator instance. @@ -107,7 +141,7 @@ export default class Authenticator { * @param {TokenStore} [opts.tokenStore] - A token store instance for persisting the tokens. * @access public */ - constructor(opts) { + constructor(opts: AuthenticatorOptions) { if (!opts || typeof opts !== 'object') { throw E.INVALID_ARGUMENT('Expected options to be an object'); } @@ -125,24 +159,39 @@ export default class Authenticator { this.platformUrl = opts.platformUrl || this.env.platformUrl; - this.persistSecrets = opts.persistSecrets; + this.persistSecrets = !!opts.persistSecrets; // validate the required string properties - for (const prop of [ 'clientId', 'realm' ]) { - if (opts[prop] === undefined || !opts[prop] || typeof opts[prop] !== 'string') { - throw E.MISSING_REQUIRED_PARAMETER(`Expected required parameter "${prop}" to be a non-empty string`); - } - this[prop] = opts[prop]; + if (!opts.clientId || typeof opts.clientId !== 'string') { + throw E.MISSING_REQUIRED_PARAMETER('Expected required parameter "clientId" to be a non-empty string'); + } + this.clientId = opts.clientId; + + if (!opts.realm || typeof opts.realm !== 'string') { + throw E.MISSING_REQUIRED_PARAMETER('Expected required parameter "realm" to be a non-empty string'); } + this.realm = opts.realm; // validate optional string options - for (const prop of [ 'accessType', 'responseType', 'scope' ]) { - if (opts[prop] !== undefined) { - if (typeof opts[prop] !== 'string') { - throw E.INVALID_PARAMETER(`Expected parameter "${prop}" to be a string`); - } - this[prop] = opts[prop]; + if (opts.accessType !== undefined) { + if (typeof opts.accessType !== 'string') { + throw E.INVALID_PARAMETER('Expected parameter "accessType" to be a string'); + } + this.accessType = opts.accessType; + } + + if (opts.responseType !== undefined) { + if (typeof opts.responseType !== 'string') { + throw E.INVALID_PARAMETER('Expected parameter "responseType" to be a string'); + } + this.responseType = opts.responseType; + } + + if (opts.scope !== undefined) { + if (typeof opts.scope !== 'string') { + throw E.INVALID_PARAMETER('Expected parameter "scope" to be a string'); } + this.scope = opts.scope; } // define the endpoints @@ -157,10 +206,10 @@ export default class Authenticator { if (!url || typeof url !== 'string') { throw E.INVALID_PARAMETER(`Expected "${name}" endpoint URL to be a non-empty string`); } - if (!this.endpoints[name]) { + if (!this.endpoints[name as keyof Endpoints]) { throw E.INVALID_VALUE(`Invalid endpoint "${name}"`); } - this.endpoints[name] = url; + this.endpoints[name as keyof Endpoints] = url; } } @@ -171,7 +220,7 @@ export default class Authenticator { this.tokenStore = opts.tokenStore; } - this.got = opts.got || request.got; + this.got = (opts.got || request.got) as Got; } /* istanbul ignore next */ @@ -181,7 +230,7 @@ export default class Authenticator { * @type {?Object} * @access private */ - get authorizationUrlParams() { + get authorizationUrlParams(): AuthorizationUrlParamsResult { return null; } @@ -192,7 +241,7 @@ export default class Authenticator { * @returns {Object} The original account object. * @access public */ - async getInfo(account) { + async getInfo(account: Account): Promise { try { const accessToken = account.auth.tokens.access_token; log(`Fetching user info: ${highlight(this.endpoints.userinfo)} ${note(accessToken)}`); @@ -202,24 +251,24 @@ export default class Authenticator { Authorization: `Bearer ${accessToken}` }, responseType: 'json', - retry: 0 + retry: { limit: 0 } }); - const { email, family_name, given_name, guid, org_guid, org_name } = body; + const { email, family_name, given_name, guid, org_guid, org_name } = body as { [key: string]: string }; if (!account.user || typeof account.user !== 'object') { - account.user = {}; + account.user = {} as User; } account.user.email = email; - account.user.firstName = given_name; + account.user.firstname = given_name; account.user.guid = guid || account.user.guid; - account.user.lastName = family_name; + account.user.lastname = family_name; if (!account.org || typeof account.org !== 'object') { - account.org = {}; + account.org = {} as Org; } account.org.name = org_name; account.org.guid = org_guid; - } catch (err) { + } catch (err: any) { const status = err.response?.statusCode; warn(`Fetch user info failed: ${err.message}${status ? ` (${status})` : ''}`); } @@ -241,10 +290,26 @@ export default class Authenticator { * @returns {Promise} Resolves the account object. * @access private */ - async getToken(code, redirectUri, force) { + async getToken(code?: string | null, redirectUri?: string | null, force?: boolean): Promise { + interface FetchTokenParams { + clientId?: string, + code: string, + grantType?: string, + redirectUri: string, + refreshToken?: string + } + + interface TokenResponse { + access_token: string, + expires_in: number, + id_token: string, + refresh_expires_in: number, + refresh_token: string + } + let now = Date.now(); let expires; - let tokens; + let tokens: TokenResponse | null = null; let response; // if you have a code, then you probably don't want to have gone through all the hassle of @@ -268,17 +333,17 @@ export default class Authenticator { } const url = this.endpoints.token; - const fetchTokens = async params => { + const fetchTokens = async (params: FetchTokenParams) => { try { log(`Fetching token: ${highlight(url)}`); log('Post form:', { ...params, password: '********' }); const response = await this.got.post(url, { - form: prepareForm(params), + form: Object.fromEntries(prepareForm(params as any).entries()), responseType: 'json' }); log(`${(response.statusCode >= 400 ? red : green)(String(response.statusCode))} ${highlight(url)}`); return response; - } catch (err) { + } catch (err: any) { if (err.code === 'ECONNREFUSED') { // don't change the code, just re-throw throw err; @@ -304,13 +369,13 @@ export default class Authenticator { } }; - if (tokens?.refresh_token && expires.refresh && expires.refresh > now) { + if (tokens && tokens.refresh_token && expires && expires.refresh && expires.refresh > now) { log('Refreshing token using refresh token'); response = await fetchTokens(Object.assign({ clientId: this.clientId, grantType: Authenticator.GrantTypes.RefreshToken, refreshToken: tokens.refresh_token - }, this.refreshTokenParams)); + }, this.refreshTokenParams) as any); } else { // get new token using the code @@ -324,13 +389,13 @@ export default class Authenticator { throw E.MISSING_AUTH_CODE('Expected code for interactive authentication to be a non-empty string'); } params.code = code; - params.redirectUri = redirectUri; + params.redirectUri = redirectUri as string; } - response = await fetchTokens(params); + response = await fetchTokens(params as any); } - tokens = response.body; + tokens = response.body as TokenResponse; log(`Authentication successful ${note(`(${response.headers['content-type']})`)}`); log(tokens); @@ -338,7 +403,7 @@ export default class Authenticator { let email; let guid; let idp; - let org; + let org: Org = {} as Org; let name = this.hash; try { @@ -355,9 +420,9 @@ export default class Authenticator { idp = info.payload.identity_provider; const { orgId } = info.payload; if (orgId) { - org = { name: orgId, id: orgId }; + org = { name: orgId, org_id: orgId } as Org; } - } catch (e) { + } catch (e: any) { throw E.AUTH_FAILED('Authentication failed: Invalid server response'); } @@ -384,12 +449,10 @@ export default class Authenticator { org, orgs: org ? [ org ] : [], user: { - axwayId: undefined, email, - firstName: undefined, + firstname: '', guid, - lastName: undefined, - organization: undefined + lastname: '' } }); @@ -426,7 +489,7 @@ export default class Authenticator { * @type {String} * @access public */ - get hash() { + get hash(): string { return this.clientId.replace(/\s/g, '_').replace(/_+/g, '_') + ':' + md5(Object.assign({ baseUrl: this.baseUrl, env: this.env.name === 'prod' ? undefined : this.env.name, @@ -441,11 +504,11 @@ export default class Authenticator { * @type {?Object} * @access private */ - get hashParams() { + get hashParams(): HashParamsResult { return null; } - get authenticatorParams() { + get authenticatorParams(): AuthenticatorParamsResult { return null; } @@ -469,7 +532,7 @@ export default class Authenticator { * successfully authenticating. * @access public */ - async login(opts = {}) { + async login(opts: LoginOptions = {}): Promise { if (!this.interactive || opts.code !== undefined) { if (this.interactive) { log('Retrieving tokens using auth code'); @@ -487,7 +550,7 @@ export default class Authenticator { timeout: opts.timeout }); - const orgSelectedCallback = await server.createCallback(async (req, res) => { + const orgSelectedCallback = await server.createCallback(async (req: http.IncomingMessage, res: http.ServerResponse) => { res.writeHead(302, { 'Content-Type': 'text/html', Location: this.platformUrl @@ -499,7 +562,7 @@ export default class Authenticator { })); }); - const codeCallback = await server.createCallback(async (req, res, { searchParams }) => { + const codeCallback: CallbackHandle = await server.createCallback(async (req: http.IncomingMessage, res: http.ServerResponse, { searchParams }) => { const code = searchParams.get('code'); if (!code) { throw new Error('Invalid auth code'); @@ -545,7 +608,9 @@ export default class Authenticator { // if manual, return now with the auth url if (opts.manual) { return { - cancel: () => Promise.all([ codeCallback.cancel(), orgSelectedCallback.cancel() ]), + async cancel() { + await Promise.all([ codeCallback.cancel(), orgSelectedCallback.cancel() ]); + }, promise, url: authorizationUrl }; @@ -557,8 +622,8 @@ export default class Authenticator { await opts.onOpenBrowser({ url: authorizationUrl }); } try { - await open(authorizationUrl, opts); - } catch (err) { + await open(authorizationUrl, opts as open.Options); + } catch (err: any) { const m = err.message.match(/Exited with code (\d+)/i); throw m ? new Error(`Failed to open web browser (code ${m[1]})`) : err; } @@ -574,7 +639,7 @@ export default class Authenticator { * @type {?Object} * @access private */ - get refreshTokenParams() { + get refreshTokenParams(): RefreshTokenParamsResult { return null; } @@ -585,7 +650,7 @@ export default class Authenticator { * @type {?Object} * @access private */ - get tokenParams() { + get tokenParams(): TokenParamsResult { return null; } } diff --git a/packages/amplify-sdk/src/authenticators/client-secret.js b/packages/amplify-sdk/src/authenticators/client-secret.ts similarity index 74% rename from packages/amplify-sdk/src/authenticators/client-secret.js rename to packages/amplify-sdk/src/authenticators/client-secret.ts index 0256094a..b320bf54 100644 --- a/packages/amplify-sdk/src/authenticators/client-secret.js +++ b/packages/amplify-sdk/src/authenticators/client-secret.ts @@ -1,13 +1,28 @@ -import Authenticator from './authenticator'; -import E from '../errors'; +import Authenticator, { + AuthenticatorParamsResult, + AuthorizationUrlParamsResult, + HashParamsResult, + TokenParamsResult, + RefreshTokenParamsResult +} from './authenticator.js'; +import { AuthenticatorOptions } from '../types.js'; +import E from '../errors.js'; const { AuthorizationCode, ClientCredentials } = Authenticator.GrantTypes; +export interface ClientSecretOptions extends AuthenticatorOptions { + clientSecret?: string, + serviceAccount?: boolean +} + /** * Authentication scheme using a pre-shared secret token. By default, the authentication process is * interactive unless it is a service account. */ export default class ClientSecret extends Authenticator { + clientSecret!: string; + shouldFetchOrgs: boolean; + /** * Initializes an client secret authentication instance. * @@ -17,7 +32,7 @@ export default class ClientSecret extends Authenticator { * requested by a service instead of a user. * @access public */ - constructor(opts) { + constructor(opts?: ClientSecretOptions) { if (!opts || typeof opts !== 'object') { throw E.INVALID_ARGUMENT('Expected options to be an object'); } @@ -40,7 +55,7 @@ export default class ClientSecret extends Authenticator { * @type {Object} * @access private */ - get authenticatorParams() { + get authenticatorParams(): AuthenticatorParamsResult { return { clientSecret: this.clientSecret }; @@ -52,7 +67,7 @@ export default class ClientSecret extends Authenticator { * @type {Object} * @access private */ - get authorizationUrlParams() { + get authorizationUrlParams(): AuthorizationUrlParamsResult { return { grantType: this.interactive ? AuthorizationCode : ClientCredentials }; @@ -64,34 +79,34 @@ export default class ClientSecret extends Authenticator { * @type {Object} * @access private */ - get hashParams() { + get hashParams(): HashParamsResult { return { clientSecret: this.clientSecret }; } /** - * Parameters to include with authentication requests. + * Parameters to include with refresh requests. * * @type {Object} * @access private */ - get tokenParams() { + get refreshTokenParams(): RefreshTokenParamsResult { return { - clientSecret: this.clientSecret, - grantType: this.interactive ? AuthorizationCode : ClientCredentials + clientSecret: this.clientSecret }; } /** - * Parameters to include with refresh requests. + * Parameters to include with authentication requests. * * @type {Object} * @access private */ - get refreshTokenParams() { + get tokenParams(): TokenParamsResult { return { - clientSecret: this.clientSecret + clientSecret: this.clientSecret, + grantType: this.interactive ? AuthorizationCode : ClientCredentials }; } } diff --git a/packages/amplify-sdk/src/authenticators/owner-password.js b/packages/amplify-sdk/src/authenticators/owner-password.ts similarity index 75% rename from packages/amplify-sdk/src/authenticators/owner-password.js rename to packages/amplify-sdk/src/authenticators/owner-password.ts index aec9afd2..0df7cb59 100644 --- a/packages/amplify-sdk/src/authenticators/owner-password.js +++ b/packages/amplify-sdk/src/authenticators/owner-password.ts @@ -1,10 +1,23 @@ -import Authenticator from './authenticator'; -import E from '../errors'; +import Authenticator, { + AuthenticatorParamsResult, + HashParamsResult, + TokenParamsResult +} from './authenticator.js'; +import { AuthenticatorOptions } from '../types.js'; +import E from '../errors.js'; + +export interface OwnerPasswordOptions extends AuthenticatorOptions { + username?: string, + password?: string +} /** * Authentication scheme using a username and password. */ export default class OwnerPassword extends Authenticator { + username!: string; + password!: string; + /** * Initializes an owner password authentication instance. * @@ -13,7 +26,7 @@ export default class OwnerPassword extends Authenticator { * @param {String} opts.password - The password used to authenticate. * @access public */ - constructor(opts) { + constructor(opts: OwnerPasswordOptions) { if (!opts || typeof opts !== 'object') { throw E.INVALID_ARGUMENT('Expected options to be an object'); } @@ -39,7 +52,7 @@ export default class OwnerPassword extends Authenticator { * @type {Object} * @access private */ - get authenticatorParams() { + get authenticatorParams(): AuthenticatorParamsResult { return { username: this.username, password: this.password @@ -52,7 +65,7 @@ export default class OwnerPassword extends Authenticator { * @type {Object} * @access private */ - get hashParams() { + get hashParams(): HashParamsResult { return { username: this.username }; @@ -64,7 +77,7 @@ export default class OwnerPassword extends Authenticator { * @type {?Object} * @access private */ - get tokenParams() { + get tokenParams(): TokenParamsResult { return { grantType: Authenticator.GrantTypes.Password, username: this.username, diff --git a/packages/amplify-sdk/src/authenticators/pkce.js b/packages/amplify-sdk/src/authenticators/pkce.ts similarity index 76% rename from packages/amplify-sdk/src/authenticators/pkce.js rename to packages/amplify-sdk/src/authenticators/pkce.ts index 8d4de419..f8f40ebb 100644 --- a/packages/amplify-sdk/src/authenticators/pkce.js +++ b/packages/amplify-sdk/src/authenticators/pkce.ts @@ -1,4 +1,5 @@ -import Authenticator from './authenticator'; +import Authenticator, { TokenParamsResult } from './authenticator.js'; +import { AuthenticatorOptions } from '../types.js'; import crypto from 'crypto'; /** @@ -10,7 +11,9 @@ export default class PKCE extends Authenticator { * authentication and verified by the server when retrieving the access token. * @type {String} */ - codeVerifier = null; + codeVerifier = ''; + + interactive: boolean; /** * Initializes an PKCE authentication instance. @@ -18,7 +21,7 @@ export default class PKCE extends Authenticator { * @param {Object} opts - Various options. * @access public */ - constructor(opts) { + constructor(opts: AuthenticatorOptions) { super(opts); this.codeVerifier = crypto.randomBytes(32) @@ -35,9 +38,9 @@ export default class PKCE extends Authenticator { * @type {Object} * @access private */ - get authorizationUrlParams() { + get authorizationUrlParams(): { codeChallenge: string, codeChallengeMethod: string, grantType: string } { const codeChallenge = crypto.createHash('sha256') - .update(this.codeVerifier) + .update(this.codeVerifier as string) .digest('base64') .split('=')[0] .replace(/\+/g, '-') @@ -56,7 +59,7 @@ export default class PKCE extends Authenticator { * @type {Object} * @access private */ - get tokenParams() { + get tokenParams(): TokenParamsResult { return { codeVerifier: this.codeVerifier, grantType: Authenticator.GrantTypes.AuthorizationCode diff --git a/packages/amplify-sdk/src/authenticators/signed-jwt.js b/packages/amplify-sdk/src/authenticators/signed-jwt.ts similarity index 79% rename from packages/amplify-sdk/src/authenticators/signed-jwt.js rename to packages/amplify-sdk/src/authenticators/signed-jwt.ts index f9a9847a..eedd6057 100644 --- a/packages/amplify-sdk/src/authenticators/signed-jwt.js +++ b/packages/amplify-sdk/src/authenticators/signed-jwt.ts @@ -1,5 +1,11 @@ -import Authenticator from './authenticator'; -import E from '../errors'; +import Authenticator, { + AuthenticatorParamsResult, + HashParamsResult, + TokenParamsResult, + RefreshTokenParamsResult +} from './authenticator.js'; +import { AuthenticatorOptions } from '../types.js'; +import E from '../errors.js'; import fs from 'fs'; import jws from 'jws'; @@ -8,10 +14,20 @@ import { v4 as uuidv4 } from 'uuid'; const { JWTAssertion, ClientCredentials } = Authenticator.GrantTypes; +export interface SignedJWTOptions extends AuthenticatorOptions { + secret?: string, + secretFile?: string +} + /** * Authentication scheme using a JSON Web Token (JWT). */ export default class SignedJWT extends Authenticator { + shouldFetchOrgs: boolean; + signedJWT = ''; + secret!: string; + secretFile = ''; + /** * Initializes an PKCE authentication instance. * @@ -20,12 +36,13 @@ export default class SignedJWT extends Authenticator { * @param {String} [opts.secretFile] - The path to the private key file when `secret` is not set. * @access public */ - constructor(opts) { + constructor(opts?: SignedJWTOptions) { if (!opts || typeof opts !== 'object') { throw E.INVALID_ARGUMENT('Expected options to be an object'); } - let { secret, secretFile } = opts; + let { secret } = opts; + const { secretFile } = opts; if (!secret && !secretFile) { throw E.INVALID_ARGUMENT('Expected either a private key or private key file to be an object'); @@ -48,7 +65,7 @@ export default class SignedJWT extends Authenticator { this.shouldFetchOrgs = false; - if (!/^-----BEGIN (RSA )?PRIVATE KEY-----/.test(secret)) { + if (!secret || !/^-----BEGIN (RSA )?PRIVATE KEY-----/.test(secret)) { throw new Error(`Private key file ${opts.secretFile} is not a PEM formatted file`); } Object.defineProperty(this, 'secret', { value: secret }); @@ -60,7 +77,7 @@ export default class SignedJWT extends Authenticator { * @returns {String} * @access private */ - getSignedJWT() { + getSignedJWT(): string { if (this.signedJWT) { return this.signedJWT; } @@ -80,7 +97,7 @@ export default class SignedJWT extends Authenticator { }, secret: this.secret }); - } catch (err) { + } catch (err: any) { err.message = `Bad secret file "${this.secretFile}" (${err.message})`; throw err; } @@ -93,7 +110,7 @@ export default class SignedJWT extends Authenticator { * @type {Object} * @access private */ - get authenticatorParams() { + get authenticatorParams(): AuthenticatorParamsResult { return { secret: this.secret }; @@ -105,7 +122,7 @@ export default class SignedJWT extends Authenticator { * @type {Object} * @access private */ - get hashParams() { + get hashParams(): HashParamsResult { return { secret: this.secret }; @@ -117,7 +134,7 @@ export default class SignedJWT extends Authenticator { * @type {Object} * @access private */ - get refreshTokenParams() { + get refreshTokenParams(): RefreshTokenParamsResult { return { clientAssertion: this.getSignedJWT(), clientAssertionType: JWTAssertion @@ -130,7 +147,7 @@ export default class SignedJWT extends Authenticator { * @type {Object} * @access private */ - get tokenParams() { + get tokenParams(): TokenParamsResult { return { clientAssertion: this.getSignedJWT(), clientAssertionType: JWTAssertion, diff --git a/packages/amplify-sdk/src/endpoints.js b/packages/amplify-sdk/src/endpoints.ts similarity index 78% rename from packages/amplify-sdk/src/endpoints.js rename to packages/amplify-sdk/src/endpoints.ts index d1761857..e2ce976b 100644 --- a/packages/amplify-sdk/src/endpoints.js +++ b/packages/amplify-sdk/src/endpoints.ts @@ -1,4 +1,13 @@ -import E from './errors'; +import E from './errors.js'; + +export interface Endpoints { + auth: string; + certs: string; + logout: string; + token: string; + userinfo: string; + wellKnown: string; +} /** * Constructs all endpoints. @@ -9,7 +18,7 @@ import E from './errors'; * @param {String} params.realm - The authentication realm. * @returns {Object} */ -export default function getEndpoints({ baseUrl, realm } = {}) { +export default function getEndpoints({ baseUrl, realm }: { baseUrl?: string, realm?: string } = {}): Endpoints { if (!baseUrl || typeof baseUrl !== 'string') { throw E.INVALID_ARGUMENT('Expected baseUrl to be a non-empty string'); } diff --git a/packages/amplify-sdk/src/environments.js b/packages/amplify-sdk/src/environments.ts similarity index 59% rename from packages/amplify-sdk/src/environments.js rename to packages/amplify-sdk/src/environments.ts index 6f21e8fb..3d8917cb 100644 --- a/packages/amplify-sdk/src/environments.js +++ b/packages/amplify-sdk/src/environments.ts @@ -1,9 +1,19 @@ +interface EnvironmentProps { + baseUrl: string; + platformUrl: string; + realm: string; +} + +export interface EnvironmentInfo extends EnvironmentProps { + name: string; +} + /** * Environment specific default settings. * * @type {Object} */ -export const environments = { +export const environments: { [key: string]: EnvironmentProps } = { staging: { baseUrl: 'https://login.axwaytest.net', platformUrl: 'https://platform.axwaytest.net', @@ -16,17 +26,17 @@ export const environments = { } }; -const mapping = { - dev: 'staging', - development: 'staging', - preprod: 'staging', - preproduction: 'staging', +const mapping: { [key: string]: string } = { + dev: 'staging', + development: 'staging', + preprod: 'staging', + preproduction: 'staging', 'pre-production': 'staging', - production: 'prod', - test: 'staging' + production: 'prod', + test: 'staging' }; -export function resolve(env) { +export function resolve(env?: string): EnvironmentInfo { let environment = 'prod'; if (env) { if (typeof env !== 'string') { diff --git a/packages/amplify-sdk/src/errors.js b/packages/amplify-sdk/src/errors.ts similarity index 87% rename from packages/amplify-sdk/src/errors.js rename to packages/amplify-sdk/src/errors.ts index 12e109b3..5ff3b427 100644 --- a/packages/amplify-sdk/src/errors.js +++ b/packages/amplify-sdk/src/errors.ts @@ -1,4 +1,14 @@ -const errors = {}; +export interface AmplifySDKError extends Error { + code?: string, + body?: string, + statusCode?: number, + statusMessage?: string +} + +type ErrorBuilder = (msg: string, meta?: any) => AmplifySDKError; +type ErrorList = { [key: string]: ErrorBuilder }; + +const errors: ErrorList = {}; export default errors; createError('AUTH_FAILED', Error, 'Authorization failed'); @@ -6,6 +16,7 @@ createError('AUTH_TIMEOUT', Error, 'A successful login did no createError('INVALID_ACCOUNT', TypeError, 'Account object is required'); createError('INVALID_ARGUMENT', TypeError, 'A function argument is undefined or the incorrect data type'); createError('INVALID_FILE', Error, 'The file does not exist or access is denied'); +createError('INVALID_MONTH', RangeError, 'The month must be be between 1 and 12'); createError('INVALID_PARAMETER', TypeError, 'A parameter was not a valid value or type'); createError('INVALID_PLATFORM_ACCOUNT', Error, 'Authorization failed'); createError('INVALID_RANGE', RangeError, 'The value is not within the acceptable min/max range'); @@ -30,7 +41,7 @@ createError('TOKEN_EXPIRED', Error, 'The access token is expir * @param {Error|RangeError|TypeError} type - An instantiable error object. * @param {String} desc - A generic error description. */ -function createError(code, type, desc) { +function createError(code: string, type: ErrorConstructor, desc: string) { errors[code] = function (msg, meta) { const err = new type(msg); diff --git a/packages/amplify-sdk/src/index.js b/packages/amplify-sdk/src/index.js deleted file mode 100644 index c9308b21..00000000 --- a/packages/amplify-sdk/src/index.js +++ /dev/null @@ -1,44 +0,0 @@ -/* istanbul ignore if */ -if (!Error.prepareStackTrace) { - require('source-map-support/register'); -} - -import AmplifySDK from './amplify-sdk'; -import Auth from './auth'; -import Telemetry from './telemetry'; - -import Authenticator from './authenticators/authenticator'; -import ClientSecret from './authenticators/client-secret'; -import OwnerPassword from './authenticators/owner-password'; -import PKCE from './authenticators/pkce'; -import SignedJWT from './authenticators/signed-jwt'; - -import FileStore from './stores/file-store'; -import MemoryStore from './stores/memory-store'; -import SecureStore from './stores/secure-store'; -import TokenStore from './stores/token-store'; - -import * as environments from './environments'; -import getEndpoints from './endpoints'; - -export default AmplifySDK; - -export { - AmplifySDK, - Auth, - Telemetry, - - Authenticator, - ClientSecret, - OwnerPassword, - PKCE, - SignedJWT, - - FileStore, - MemoryStore, - SecureStore, - TokenStore, - - environments, - getEndpoints -}; diff --git a/packages/amplify-sdk/src/index.ts b/packages/amplify-sdk/src/index.ts new file mode 100644 index 00000000..673a2550 --- /dev/null +++ b/packages/amplify-sdk/src/index.ts @@ -0,0 +1,127 @@ +import AmplifySDK from './amplify-sdk.js'; +import Auth from './auth.js'; + +import Authenticator from './authenticators/authenticator.js'; +import ClientSecret from './authenticators/client-secret.js'; +import OwnerPassword from './authenticators/owner-password.js'; +import PKCE from './authenticators/pkce.js'; +import SignedJWT from './authenticators/signed-jwt.js'; + +import FileStore from './stores/file-store.js'; +import MemoryStore from './stores/memory-store.js'; +import SecureStore from './stores/secure-store.js'; +import TokenStore from './stores/token-store.js'; + +import * as environments from './environments.js'; +import getEndpoints from './endpoints.js'; + +import Telemetry, { + CrashPayload, + EventPayload, + TelemetryOptions +} from './telemetry.js'; + +export default AmplifySDK; + +export { + AmplifySDK, + Auth, + Telemetry, + + Authenticator, + ClientSecret, + OwnerPassword, + PKCE, + SignedJWT, + + FileStore, + MemoryStore, + SecureStore, + TokenStore, + + environments, + getEndpoints +}; + +import { + Account, + AccountAuthInfo, + ActivityChange, + ActivityEvent, + ActivityParams, + ActivityResult, + AmplifySDKOptions, + AuthenticatorOptions, + Client, + ClientRef, + ClientTeam, + ClientUpdateParams, + DefaultTeams, + Entitlement, + Entitlements, + Environment, + ManualLoginResult, + Org, + OrgLike, + OrgPartner, + OrgRef, + OrgUser, + Role, + Subscription, + Team, + TeamInfo, + TeamInfoChanges, + TeamUser, + User, + UserChanges, + UserInfo, + UsageBundleMetric, + UsageParams, + UsageParamsRange, + UsageParamsMonth, + UsageProductMetric, + UsageResult +} from './types.js'; + +export type { + Account, + AccountAuthInfo, + ActivityChange, + ActivityEvent, + ActivityParams, + ActivityResult, + AmplifySDKOptions, + AuthenticatorOptions, + Client, + ClientRef, + ClientTeam, + ClientUpdateParams, + CrashPayload, + DefaultTeams, + Entitlement, + Entitlements, + Environment, + EventPayload, + ManualLoginResult, + Org, + OrgLike, + OrgPartner, + OrgRef, + OrgUser, + Role, + Subscription, + Team, + TeamInfo, + TeamInfoChanges, + TeamUser, + TelemetryOptions, + User, + UserChanges, + UserInfo, + UsageBundleMetric, + UsageParams, + UsageParamsRange, + UsageParamsMonth, + UsageProductMetric, + UsageResult +}; diff --git a/packages/amplify-sdk/src/sdk/activity.ts b/packages/amplify-sdk/src/sdk/activity.ts new file mode 100644 index 00000000..2c476f8d --- /dev/null +++ b/packages/amplify-sdk/src/sdk/activity.ts @@ -0,0 +1,58 @@ +import Base from './base.js'; +import { Account, ActivityParams, ActivityResult, OrgRef } from '../types.js'; +import { PlatformActivityEvent } from './platform-types.js'; +import { resolveDateRange, resolveMonthRange } from '../util.js'; + +export default class AmplifySDKActivity extends Base { + /** + * Retrieves activity for an organization or user. + * @param {Object} account - The account object. + * @param {Object} [params] - Various parameters. + * @param {String} [params.from] - The start date in ISO format. + * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and `from`. + * If `true`, uses current month. + * @param {Object|String|Number} [params.org] - The organization object, name, guid, or id. + * @param {String} [params.to] - The end date in ISO format. + * @param {String} [params.userGuid] - The user guid. + * @returns {Promise} + */ + async find(account: Account, params: ActivityParams = {}): Promise { + this.assertPlatformAccount(account); + + if (params.month !== undefined) { + Object.assign(params, resolveMonthRange(params.month)); + } + + const { from, to } = resolveDateRange(params.from, params.to); + let url = '/api/v1/activity?data=true'; + + let org: OrgRef | undefined; + if (params.org) { + org = this.sdk.org.resolve(account, params.org, true); + url += `&org_id=${org.org_id}`; + } + + if (params.userGuid) { + url += `&user_guid=${params.userGuid}`; + } + + if (from) { + url += `&from=${from.toISOString()}`; + } + + if (to) { + url += `&to=${to.toISOString()}`; + } + + const events: PlatformActivityEvent[] = await this.sdk.request(url, account, { + errorMsg: 'Failed to get user activity' + }); + + return { + events, + from, + org, + to + }; + } +} diff --git a/packages/amplify-sdk/src/sdk/auth.ts b/packages/amplify-sdk/src/sdk/auth.ts new file mode 100644 index 00000000..ec688bff --- /dev/null +++ b/packages/amplify-sdk/src/sdk/auth.ts @@ -0,0 +1,474 @@ +import AmplifySDK from '../amplify-sdk.js'; +import Auth, { AuthOptions, DefaultOptions, ServerInfo, ServerInfoOptions } from '../auth.js'; +import Base from './base.js'; +import E from '../errors.js'; +import getEndpoints from '../endpoints.js'; +import http from 'http'; +import open from 'open'; +import Server from '../server.js'; +import snooplogg from 'snooplogg'; +import * as environments from '../environments.js'; +import { Account, DefaultTeams, ManualLoginResult, OrgLike, OrgRef } from '../types.js'; +import { createURL } from '../util.js'; +import { PlatformSession } from './platform-types.js'; + +const { error, log, warn } = snooplogg('amplify-sdk:auth'); +const { highlight, note } = snooplogg.styles; + +export class AlreadyAuthenticatedError extends Error { + account?: Account | null; + code?: string; +} + +export default class AmplifySDKAuth extends Base { + baseUrl?: string; + platformUrl?: string; + realm?: string; + _client!: Auth; + + /** + * Returns an Amplify Auth SDK client or creates one if it doesn't exist. + * @type {Auth} + * @access public + */ + get client(): Auth { + try { + if (!this._client) { + this._client = new Auth(this.sdk.opts as AuthOptions); + } + return this._client; + } catch (err: any) { + if (err.code === 'ERR_SECURE_STORE_UNAVAILABLE') { + const isWin = process.platform === 'win32'; + err.message = `Secure token store is not available.\nPlease reinstall the Axway CLI by running:\n ${isWin ? '' : 'sudo '}npm install --global ${isWin ? '' : '--unsafe-perm '}axway`; + } + throw err; + } + } + + constructor(sdk: AmplifySDK, params: { + baseUrl?: string, + platformUrl?: string, + realm?: string + } = {}) { + super(sdk); + this.baseUrl = params.baseUrl; + this.platformUrl = params.platformUrl; + this.realm = params.realm; + } + + /** + * Finds an authenticated account or `null` if not found. If the account is found and + * the access token is expired yet the refresh token is still valid, it will + * automatically get a valid access token. + * @param {String} accountName - The name of the account including the client id prefix. + * @param {Object} [defaultTeams] - A map of account hashes to their selected team guid. + * @returns {Promise} Resolves the account info object. + */ + async find(accountName?: string, defaultTeams?: DefaultTeams): Promise { + const account = await this.client.find(accountName); + return account ? await this.loadSession(account, defaultTeams) : undefined; + } + + /** + * Retrieves platform session information such as the organizations, then mutates the + * account object and returns it. + * @param {Object} account - The account object. + * @param {Object} [defaultTeams] - A map of account hashes to their selected team guid. + * @returns {Promise} Resolves the original account info object. + */ + async findSession(account: Account, defaultTeams?: DefaultTeams): Promise { + if (defaultTeams && typeof defaultTeams !== 'object') { + throw E.INVALID_ARGUMENT('Expected default teams to be an object'); + } + + const result: PlatformSession = await this.sdk.request('/api/v1/auth/findSession', account, { + errorMsg: 'Failed to find session' + }) as PlatformSession; + + account.isPlatform = !!result; + + if (result) { + const { org, orgs, role, roles, user } = result; + // note: account.orgs must be defined first + account.orgs = orgs.map(o => ({ + default: o.guid === org.guid, + guid: o.guid, + name: o.name, + org_id: o.org_id, + role: o.role + })); + account.org = await this.sdk.org.init(account, org); + account.role = role; + account.roles = roles; + + account.user = { + ...account.user, + dateJoined: user.date_activated, + email: user.email, + firstname: user.firstname, + guid: user.guid, + lastname: user.lastname + }; + } else if (account.org?.guid) { + // we have a service account + account.org = await this.sdk.org.find(account); + account.orgs = [ + { + guid: account.org.guid, + name: account.org.name, + org_id: account.org.org_id + } + ]; + } + + account.team = undefined; + + if (account.user.guid) { + const { teams } = await this.sdk.team.list(account, account.org, account.user.guid); + account.org.teams = teams; + + const selectedTeamGuid = defaultTeams?.[account.hash]; + if (teams.length) { + account.team = teams.find(t => (selectedTeamGuid && t.guid === selectedTeamGuid) || (!selectedTeamGuid && t.default)) || teams[0]; + } + } + + return account; + } + + /** + * Returns a list of all authenticated accounts. + * @param {Object} [opts] - Various options. + * @param {Object} [opts.defaultTeams] - A map of account hashes to their selected team guid. + * @param {Array.} [opts.skip] - A list of accounts to skip validation for. + * @param {Boolean} [opts.validate] - When `true`, checks to see if each account has an + * active access token and session. + * @returns {Promise} + */ + async list(opts: { + defaultTeams?: DefaultTeams, + skip?: string[], + validate?: boolean + } = {}): Promise { + if (!opts || typeof opts !== 'object') { + throw E.INVALID_ARGUMENT('Expected options to be an object'); + } + + const allAccounts: Account[] = await this.client.list(); + const accounts: Account[] = await allAccounts.reduce((promise, account: Account) => { + return promise.then(async list => { + let acct: Account | undefined | null = account; + if (opts.validate && (!opts.skip || (acct.name && !opts.skip.includes(acct.name)))) { + try { + acct = await this.find(account.name, opts.defaultTeams); + } catch (err: any) { + warn(`Failed to load session for account "${account.name}": ${err.toString()}`); + } + } + if (acct && acct.auth) { + delete account.auth.clientSecret; + delete account.auth.password; + delete account.auth.secret; + delete account.auth.username; + list.push(acct); + } + return list; + }); + }, Promise.resolve([] as Account[])); + + return accounts.sort((a: Account, b: Account) => a.name.localeCompare(b.name)); + } + + /** + * Populates the specified account info object with a dashboard session id and org + * information. + * @param {Object} account - The account object. + * @param {Object} [defaultTeams] - A map of account hashes to their selected team guid. + * @returns {Promise} Resolves the original account info object. + */ + async loadSession(account: Account, defaultTeams?: DefaultTeams): Promise { + try { + // grab the org guid before findSession clobbers it + const { guid } = account.org; + + account = await this.findSession(account, defaultTeams); + + // validate the service account + if (account.isPlatformTooling) { + const filteredOrgs = account.orgs.filter(o => o.guid === guid); + if (!filteredOrgs.length) { + error(`Service account belongs to org "${guid}", but platform account belongs to:\n${account.orgs.map(o => ` "${o.guid}"`).join('\n')}`); + throw new Error('The service account\'s organization does not match the specified platform account\'s organizations'); + } + account.orgs = filteredOrgs; + } + } catch (err: any) { + if (err.code === 'ERR_SESSION_INVALIDATED') { + warn(`Detected invalidated session, purging account ${highlight(account.name)}`); + await this.client.logout({ + accounts: [ account.name ], + baseUrl: this.baseUrl + }); + return; + } + throw err; + } + + await this.client.updateAccount(account); + + if (account.isPlatform) { + log(`Current org: ${highlight(account.org.name)} ${note(`(${account.org.guid})`)}`); + log('Available orgs:'); + for (const org of account.orgs) { + log(` ${highlight(org.name)} ${note(`(${org.guid})`)}`); + } + } + + delete account.auth.clientSecret; + delete account.auth.password; + delete account.auth.secret; + delete account.auth.username; + + return account; + } + + /** + * Authenticates a user, retrieves the access tokens, populates the session id and + * org info, and returns it. + * @param {Object} opts - Various authentication options to override the defaults set + * via the `Auth` constructor. + * @param {Boolean} [opts.force] - When `true`, skips the already logged in check. + * @param {String} [opts.password] - The platform tooling password used to + * authenticate. Requires a `username` and `clientSecret` or `secretFile`. + * @param {String} [opts.secretFile] - The path to the PEM formatted private key used + * to sign the JWT. + * @param {String} [opts.username] - The platform tooling username used to + * authenticate. Requires a `password` and `clientSecret` or `secretFile`. + * @returns {Promise} Resolves the account info object. + */ + async login(opts: DefaultOptions & { + force?: boolean, + password?: string, + secretFile?: string, + username?: string + } = {}): Promise { + let account: Account | ManualLoginResult | null | undefined; + + // validate the username/password + const { password, username } = opts; + if (username || password) { + const clientSecret = opts.clientSecret || this.sdk.opts.clientSecret; + const secretFile = opts.secretFile || this.sdk.opts.secretFile; + if (!clientSecret && !secretFile) { + throw new Error('Username/password can only be specified when using client secret or secret file'); + } + if (!username || typeof username !== 'string') { + throw new TypeError('Expected username to be an email address'); + } + if (!password || typeof password !== 'string') { + throw new TypeError('Expected password to be a non-empty string'); + } + delete opts.username; + delete opts.password; + } + + // check if already logged in + if (!opts?.force) { + account = await this.client.find(opts); + if (account && !account.auth.expired) { + warn(`Account ${highlight(account.name)} is already authenticated`); + const err = new AlreadyAuthenticatedError('Account already authenticated'); + err.account = account; + try { + err.account = await this.loadSession(account); + } catch (e: any) { + warn(e); + } + err.code = 'EAUTHENTICATED'; + throw err; + } + } + + // do the login + account = await this.client.login(opts); + + // if we're in manual mode (e.g. --no-launch-browser), then return now + if (opts.manual) { + // account is actually an object containing `cancel`, `promise`, and `url` + return account; + } + + const acct: Account = account as Account; + + try { + // upgrade the service account with the platform tooling account + if (username && password) { + // request() will set the sid and update the account in the token store + await this.sdk.request('/api/v1/auth/login', acct, { + errorMsg: 'Failed to authenticate', + isToolingAuth: true, + json: { + from: 'cli', + username, + password + } + }); + + acct.isPlatformTooling = true; + } + + return await this.loadSession(acct); + } catch (err: any) { + // something happened, revoke the access tokens we just got and rethrow + await this.client.logout({ + accounts: [ acct.name ], + baseUrl: this.baseUrl + }); + throw err; + } + } + + /** + * Discards an access token and notifies AxwayID to revoke the access token. + * @param {Object} opts - Various authentication options to override the defaults set + * via the `Auth` constructor. + * @param {Array.} opts.accounts - A list of accounts names. + * @param {Boolean} opts.all - When `true`, revokes all accounts. + * @param {String} [opts.baseUrl] - The base URL used to filter accounts. + * @param {Function} [opts.onOpenBrowser] - A callback when the web browser is about to + * be launched. + * @returns {Promise} Resolves a list of revoked credentials. + */ + async logout({ accounts, all, baseUrl, onOpenBrowser }: { + accounts?: string[], + all?: boolean, + baseUrl?: string, + onOpenBrowser?: (p: { url: string }) => void + }) { + if (baseUrl === undefined) { + baseUrl = this.baseUrl; + } + + let accountList: Account[]; + + if (all) { + accountList = (await this.client.list()); + } else if (!Array.isArray(accounts)) { + throw E.INVALID_ARGUMENT('Expected accounts to be a list of accounts'); + } else if (!accounts.length) { + return []; + } else { + accountList = (await this.client.list()) + .filter(account => accounts.includes(account.name)); + } + + for (const account of accountList) { + if (account.isPlatform && !account.isPlatformTooling) { + // note: there should only be 1 platform account in the accounts list + const { platformUrl } = environments.resolve(account.auth.env); + const { logout } = getEndpoints({ baseUrl: account.auth.baseUrl, realm: account.auth.realm }); + const redirect = `${logout}?redirect_uri=${platformUrl}/signed.out?msg=signout`; + const url = `${platformUrl}/api/v1/auth/logout?redirect=${encodeURIComponent(redirect)}`; + if (typeof onOpenBrowser === 'function') { + await onOpenBrowser({ url }); + } + try { + await open(url); + } catch (err: any) { + const m = err.message.match(/Exited with code (\d+)/i); + throw m ? new Error(`Failed to open web browser (code ${m[1]})`) : err; + } + } + } + + return await this.client.logout({ accounts: accountList.map(a => a.hash), baseUrl }); + } + + /** + * Returns AxwayID server information. + * @param {Object} [opts] - Various authentication options to override the defaults set + * via the `Auth` constructor. + * @returns {Promise} + */ + async serverInfo(opts: ServerInfoOptions | undefined = {}): Promise { + return await this.client.serverInfo(opts); + } + + /** + * Switches your current organization. + * @param {Object} [account] - The account object. Note that this object reference will + * be updated with new org info. + * @param {Object|String|Number} [org] - The organization object, name, guid, or id. + * @param {Object} [opts] - Various options. + * @param {Function} [opts.onOpenBrowser] - A callback when the web browser is about to + * be launched. + * @returns {Promise} Resolves the updated account object. + */ + async switchOrg(account?: Account, org?: OrgLike, opts: { + onOpenBrowser?: (p: { url: string }) => void + } = {}): Promise { + if (!account || account.auth.expired) { + log(`${account ? 'Account is expired' : 'No account specified'}, doing login`); + account = await this.client.login() as Account; + } else { + let orgRef: OrgRef | undefined; + + try { + orgRef = this.sdk.org.resolve(account, org, true); + log(`Switching ${highlight(account.name)} to org ${highlight(orgRef.name)} (${orgRef.guid})`); + } catch (err: any) { + if (err.code !== 'ERR_INVALID_ACCOUNT' && err.code !== 'ERR_INVALID_PLATFORM_ACCOUNT' && err.code !== 'ERR_INVALID_ARGUMENT') { + // probably org not found + throw err; + } + orgRef = undefined; + } + + const server = new Server(); + const { start, url: redirect } = await server.createCallback(async (req: http.IncomingMessage, res: http.ServerResponse) => { + log(`Telling browser to redirect to ${highlight(this.platformUrl)}`); + res.writeHead(302, { + Location: this.platformUrl + }); + res.end(); + }); + + try { + const url = createURL(`${this.platformUrl}/#/auth/org.select`, { + org_id: orgRef?.org_id, + redirect + }); + log(`Launching default web browser: ${highlight(url)}`); + if (typeof opts.onOpenBrowser === 'function') { + await opts.onOpenBrowser({ url }); + } + try { + await open(url); + } catch (err: any) { + const m = err.message.match(/Exited with code (\d+)/i); + throw m ? new Error(`Failed to open web browser (code ${m[1]})`) : err; + } + + log(`Waiting for browser to be redirected to: ${highlight(redirect)}`); + await start(); + } finally { + await server.stop(); + } + } + + try { + log('Refreshing the account session...'); + if (account.sid) { + log(`Deleting sid ${account.sid}`); + delete account.sid; + } + return await this.loadSession(account); + } catch (e: any) { + // squelch + log(e); + } + + throw new Error('Failed to switch organization'); + } +} diff --git a/packages/amplify-sdk/src/sdk/base.ts b/packages/amplify-sdk/src/sdk/base.ts new file mode 100644 index 00000000..23c0ca95 --- /dev/null +++ b/packages/amplify-sdk/src/sdk/base.ts @@ -0,0 +1,26 @@ +import AmplifySDK from '../amplify-sdk.js'; +import E from '../errors.js'; +import { Account } from '../types.js'; + +export default class Base { + sdk: AmplifySDK; + + constructor(sdk: AmplifySDK) { + this.sdk = sdk; + } + + /** + * Checks that the specified account is a platform account. + * + * @param {Object} account - The account object. + */ + assertPlatformAccount(account: Account) { + if (!account || typeof account !== 'object') { + throw E.INVALID_ACCOUNT('Account required'); + } + + if (!account.isPlatform) { + throw E.INVALID_PLATFORM_ACCOUNT('Account must be a platform account'); + } + } +} diff --git a/packages/amplify-sdk/src/sdk/client.ts b/packages/amplify-sdk/src/sdk/client.ts new file mode 100644 index 00000000..57a7f97a --- /dev/null +++ b/packages/amplify-sdk/src/sdk/client.ts @@ -0,0 +1,447 @@ +import Base from './base.js'; +import crypto from 'crypto'; +import E from '../errors.js'; +import { + Account, + Client, + ClientRef, + ClientTeam, + ClientUpdateParams, + OrgLike, + OrgRef, + Team +} from '../types.js'; +import { PlatformClient } from './platform-types.js'; +import { promisify } from 'util'; + +interface PlatformClientPayload { + description?: string, + name?: string, + org_guid?: string, + publicKey?: string, + roles?: string[], + secret?: string, + teams?: ClientTeam[], + type?: string +} + +export default class AmplifySDKClient extends Base { + /** + * Creates a new service account. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {Object} opts - Various options. + * @param {String} [opts.desc] - The service account description. + * @param {String} opts.name - The display name. + * @param {String} [opts.publicKey] - A PEM formatted public key. + * @param {Array} [opts.roles] - A list of roles to assign to the service account. + * @param {String} [opts.secret] - A client secret key. + * @param {Array} [opts.teams] - A list of objects containing `guid` and `roles` + * properties. + * @returns {Promise} + */ + async create(account: Account, org: OrgLike, opts: { + desc?: string, + name: string, + publicKey?: string, + roles?: string[], + secret?: string, + teams?: ClientTeam[] + }): Promise<{ client: Client, org: OrgRef }> { + const orgRef: OrgRef = this.sdk.org.resolve(account, org, true); + + if (!opts || typeof opts !== 'object') { + throw E.INVALID_ARGUMENT('Expected options to be an object'); + } + + if (!opts.name || typeof opts.name !== 'string') { + throw E.INVALID_ARGUMENT('Expected name to be a non-empty string'); + } + + if (opts.desc && typeof opts.desc !== 'string') { + throw E.INVALID_ARGUMENT('Expected description to be a string'); + } + + const data: PlatformClientPayload = { + description: opts.desc || '', + name: opts.name, + org_guid: orgRef.guid + }; + + if (opts.publicKey) { + if (typeof opts.publicKey !== 'string') { + throw E.INVALID_ARGUMENT('Expected public key to be a string'); + } + if (!opts.publicKey.startsWith('-----BEGIN PUBLIC KEY-----')) { + throw new Error('Expected public key to be PEM formatted'); + } + data.type = 'certificate'; + data.publicKey = opts.publicKey; + } else if (opts.secret) { + if (typeof opts.secret !== 'string') { + throw E.INVALID_ARGUMENT('Expected secret to be a string'); + } + data.type = 'secret'; + data.secret = opts.secret; + } else { + throw new Error('Expected public key or secret'); + } + + if (opts.roles) { + data.roles = await this.sdk.role.resolve(account, opts.roles, { client: true, org: orgRef }); + } + + if (opts.teams) { + data.teams = await this.resolveTeams(account, org, opts.teams); + } + + const client: PlatformClient = await this.sdk.request('/api/v1/client', account, { + errorMsg: 'Failed to create service account', + json: data + }); + + const { teams } = await this.sdk.team.list(account, orgRef, client.guid); + const clientTeams = []; + + for (const team of teams) { + const user = team.users.find(u => u.guid === client.guid); + if (user) { + clientTeams.push({ + guid: team.guid, + name: team.name, + roles: user.roles + }); + } + } + + return { + client: { + client_id: client.client_id, + created: client.created, + description: client.description, + guid: client.guid, + method: this.resolveType(client.type), + name: client.name, + org_guid: client.org_guid, + teams: clientTeams, + type: client.type + } as Client, + org: orgRef + }; + } + + /** + * Finds a service account by client id. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} clientId - The service account's client id. + * @returns {Promise} + */ + async find(account: Account, org: OrgLike, clientId: string): Promise<{ client: Client, org: OrgRef }> { + this.assertPlatformAccount(account); + + const { clients, org: orgRef } = await this.list(account, org); + + // first try to find the service account by guid, then client id, then name + let clientRef: ClientRef | undefined = clients.find(c => c.guid === clientId); + if (!clientRef) { + clientRef = clients.find(c => c.client_id === clientId); + } + if (!clientRef) { + clientRef = clients.find(c => c.name === clientId); + } + + // if still not found, error + if (!clientRef) { + throw new Error(`Service account "${clientId}" not found`); + } + + // get service account description + const platformClient: PlatformClient = await this.sdk.request(`/api/v1/client/${clientRef.client_id}`, account, { + errorMsg: 'Failed to get service account' + }); + + // get the teams + const teams: ClientTeam[] = []; + const { teams: allTeams } = await this.sdk.team.list(account, platformClient.org_guid); + for (const team of allTeams) { + const user = team.users.find(u => u.guid === platformClient.guid); + if (user) { + teams.push({ + desc: team.desc, + guid: team.guid, + name: team.name, + roles: user.roles + }); + } + } + + return { + client: { + client_id: platformClient.client_id, + created: platformClient.created, + description: platformClient.description, + guid: platformClient.guid, + method: this.resolveType(platformClient.type), + name: platformClient.name, + org_guid: platformClient.org_guid, + roles: platformClient.roles, + teams, + type: platformClient.type + }, + org: orgRef + }; + } + + /** + * Generates a new public/private key pair. + * @returns {Promise} Resolves an object with `publicKey` and `privateKey` properties. + */ + async generateKeyPair(): Promise<{ publicKey: string, privateKey: string }> { + return await promisify(crypto.generateKeyPair)('rsa', { + modulusLength: 2048, + publicKeyEncoding: { type: 'spki', format: 'pem' }, + privateKeyEncoding: { type: 'pkcs8', format: 'pem' } + }); + } + + /** + * Retrieves a list of all service accounts for the given org. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @returns {Promise} Resolves a list of service accounts and their org. + */ + async list(account: Account, org: OrgLike): Promise<{ clients: ClientRef[], org: OrgRef }> { + const orgRef: OrgRef = this.sdk.org.resolve(account, org, true); + const clients: PlatformClient[] = await this.sdk.request(`/api/v1/client?org_id=${orgRef.org_id}`, account, { + errorMsg: 'Failed to get service accounts' + }); + + return { + org: orgRef, + clients: clients + .map(c => ({ + client_id: c.client_id, + created: c.created, + guid: c.guid, + method: this.resolveType(c.type), + name: c.name, + org_guid: c.org_guid, + roles: c.roles, + team_count: c.teams, + type: c.type + } as ClientRef)) + .sort((a, b) => a.name.localeCompare(b.name)) + }; + } + + /** + * Removes a service account. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {Object|String} client - The service account object or client id. + * @returns {Promise} Resolves the service account that was removed. + */ + async remove(account: Account, org: OrgLike, client: string): Promise<{ client: Client, org: OrgRef }> { + const orgRef: OrgRef = this.sdk.org.resolve(account, org, true); + + const c: Client = await this.resolve(account, orgRef, client); + await this.sdk.request(`/api/v1/client/${c.client_id}`, account, { + errorMsg: 'Failed to remove service account', + method: 'delete' + }); + + return { client: c, org: orgRef }; + } + + /** + * Resolves a client by name, id, org guid using the specified account. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, guid, or id. + * @param {Object|String} client - The service account object or client id. + * @returns {Promise} + */ + async resolve(account: Account, org: OrgLike, client: Client | string): Promise { + if (client && typeof client === 'object' && client.client_id) { + return client; + } + + if (client && typeof client === 'string') { + return (await this.find(account, org, client)).client; + } + + throw E.INVALID_ARGUMENT('Expected client to be an object or client id'); + } + + /** + * Validates a list of teams for the given org. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {Array} [teams] - A list of objects containing `guid` and `roles` + * properties. + * @returns {Array} An aray of team guids. + */ + async resolveTeams(account: Account, org: OrgLike, teams: ClientTeam[]): Promise { + if (!Array.isArray(teams)) { + throw E.INVALID_ARGUMENT('Expected teams to be an array'); + } + + const resolvedTeams: ClientTeam[] = []; + + if (!teams.length) { + return resolvedTeams; + } + + const { org: orgRef, teams: availableTeams } = await this.sdk.team.list(account, org); + const teamRoles = await this.sdk.role.list(account, { org: orgRef, team: true }); + const guids: { [guid: string]: number } = {}; + + for (const team of teams) { + if (!team || typeof team !== 'object' || !team.guid || typeof team.guid !== 'string' || !team.roles || !Array.isArray(team.roles) || !team.roles.length) { + throw E.INVALID_ARGUMENT('Expected team to be an object containing a guid and array of roles'); + } + + // find the team by name or guid + const lt = team.guid.toLowerCase().trim(); + const found: Team | undefined = availableTeams.find(t => t.guid === lt || t.name.toLowerCase() === lt); + if (!found) { + throw new Error(`Invalid team "${team.guid}"`); + } + + // validate roles + for (const role of team.roles) { + if (!teamRoles.find(r => r.id === role)) { + throw new Error(`Invalid team role "${role}"`); + } + } + + // dedupe + if (guids[found.guid]) { + continue; + } + guids[found.guid] = 1; + + resolvedTeams.push({ + guid: found.guid, + name: found.name, + roles: team.roles + }); + } + + return resolvedTeams; + } + + /** + * Returns the service account auth type label. + * @param {String} type - The auth type. + * @returns {String} + */ + resolveType(type: string): string { + return type === 'secret' ? 'Client Secret' : type === 'certificate' ? 'Client Certificate' : 'Other'; + } + + /** + * Updates an existing service account's information. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {Object} opts - Various options. + * @param {Object|String} opts.client - The service account object or client id. + * @param {String} [opts.desc] - The service account description. + * @param {String} [opts.name] - The display name. + * @param {String} [opts.publicKey] - A PEM formatted public key. + * @param {Array} [opts.roles] - A list of roles to assign to the service account. + * @param {String} [opts.secret] - A client secret key. + * @param {Array} [opts.teams] - A list of objects containing `guid` and `roles` + * properties. + * @returns {Promise} + */ + async update(account: Account, org: OrgLike, opts: ClientUpdateParams): Promise<{ client: Client, org: OrgRef }> { + const orgRef: OrgRef = this.sdk.org.resolve(account, org, true); + + if (!opts || typeof opts !== 'object') { + throw E.INVALID_ARGUMENT('Expected options to be an object'); + } + + const client: Client = await this.resolve(account, orgRef, opts.client); + const data: PlatformClientPayload = {}; + + if (opts.name) { + if (typeof opts.name !== 'string') { + throw E.INVALID_ARGUMENT('Expected name to be a non-empty string'); + } + data.name = opts.name; + } + + if (opts.desc) { + if (typeof opts.desc !== 'string') { + throw E.INVALID_ARGUMENT('Expected description to be a string'); + } + data.description = opts.desc; + } + + if (opts.publicKey) { + if (typeof opts.publicKey !== 'string') { + throw E.INVALID_ARGUMENT('Expected public key to be a string'); + } + if (!opts.publicKey.startsWith('-----BEGIN PUBLIC KEY-----')) { + throw new Error('Expected public key to be PEM formatted'); + } + if (client.type !== 'certificate') { + throw new Error(`Service account "${client.name}" uses auth method "${this.resolveType(client.type)}" and cannot be changed to "${this.resolveType('certificate')}"`); + } + data.publicKey = opts.publicKey; + } else if (opts.secret) { + if (typeof opts.secret !== 'string') { + throw E.INVALID_ARGUMENT('Expected secret to be a string'); + } + if (client.type !== 'secret') { + throw new Error(`Service account "${client.name}" uses auth method "${this.resolveType(client.type)}" and cannot be changed to "${this.resolveType('secret')}"`); + } + data.secret = opts.secret; + } + + if (opts.roles !== undefined) { + data.roles = !opts.roles ? [] : await this.sdk.role.resolve(account, opts.roles, { client: true, org: orgRef }); + } + + if (opts.teams !== undefined) { + data.teams = opts.teams && await this.resolveTeams(account, orgRef, opts.teams) || []; + } + + const platformClient: PlatformClient = await this.sdk.request(`/api/v1/client/${client.guid}`, account, { + errorMsg: 'Failed to update service account', + json: data, + method: 'put' + }); + + // get the teams + const teams: ClientTeam[] = []; + const { teams: allTeams } = await this.sdk.team.list(account, platformClient.org_guid); + for (const team of allTeams) { + const user = team.users.find(u => u.client_id && u.guid === platformClient.guid); + if (user) { + teams.push({ + guid: team.guid, + name: team.name, + roles: user.roles + }); + } + } + + return { + client: { + client_id: platformClient.client_id, + created: platformClient.created, + description: platformClient.description, + guid: platformClient.guid, + method: this.resolveType(platformClient.type), + name: platformClient.name, + org_guid: platformClient.org_guid, + roles: platformClient.roles, + teams, + type: platformClient.type + }, + org: orgRef + }; + } +} diff --git a/packages/amplify-sdk/src/sdk/entitlement.ts b/packages/amplify-sdk/src/sdk/entitlement.ts new file mode 100644 index 00000000..03f0eb4f --- /dev/null +++ b/packages/amplify-sdk/src/sdk/entitlement.ts @@ -0,0 +1,18 @@ +import Base from './base.js'; +import { Account, Entitlement } from '../types.js'; +import { PlatformEntitlement } from './platform-types.js'; + +export default class AmplifySDKEntitlement extends Base { + /** + * Retrieves entitlement information for a specific entitlement metric. + * @param {Object} account - The account object. + * @param {String} metric - The entitlement metric name. + * @returns {Promise} + */ + async find(account: Account, metric: string): Promise { + const entitlement: PlatformEntitlement = await this.sdk.request(`/api/v1/entitlement/${metric}`, account, { + errorMsg: 'Failed to get entitlement info' + }); + return entitlement; + } +} diff --git a/packages/amplify-sdk/src/sdk/org.ts b/packages/amplify-sdk/src/sdk/org.ts new file mode 100644 index 00000000..91f9c0db --- /dev/null +++ b/packages/amplify-sdk/src/sdk/org.ts @@ -0,0 +1,430 @@ +import Base from './base.js'; +import E from '../errors.js'; +import snooplogg from 'snooplogg'; +import { + Account, + ActivityParams, + ActivityResult, + Entitlements, + Environment, + Org, + OrgLike, + OrgRef, + OrgUser, + Subscription, + UsageParams, + UsageResult +} from '../types.js'; +import { + PlatformOrg, + PlatformOrgEnvironment, + PlatformOrgPartners, + PlatformOrgUsage, + PlatformOrgUser, + PlatformPartner, + PlatformSubscription +} from './platform-types.js'; +import { resolveDateRange, resolveMonthRange } from '../util.js'; + +const { log } = snooplogg('amplify-sdk:org'); + +export default class AmplifySDKOrg extends Base { + /** + * Retieves organization activity. + * @param {Object} account - The account object. + * @param {Object|String|Number} [org] - The organization object, name, guid, or id. + * @param {Object} [params] - Various parameters. + * @param {String} [params.from] - The start date in ISO format. + * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and + * `from`. If `true`, uses current month. + * @param {String} [params.to] - The end date in ISO format. + * @returns {Promise} + */ + async activity(account: Account, org?: OrgLike, params?: { + from?: string, + month?: string | boolean, + to?: string + }): Promise { + return await this.sdk.activity.find(account, { + ...params, + org + } as ActivityParams); + } + + /** + * Retrieves organization details for an account. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @returns {Promise} + */ + async find(account: Account, org?: OrgLike): Promise { + const { org_id } = this.resolve(account, org); + const platformOrg = await this.sdk.request(`/api/v1/org/${org_id}`, account, { + errorMsg: 'Failed to get organization' + }); + return await this.init(account, platformOrg); + } + + /** + * Retrieves the list of environments associated to the user's org. + * @param {Object} account - The account object. + * @returns {Promise} + */ + async environments(account: Account): Promise { + this.assertPlatformAccount(account); + + const envs: PlatformOrgEnvironment[] = await this.sdk.request('/api/v1/org/env', account, { + errorMsg: 'Failed to get organization environments' + }); + + return envs.map(env => ({ + guid: env.guid, + isProduction: env.isProduction, + name: env.name + })); + } + + /** + * Formats a platform org into an org object. + * @param {Object} account - The account object. + * @param {PlatformOrg} platformOrg - The platform org object. + * @returns {Promise} + */ + async init(account: Account, platformOrg: PlatformOrg): Promise { + const subscriptions: Subscription[] = (platformOrg.subscriptions.map((s: PlatformSubscription) => { + return { + category: s.product, // TODO: Replace with annotated name + edition: s.plan, // TODO: Replace with annotated name + endDate: s.end_date, + expired: !!s.expired, + governance: s.governance || 'SaaS', + startDate: s.start_date, + tier: s.tier + } as Subscription; + }) || []) as Subscription[]; + + const { teams } = await this.sdk.team.list(account, platformOrg.org_id); + + const result: Org = { + active: platformOrg.active, + created: platformOrg.created, + entitlements: (platformOrg.entitlements || {}) as Entitlements, + guid: platformOrg.guid, + insightUserCount: platformOrg.entitlements?.limit_read_only_users || 0, + name: platformOrg.name, + org_id: platformOrg.org_id, + partners: {}, + region: platformOrg.region, + seats: platformOrg.entitlements?.limit_users === 10000 ? null : platformOrg.entitlements?.limit_users, + subscriptions, + teams, + userCount: platformOrg.users.length, + userRoles: platformOrg.users.find(u => u.guid === account.user.guid)?.roles || [] + }; + + if (platformOrg.entitlements?.partners) { + for (const partner of platformOrg.entitlements.partners) { + const platformPartner: PlatformPartner | undefined = platformOrg[partner as keyof PlatformOrgPartners]; + result.partners[partner] = { + provisioned: !!platformPartner?.provisioned + }; + } + } + + return result; + } + + /** + * Retrieves the list of orgs from the specified account. + * @param {Object} account - The account object. + * @param {String} [defaultOrg] - The name, id, or guid of the default organization. + * @returns {Promise} + */ + async list(account: Account, defaultOrg?: OrgLike): Promise { + const { guid } = this.resolve(account, defaultOrg, true); + + return account.orgs + .map(orgRef => ({ + ...orgRef, + default: orgRef.guid === guid + })) + .sort((a: OrgRef, b: OrgRef) => a.name.localeCompare(b.name)); + } + + /** + * Resolves an org by name, id, org guid using the specified account. + * + * @param {Object} account - The account object. + * @param {Object|String|Number} [org] - The organization object, name, guid, or id. + * @param {Boolean} [checkPlatformAccount=false] - When `true`, asserts the account is a platform account. + * @returns {Object} Resolves the org info from the account object. + * @access public + */ + resolve(account: Account, org?: OrgLike, checkPlatformAccount = false): OrgRef { + if (checkPlatformAccount) { + this.assertPlatformAccount(account); + } + + if (org && typeof org === 'object' && org.guid) { + return { + default: !!org.default, + guid: org.guid, + name: org.name, + org_id: org.org_id + }; + } + + if (org === undefined) { + // get the default org guid + org = account.org.guid; + } + + if (typeof org !== 'string' && typeof org !== 'number') { + throw E.INVALID_ARGUMENT('Expected organization identifier'); + } + + const subject = String(org).toLowerCase(); + const found: OrgRef | undefined = account.orgs.find(o => { + return o.guid.toLowerCase() === subject + || (o.name && o.name.toLowerCase() === subject) // service accounts don't have access to the org name + || String(o.org_id) === subject; + }); + + if (!found) { + throw new Error(`Unable to find the organization "${org}"`); + } + + log(`Resolved org "${org}"${found.name ? ` as ${found.name}` : ''} (${found.org_id}) ${found.guid}`); + + return found; + } + + /** + * Renames an org. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} name - The new organization name. + * @returns {Promise} + */ + async rename(account: Account, org: OrgLike, name: string): Promise<{ + name: string, + oldName: string, + org: Org + }> { + const { org_id, name: oldName } = this.resolve(account, org, true); + + if (typeof name !== 'string' || !(name = name.trim())) { + throw E.INVALID_ARGUMENT('Organization name must be a non-empty string'); + } + + const platformOrg: PlatformOrg = await this.sdk.request(`/api/v1/org/${org_id}`, account, { + errorMsg: 'Failed to rename organization', + json: { name }, + method: 'put' + }); + + return { + name, + oldName, + org: await this.init(account, platformOrg) + }; + } + + /** + * Retrieves organization usage information. + * @param {Object} account - The account object. + * @param {Object|String|Number} [org] - The organization object, name, id, or guid. + * @param {Object} [params] - Various parameters. + * @param {String} [params.from] - The start date in ISO format. + * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and + * `from`. If `true`, uses current month. + * @param {String} [params.to] - The end date in ISO format. + * @returns {Promise} + */ + async usage(account: Account, org?: OrgLike, params?: UsageParams): Promise { + const { org_id } = this.resolve(account, org, true); + + if (params === undefined) { + params = {} as UsageParams; + } + + if (params.month !== undefined) { + Object.assign(params, resolveMonthRange(params.month)); + } + + const { from, to } = resolveDateRange(params.from, params.to); + + let url = `/api/v1/org/${org_id}/usage?by_product=true`; + if (from) { + url += `&from=${from.toISOString()}`; + } + if (to) { + url += `&to=${to.toISOString()}`; + } + + const results: PlatformOrgUsage = await this.sdk.request(url, account, { + errorMsg: 'Failed to get organization usage' + }); + + if (results.bundle?.metrics) { + for (const [ metric, info ] of Object.entries(results.bundle.metrics)) { + if (!info.name) { + info.name = (await this.sdk.entitlement.find(account, metric)).title; + } + } + } + + return { + ...results, + from, + to + }; + } + + /** + * Adds a user to an org. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} email - The user's email. + * @param {Array.} roles - One or more roles to assign. Must include a "default" role. + * @returns {Promise} + */ + async userAdd(account: Account, org: OrgLike, email: string, roles: string[]): Promise<{ + org: OrgRef, + user?: OrgUser + }> { + const orgRef = this.resolve(account, org, true); + const { guid } = await this.sdk.request(`/api/v1/org/${orgRef.org_id}/user`, account, { + errorMsg: 'Failed to add user to organization', + json: { + email, + roles: await this.sdk.role.resolve(account, roles, { + org: orgRef, + requireDefaultRole: true + }) + } + }); + log(`User "${guid}" added to org ${orgRef.name} (${orgRef.guid})`); + return { + org: orgRef, + user: await this.userFind(account, orgRef, guid) + }; + } + + /** + * Finds a user and returns their information. + * @param {Object} account - The account object. + * @param {Object|String|Number} [org] - The organization object, name, id, or guid. + * @param {String} user - The user email or guid. + * @returns {Promise} + */ + async userFind(account: Account, org: OrgLike, user: string): Promise { + const { users } = await this.userList(account, org); + user = user.toLowerCase(); + return users.find(u => String(u.email).toLowerCase() === user || String(u.guid).toLowerCase() === user); + } + + /** + * Lists all users in an org. + * @param {Object} account - The account object. + * @param {Object|String|Number} [org] - The organization object, name, id, or guid. + * @returns {Promise} + */ + async userList(account: Account, org?: OrgLike): Promise<{ org: OrgRef, users: OrgUser[] }> { + const orgRef = this.resolve(account, org, false); // this should be true + const users: PlatformOrgUser[] = await this.sdk.request(`/api/v1/org/${orgRef.org_id}/user?clients=1`, account, { + errorMsg: 'Failed to get organization users' + }); + + return { + org: orgRef, + users: users + .map((user: PlatformOrgUser) => { + return { + client_id: user.client_id, + email: user.email, + firstname: user.firstname, + guid: user.guid, + lastname: user.lastname, + name: user.name, + primary: user.primary, + roles: user.roles + } as OrgUser; + }) + .sort((a, b) => { + if ((a.client_id && !b.client_id) || (!a.client_id && b.client_id)) { + return !a.client_id ? -1 : a.client_id ? 1 : 0; + } + const aname = a.name || `${a.firstname} ${a.lastname}`.trim(); + const bname = b.name || `${b.firstname} ${b.lastname}`.trim(); + return aname.localeCompare(bname); + }) + }; + } + + /** + * Removes an user from an org. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} user - The user email or guid. + * @returns {Promise} + */ + async userRemove(account: Account, org: OrgLike, user: string): Promise<{ + org: OrgRef, + user: OrgUser + }> { + const orgRef: OrgRef = this.resolve(account, org, true); + const found = await this.userFind(account, orgRef, user); + + if (!found) { + throw new Error(`Unable to find the user "${user}"`); + } + + await this.sdk.request(`/api/v1/org/${orgRef.org_id}/user/${found.guid}`, account, { + errorMsg: 'Failed to remove user from organization', + method: 'delete' + }); + + return { + org: orgRef, + user: found + }; + } + + /** + * Updates a users role in an org. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} user - The user email or guid. + * @param {Array.} roles - One or more roles to assign. Must include a "default" role. + * @returns {Promise} + */ + async userUpdate(account: Account, org: OrgLike, user: string, roles: string[]): Promise<{ + org: OrgRef, + roles: string[], + user?: OrgUser + }> { + const orgRef: OrgRef = this.resolve(account, org, true); + const found = await this.userFind(account, org, user); + + if (!found) { + throw new Error(`Unable to find the user "${user}"`); + } + + roles = await this.sdk.role.resolve(account, roles, { org: orgRef, requireDefaultRole: true }); + + await this.sdk.request(`/api/v1/org/${orgRef.org_id}/user/${found.guid}`, account, { + errorMsg: 'Failed to update user\'s organization roles', + json: { + roles + }, + method: 'put' + }); + + return { + org: orgRef, + roles, + user: await this.userFind(account, org, found.guid) + }; + } +} diff --git a/packages/amplify-sdk/src/sdk/platform-types.ts b/packages/amplify-sdk/src/sdk/platform-types.ts new file mode 100644 index 00000000..258f7b85 --- /dev/null +++ b/packages/amplify-sdk/src/sdk/platform-types.ts @@ -0,0 +1,463 @@ +export interface PlatformActivityChange { + k: string, + v?: string | string[] | boolean, + o?: string | string[], + a?: number +} + +export interface PlatformActivityDetail { + text: string, + title: string +} + +export interface PlatformActivityEvent { + context: string, // 'api_central', 'auth', 'org', 'team' + data: { + action_user_email?: string, + action_user_guid: string, + added_roles?: string[], + app_id?: string, + app_name?: string, + automatic?: boolean, + changes?: PlatformActivityChange[], + client_guid?: string, + client_id?: string, + client_name?: string, + envId?: string, + envIds?: string[], + from?: string, // 'web' + governance?: string, + id?: string, + idp?: { + id: string, + name: string + }, + internal?: boolean, + ip?: string, + modified_by?: string, // 'Platform' + name?: string, + org_guid?: string, + org_id: number, + org_name?: string, + previous_role?: string, + production?: boolean + region?: string, + removed_roles?: string[], + role?: string, + roles?: string[], + team?: { + apps?: string[], + default: boolean, + guid: string, + name: string + }, + team_guid?: string, + team_name?: string, + user_email?: string, + user_firstname?: string, + user_guid?: string, + user_lastname?: string + }, + details: PlatformActivityDetail[], + event: string, + id: string, + message: string, + ts: number +} + +export interface PlatformClient { + _id: string, + client_id: string, + created: string, + created_by: { + guid: string, + type: string // 'user' + }, + description?: string, + guid: string, + key_id?: string, + migrated?: boolean, + name: string, + org_guid: string, + roles: string[], + tags?: string[], + teams?: number, + type: 'certificate' | 'secret', + updated: string +} + +export interface PlatformEntitlement { + description: string, + items?: { // when `type === 'array'` + type: string // 'string' + }, + title: string, + type?: 'array' | 'boolean' | 'integer' | 'number', + 'x-abs'?: boolean, + 'x-allow-below-plan'?: boolean, + 'x-allow-governance'?: string[], // [ 'Axway Managed' ] + 'x-aggregate': boolean, + 'x-aggregate-envs'?: boolean, + 'x-entry-unit'?: string, // 'bytes' + 'x-event'?: string, + 'x-governance'?: string, // 'Customer Managed' + 'x-hide-if'?: boolean, + 'x-immutable'?: boolean | string[], // [ 'Bundle' ] + 'x-metric': string, + 'x-translate-metrics'?: string[], + 'x-unit': string, // 'Calls', 'GB', 'transactions' + 'x-unit-multiplier'?: number +} + +export interface PlatformEntitlements { + allowChildOrgs?: boolean, + allowProduction?: boolean, + 'AOB.Transactions'?: number, + 'APIM.Transactions': number, + 'APIB.Transactions': number, + apiRateMonth?: number, + appDesigner?: boolean, + appPreview?: boolean, + collaboration?: boolean, + containerPoints?: number, + daysDataRetained?: number, + eventRateMonth?: number, + 'Hub.Assets'?: number, + 'Hub.Subscriptions'?: number, + 'Hub.Transactions'?: number, + hyperloop?: boolean, + idp?: boolean, + limit_read_only_users?: number, + limit_users?: number, + nativeSDK?: boolean, + paidSupport?: boolean, + partners?: PlatformEntitlementPartner[], + premiumModules?: boolean, + provider?: boolean, + provision_envs?: string[], // 'sandbox' + public_provider?: true, + pushRateMonth?: number, + storageDatabaseGB?: number, + storageFilesGB?: number, + 'Streams.Events'?: number, + transactions?: number +} + +export type PlatformEntitlementPartner = 'acs' | 'analytics' | 'api_central' | 'cloud_elements'; + +export interface PlatformOrg extends PlatformOrgPartners { + _id: string, + account_id: null, + active: boolean, + analytics: { + token: string + }, + branding?: PlatformOrgBranding, + children?: [], + created: string, // ISO date + created_by: { + email: string, + guid: string, + name: string, + type: string + }, + entitlements?: PlatformEntitlements, + envs?: string[], + guid: string, + has_apps: boolean, + internal: boolean, + last_login?: string, // ISO date + last_push?: string, // ISO date + last_push_success?: boolean, + logged_in_count?: number, + name: string, + org_id: number, + region: string, + subscriptions: PlatformSubscription[], + support_access_code: null, + updated?: string, // ISO date + users: PlatformOrgUserRef[] +} + +export interface PlatformOrgBranding { + catalog_header_left: string, + catalog_header_right: string, + catalog_tile_border: string, + catalog_tile_border_hover: string, + logo: string +} + +export interface PlatformOrgEnvironment { + _id: string, // 'production' + acsBaseUrl?: string, + created?: string, // ISO date + created_by?: { + guid: string, + type: string // 'user' + }, + governance?: string, // 'Customer Managed' + guid?: string, + isProduction: boolean, + name: string, + nodeACSEndpoint?: string, + org_guid?: string, + source?: string, // 'api_central' + type?: string, // 'usage' + updated?: string // ISO date +} + +export interface PlatformOrgPartners { + acs?: PlatformPartner, + api_central?: PlatformPartner, + cloud_elements?: PlatformPartner +} + +export interface PlatformOrgRef { + guid: string, + name: string, + org_id: number, + role: string +} + +export interface PlatformOrgUsage { + basis: string, // 'range' + bundle?: { + edition: string, + end_date: string, // ISO date + metrics?: { + [metric: string]: { + envs: { + [guid: string]: { + production: boolean, + quota: number, + tokens: number, + value: number + } + }, + name: string, + tokens: number, + unit: string, + value: number + } + }, + name: string, + plan: string, // 'trial' + product: string, // 'Bundle' + ratios: { + [key: string]: number | boolean + }, + start_date: string // ISO date + }, + created: string, // ISO date + ending: string, // ISO date + from: string, // ISO date + from_ts: number, + org_id: number, + to: string, // ISO date + to_ts: number, + usage: { + [product: string]: { + name: string, + governance: { + [name: string]: { + [metric: string]: PlatformOrgUsageMetric + } + } + } + } +} + +export interface PlatformOrgUsageMetric { + envs: { + [name: string]: any + }, + name: string, + quota: number, + percent: number, + unit: string, + unlimited: boolean, + value: number +} + +export interface PlatformOrgUser { + _id?: string, + activated?: boolean, + active?: boolean, + client_id?: string, + created: string, // ISO date + created_by?: { + guid: string, + type: string // 'user' + }, + date_activated?: string, // ISO date + email?: string, + external?: boolean, + firstname?: string, + guid: string, + last_login?: string, // ISO date + lastname?: string, + name: string, + nodeacs?: boolean, + org_guid?: string, + org_id?: number, + primary: boolean, + role: string, + roles: string[], + teams: number, + type?: string, // 'secret' + user_id: number +} + +export interface PlatformOrgUserRef { + guid: string, + primary?: boolean, + roles: string[] +} + +export interface PlatformPartner { + provisioned: boolean, + provisioned_date: string, // ISO date + provisioned_envs?: string[], // 'sandbox' + requested_date: string, // ISO date + requested_envs?: string[], // 'sandbox' + state: string // 'provisioned' +} + +export interface PlatformRole { + client?: boolean, + default?: boolean, + entitlement?: string, // 'containerPoints' + id: string, + name: string, + order?: number, + org?: boolean, + partner?: string, // 'api_central' + product?: string, // 'ars' + required_default_roles?: string[], // [ 'administrator', 'developer' ] + subscription?: string[], + team?: boolean +} + +export interface PlatformRoleRef { + id: string, + name: string +} + +export interface PlatformSession { + from: string, + guid: string, + idp: string, + nodeacs: boolean, + org: PlatformOrg, + orgs: PlatformOrgRef[], + org_id: number, + role: string, // 'administrator' + roles: string[], // [ 'administrator', 'ars_admin', 'api_central_admin' ] + sessionID: string, + sid: string, + teams: PlatformTeamRef[], + token: string, + user: PlatformUser, + username: string +} + +export interface PlatformSubscription { + end_date: string, // ISO date + entitlements: PlatformEntitlements, + expired: boolean, + governance: string, // 'SaaS' + id: string, + plan: string, + product: string, + source?: string, + start_date: string, // ISO date + tier: string +} + +export interface PlatformTeam { + _central_migrated?: boolean, + _default?: boolean, + _id: string, + apps: string[], + created: string, // ISO date + default: boolean, + desc?: string, + guid: string, + name: string, + org_guid: string, + tags: string[], + updated: string, // ISO date + users: PlatformTeamUser[] +} + +export interface PlatformTeamRef { + apps: string[], + default: boolean, + guid: string, + name: string, + roles: PlatformRoleRef[] +} + +export interface PlatformTeamUser { + guid: string, + roles: string[], + type: 'client' | 'user' +} + +export interface PlatformUser { + _id: string, + activated?: boolean, + active?: boolean, + created: string, // ISO date + date_activated: string, // ISO date + disable_2fa?: boolean, + email: string, + external?: boolean, + firstname: string, + guid: string, + is_titan?: number, + last_browser_language?: string, + last_logged_in_org?: number, + last_login?: string, // ISO date + lastname: string, + logged_in_count?: number, + logged_in_from_cli?: boolean, + logged_in_from_other?: boolean, + logged_in_from_studio?: boolean, + logged_in_from_web?: boolean, + login_org?: string, // 'last_logged' + oidc_org?: number, + password_updated?: string, // ISO date + prefs?: { + chart_scale_page: boolean, + collapse_nav: boolean, + favorite_apps: string[], + hide_custom_query_doc: boolean, + inactivity_period: number, + map: { + bounds: { + _ne: { + lat: number, + lng: number + }, + _sw: { + lat: number, + lng: number + } + }, + center: { + lat: number, + lng: number + }, + zoom: number + }, + notification_checked: { + [key: string]: string + }, + roles_documentation: boolean, + theme: string + }, + timezone?: string, + updated: string, // ISO date + user_id: number +} diff --git a/packages/amplify-sdk/src/sdk/role.ts b/packages/amplify-sdk/src/sdk/role.ts new file mode 100644 index 00000000..95372889 --- /dev/null +++ b/packages/amplify-sdk/src/sdk/role.ts @@ -0,0 +1,134 @@ +import Base from './base.js'; +import E from '../errors.js'; +import snooplogg from 'snooplogg'; +import { Account, Entitlements, Org, OrgRef, OrgLike } from '../types.js'; +import { PlatformEntitlementPartner, PlatformRole } from './platform-types.js'; + +const { log } = snooplogg('amplify-sdk:auth'); +const { highlight } = snooplogg.styles; + +export default class AmplifySDKRole extends Base { + /** + * Get all roles. + * @param {Object} account - The account object. + * @param {Object} [params] - Various parameters. + * @param {Boolean} [params.client] - When `true`, returns client specific roles. + * @param {Boolean} [params.default] - When `true`, returns default roles only. + * @param {Object|String|Number} [params.org] - The organization object, name, id, or guid. + * @param {Boolean} [params.team] - When `true`, returns team specific roles. + * @returns {Promise} + */ + async list(account: Account, params?: { + client?: boolean, + default?: boolean, + org?: OrgLike, + team?: boolean + }): Promise { + if (params === undefined) { + params = {}; + } + + let roles: PlatformRole[] = await this.sdk.request( + `/api/v1/role${params.team ? '?team=true' : ''}`, + account, + { errorMsg: 'Failed to get roles' } + ); + + const orgLike = params.org || account.org?.guid; + if (orgLike) { + const org: Org = await this.sdk.org.find(account, orgLike); + const { entitlements, subscriptions } = org; + + roles = roles.filter((role: PlatformRole) => { + return role.org + && (!role.partner || entitlements.partners?.includes(role.partner as PlatformEntitlementPartner) && org.partners[role.partner as PlatformEntitlementPartner]?.provisioned) + && (!role.entitlement || entitlements[role.entitlement as keyof Entitlements]) + && (!role.subscription || subscriptions.find(sub => { + return new Date(sub.endDate) >= new Date() && role.subscription?.includes(sub.category); + })); + }); + } + + if (params.client) { + roles = roles.filter((r: PlatformRole) => r.client); + } + + if (params.default) { + roles = roles.filter((r: PlatformRole) => r.default); + } + + if (params.team) { + roles = roles.filter((r: PlatformRole) => r.team); + } + + return roles; + } + + /** + * Fetches roles for the given params, then validates the supplied list of roles. + * @param {Object} account - The account object. + * @param {Array.} roles - One or more roles to assign. + * @param {Object} [opts] - Various options. + * @param {Boolean} [opts.client] - When `true`, returns client specific roles. + * @param {Boolean} [opts.default] - When `true`, returns default roles only. + * @param {Object|String|Number} [opts.org] - The organization object, name, id, or guid. + * @param {Boolean} [opts.requireRoles] - When `true`, throws an error if roles is empty. + * @param {Boolean} [opts.requireDefaultRole] - When `true`, throws an error if roles is empty or if there are no default roles. + * @param {Boolean} [opts.team] - When `true`, validates team specific roles. + * @returns {Promise} + */ + async resolve(account: Account, roles: string[], opts: { + client?: boolean, + default?: boolean, + org?: OrgRef, + requireRoles?: boolean, + requireDefaultRole?: boolean, + team?: boolean + }): Promise { + if (!Array.isArray(roles)) { + throw E.INVALID_ARGUMENT('Expected roles to be an array'); + } + + if (opts === undefined) { + opts = {}; + } + + if (!roles.length && !opts.requireRoles && !opts.requireDefaultRole) { + return []; + } + + const allowedRoles: PlatformRole[] = await this.list(account, { + client: opts.client, + default: opts.default, + org: opts.org, + team: opts.team + }); + const defaultRoles: string[] = allowedRoles.filter(r => r.default).map(r => r.id); + + if (!roles.length && opts.requireDefaultRole) { + throw new Error(`Expected at least one of the following roles: ${defaultRoles.join(', ')}`); + } + if (!roles.length && opts.requireRoles) { + throw new Error(`Expected at least one of the following roles: ${allowedRoles.join(', ')}`); + } + + roles = roles + .reduce((arr, role: string) => arr.concat(role.split(',')), [] as string[]) + .map((role: string) => { + const lr = role.toLowerCase().trim(); + const found = allowedRoles.find(ar => ar.id === lr || ar.name.toLowerCase() === lr); + if (!found) { + throw new Error(`Invalid role "${role}", expected one of the following: ${allowedRoles.map(r => r.id).join(', ')}`); + } + return found.id; + }); + + log(`Resolved roles: ${highlight(roles.join(', '))}`); + + if (opts.requireDefaultRole && !roles.some((r: string) => defaultRoles.includes(r))) { + throw new Error(`You must specify a default role: ${defaultRoles.join(', ')}`); + } + + return roles; + } +} diff --git a/packages/amplify-sdk/src/sdk/team.ts b/packages/amplify-sdk/src/sdk/team.ts new file mode 100644 index 00000000..d2bcb82a --- /dev/null +++ b/packages/amplify-sdk/src/sdk/team.ts @@ -0,0 +1,477 @@ +import Base from './base.js'; +import E from '../errors.js'; +import { + Account, + OrgLike, + OrgRef, + OrgUser, + Team, + TeamInfo, + TeamInfoChanges, + TeamUser +} from '../types.js'; +import { PlatformTeam } from './platform-types.js'; + +export default class AmplifySDKTeam extends Base { + /** + * Creates a team in an org. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} name - The name of the team. + * @param {Object} [info] - The team info. + * @param {Boolean} [info.default] - When `true`, makes this team the default. + * @param {String} [info.desc] - The team description. + * @param {Array.} [info.tags] - A list of tags. + * @returns {Promise} + */ + async create(account: Account, org: OrgLike, name: string, info?: TeamInfo): Promise<{ + org: OrgRef, + team: Team + }> { + const orgRef: OrgRef = this.sdk.org.resolve(account, org); + + if (!name || typeof name !== 'string') { + throw E.INVALID_ARGUMENT('Expected name to be a non-empty string'); + } + + const team: PlatformTeam = await this.sdk.request('/api/v1/team', account, { + errorMsg: 'Failed to create team', + json: { + ...this.prepareTeamInfo(info).data, + name, + org_guid: orgRef.guid + } + }) as PlatformTeam; + + return { + org: orgRef, + team: { + apps: team.apps, + created: team.created, + default: team.default, + desc: team.desc, + guid: team.guid, + name: team.name, + org_guid: orgRef.guid, + tags: team.tags, + users: [] // no users for new teams + } as Team + }; + } + + /** + * Find a team by name or guid. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team name or guid. + * @returns {Promise} + */ + async find(account: Account, org: OrgLike, team: string): Promise<{ + org: OrgRef, + team: Team + }> { + const orgRef: OrgRef = this.sdk.org.resolve(account, org); + const origTeam = team; + + if (!team || typeof team !== 'string') { + throw E.INVALID_ARGUMENT('Expected team to be a name or guid'); + } + + const { teams } = await this.list(account, org); + team = team.toLowerCase(); + + const teamObj = teams.find(t => t.name.toLowerCase() === team || t.guid === team); + if (!teamObj) { + throw new Error(`Unable to find team "${origTeam}" in the "${orgRef.name}" organization`); + } + + return { + org: orgRef, + team: teamObj + }; + } + + /** + * List all teams in an org. + * @param {Object} account - The account object. + * @param {Object|String|Number|undefined} org - The organization object, name, id, or guid. + * @param {String} [userGuid] - A user guid to filter teams + * @returns {Promise} + */ + async list(account: Account, org: OrgLike, userGuid?: string): Promise<{ + org?: OrgRef, + teams: Team[] + }> { + const orgRef: OrgRef = this.sdk.org.resolve(account, org); + let teams: PlatformTeam[] = await this.sdk.request(`/api/v1/team${orgRef?.org_id ? `?org_id=${orgRef.org_id}` : ''}`, account, { + errorMsg: 'Failed to get organization teams' + }); + + if (userGuid) { + teams = teams.filter(team => { + return team.users.find(u => u.guid === userGuid); + }); + } + + const { users } = await this.sdk.org.userList(account, orgRef); + + return { + org: orgRef, + teams: teams + .map((team: PlatformTeam): Team => ({ + apps: team.apps, + created: team.created, + default: team.default, + desc: team.desc, + guid: team.guid, + name: team.name, + org_guid: team.org_guid, + tags: team.tags, + users: team.users + .reduce((list, { guid, roles, type }) => { + const user: OrgUser | undefined = users.find(u => u.guid === guid); + if (user) { + list.push({ + client_id: user.client_id, + email: user.email, + firstname: user.firstname, + guid, + lastname: user.lastname, + name: user.name, + roles, + type + }); + } + return list; + }, [] as TeamUser[]) + .sort((a, b) => { + if (a.type !== b.type) { + return a.type === 'user' ? -1 : a.type === 'client' ? 1 : 0; + } + return a.name.localeCompare(b.name); + }) + })) + .sort((a: Team, b: Team) => a.name.localeCompare(b.name)) + }; + } + + /** + * Determines team info changes and prepares the team info to be sent. + * @param {Object} [info] - The new team info. + * @param {Object} [prevInfo] - The previous team info. + * @returns {Promise} + */ + prepareTeamInfo(info: TeamInfo = {}, prevInfo?: TeamInfo): { + changes: TeamInfoChanges, + data: TeamInfo + } { + if (!info || typeof info !== 'object') { + throw E.INVALID_ARGUMENT('Expected team info to be an object'); + } + + const changes: TeamInfoChanges = {}; + const data: TeamInfo = {}; + + // populate data + if (info.default !== undefined) { + data.default = !!info.default; + } + if (info.desc !== undefined) { + data.desc = String(info.desc).trim(); + } + if (info.name !== undefined) { + data.name = String(info.name).trim(); + } + if (info.tags !== undefined) { + if (!Array.isArray(info.tags)) { + throw E.INVALID_ARGUMENT('Expected team tags to be an array of strings'); + } + data.tags = info.tags + .reduce((arr, tag) => arr.concat(tag.split(',')), [] as string[]) + .map(tag => tag.trim()); + } + + // remove unchanged + if (prevInfo) { + for (const key of Object.keys(data)) { + const cur = data[key as keyof TeamInfo]; + const prev = prevInfo[key as keyof TeamInfo]; + if (Array.isArray(cur)) { + if (cur && prev && !(cur < prev || cur > prev)) { + delete data[key as keyof TeamInfo]; + } + } else if (cur === prev) { + delete data[key as keyof TeamInfo]; + } else { + changes[key] = { + v: cur, + p: prev + }; + } + } + } + + return { changes, data }; + } + + /** + * Removes a team from an organization. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team or guid. + * @returns {Promise} + */ + async remove(account: Account, org: OrgLike, team: string): Promise<{ + org: OrgRef, + team: Team + }> { + const result = await this.find(account, org, team); + + await this.sdk.request(`/api/v1/team/${result.team.guid}`, account, { + errorMsg: 'Failed to remove team', + method: 'delete' + }); + + return result; + } + + /** + * Updates team information. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team or guid. + * @param {Object} [info] - The team info. + * @param {String} [info.desc] - The team description. + * @param {Boolean} [info.default] - When `true`, makes this team the default. + * @param {Array.} [info.tags] - A list of tags. + * @returns {Promise} + */ + async update(account: Account, org: OrgLike, team: string, info: TeamInfo): Promise<{ + changes: TeamInfoChanges, + org: OrgRef, + team: Team + }> { + const result = await this.find(account, org, team); + let teamObj: Team = result.team; + + const { changes, data } = this.prepareTeamInfo(info, teamObj); + + if (Object.keys(data).length) { + const platformTeam: PlatformTeam = await this.sdk.request(`/api/v1/team/${teamObj.guid}`, account, { + errorMsg: 'Failed to update team', + json: data, + method: 'put' + }); + teamObj = { + apps: platformTeam.apps, + created: platformTeam.created, + default: platformTeam.default, + desc: platformTeam.desc, + guid: platformTeam.guid, + name: platformTeam.name, + org_guid: platformTeam.org_guid, + tags: platformTeam.tags, + users: teamObj.users + }; + } + + return { + changes, + org: result.org, + team: teamObj + }; + } + + /** + * Adds a user to a team. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team or guid. + * @param {String} user - The user email or guid. + * @param {Array.} roles - One or more roles to assign. Must include a "default" role. + * @returns {Promise} + */ + async userAdd(account: Account, org: OrgLike, team: string, user: string, roles: string[]): Promise<{ + org: OrgRef, + team: Team, + user: OrgUser + }> { + const result = await this.find(account, org, team); + + const found: OrgUser | undefined = await this.sdk.org.userFind(account, result.org.guid, user); + if (!found) { + throw new Error(`Unable to find the user "${user}"`); + } + + const teamRoles: string[] = await this.sdk.role.resolve(account, roles, { + org: result.org, + requireRoles: true, + team: true + }); + const platformTeam: PlatformTeam = await this.sdk.request(`/api/v1/team/${result.team.guid}/user/${found.guid}`, account, { + errorMsg: 'Failed to add user to organization', + json: { + roles: teamRoles, + type: found.client_id ? 'client' : 'user' + } + }); + const { users } = await this.sdk.org.userList(account, result.org); + + return { + org: result.org, + team: { + apps: platformTeam.apps, + created: platformTeam.created, + default: platformTeam.default, + guid: platformTeam.guid, + name: platformTeam.name, + org_guid: platformTeam.org_guid, + tags: platformTeam.tags, + users: platformTeam.users + .reduce((list, { guid, roles, type }) => { + const user: OrgUser | undefined = users.find(u => u.guid === guid); + if (user) { + list.push({ + client_id: user.client_id, + email: user.email, + firstname: user.firstname, + guid, + lastname: user.lastname, + name: user.name, + roles, + type + }); + } + return list; + }, [] as TeamUser[]) + }, + user: found + }; + } + + /** + * Finds a user in a team. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team or guid. + * @param {String} user - The user email or guid. + * @returns {Promise} + */ + async userFind(account: Account, org: OrgLike, team: string, user: string): Promise<{ + org: OrgRef, + team: Team, + user?: TeamUser + }> { + const { org: orgRef, team: teamObj, users } = await this.userList(account, org, team); + user = user.toLowerCase(); + return { + org: orgRef, + team: teamObj, + user: users.find(u => String(u.email).toLowerCase() === user || String(u.guid).toLowerCase() === user) + }; + } + + /** + * List all users of a team. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team or guid. + * @returns {Promise} + */ + async userList(account: Account, org: OrgLike, team: string): Promise<{ + org: OrgRef, + team: Team, + users: TeamUser[] + }> { + const { org: orgRef, team: teamObj } = await this.find(account, org, team); + return { + org: orgRef, + team: teamObj, + users: teamObj.users + }; + } + + /** + * Removes a user from a team. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team or guid. + * @param {String} user - The user email or guid. + * @returns {Promise} + */ + async userRemove(account: Account, org: OrgLike, team: string, user: string): Promise<{ + org: OrgRef, + team: Team, + user: TeamUser + }> { + const { org: orgRef, team: teamObj, user: found } = await this.userFind(account, org, team, user); + + if (!found) { + throw new Error(`Unable to find the user "${user}"`); + } + + await this.sdk.request(`/api/v1/team/${teamObj.guid}/user/${found.guid}`, account, { + errorMsg: 'Failed to remove user from team', + method: 'delete' + }); + + return { + org: orgRef, + team: teamObj, + user: found + }; + } + + /** + * Updates a user's role in a team. + * @param {Object} account - The account object. + * @param {Object|String|Number} org - The organization object, name, id, or guid. + * @param {String} team - The team or guid. + * @param {String} user - The user email or guid. + * @param {Array.} roles - One or more roles to assign. Must include a "default" role. + * @returns {Promise} + */ + async userUpdate(account: Account, org: OrgLike, team: string, user: string, roles: string[]): Promise<{ + org: OrgRef, + roles: string[], + team: Team, + user: TeamUser + }> { + const { org: orgRef, team: teamObj, user: found } = await this.userFind(account, org, team, user); + + if (!found) { + throw new Error(`Unable to find the user "${user}"`); + } + + roles = await this.sdk.role.resolve(account, roles, { org: orgRef, requireRoles: true, team: true }); + + const result: PlatformTeam = await this.sdk.request(`/api/v1/team/${teamObj.guid}/user/${found.guid}`, account, { + errorMsg: 'Failed to update user\'s organization roles', + json: { + roles + }, + method: 'put' + }); + + // update the roles in the results + for (const user of result.users) { + if (user.guid === found.guid) { + found.roles = user.roles; + for (const teamUser of teamObj.users) { + if (teamUser.guid === found.guid) { + teamUser.roles = user.roles; + break; + } + } + break; + } + } + + return { + org: orgRef, + roles, + team: teamObj, + user: found + }; + } +} diff --git a/packages/amplify-sdk/src/sdk/user.ts b/packages/amplify-sdk/src/sdk/user.ts new file mode 100644 index 00000000..fa96707e --- /dev/null +++ b/packages/amplify-sdk/src/sdk/user.ts @@ -0,0 +1,119 @@ +import Base from './base.js'; +import E from '../errors.js'; +import snooplogg from 'snooplogg'; +import { Account, ActivityParams, ActivityResult, User, UserChanges, UserInfo } from '../types.js'; +import { PlatformUser } from './platform-types.js'; + +const { log } = snooplogg('amplify-sdk:auth'); + +export default class AmplifySDKUser extends Base { + /** + * Retrieves an account's user's activity. + * @param {Object} account - The account object. + * @param {Object} [params] - Various parameters. + * @param {String} [params.from] - The start date in ISO format. + * @param {String|Boolean} [params.month] - A month date range. Overrides `to` and + * `from`. If `true`, uses current month. + * @param {String} [params.to] - The end date in ISO format. + * @returns {Promise} + */ + async activity(account: Account, params?: { + from?: string, + month?: string | boolean, + to?: string + }): Promise { + return await this.sdk.activity.find(account, { + ...params, + userGuid: account.user.guid + } as ActivityParams); + } + + /** + * Retrieves a user's information. + * @param {Object} account - The account object. + * @param {String} user - The user email or guid. + * @returns {Promise} + */ + async find(account: Account, user: User | string): Promise { + if (typeof user === 'object' && user.guid) { + return user; + } + + const subject: string = user as string; + try { + const platformUser: PlatformUser = await this.sdk.request(`/api/v1/user/${subject}`, account, { + errorMsg: 'Failed to find user' + }); + + return { + dateJoined: platformUser.date_activated, + email: platformUser.email, + firstname: platformUser.firstname, + guid: platformUser.guid, + lastname: platformUser.lastname + }; + } catch (e: any) { + if (e.statusCode === 404) { + throw new Error(`User "${subject}" not found`); + } + throw e; + } + } + + /** + * Updates an account's user's information. + * @param {Object} account - The account object. + * @param {Object} [info] - Various user fields. + * @param {String} [info.firstname] - The user's first name. + * @param {String} [info.lastname] - The user's last name. + * @returns {Promise} + */ + async update(account: Account, info: UserInfo = {}): Promise<{ + changes: UserChanges, + user: User | null + }> { + this.assertPlatformAccount(account); + + if (!info || typeof info !== 'object') { + throw E.INVALID_ARGUMENT('Expected user info to be an object'); + } + + let user: User | null = account.user; + + const changes: UserChanges = {}; + const json: UserInfo = { + firstname: info.firstname ? String(info.firstname).trim() : undefined, + lastname: info.lastname ? String(info.lastname).trim() : undefined + }; + + // remove unchanged + for (const key of Object.keys(json)) { + const value = json[key as keyof UserInfo]; + if (value === undefined || value === user[key as keyof UserInfo]) { + delete json[key as keyof UserInfo]; + } else { + changes[key] = { + v: json[key as keyof UserInfo], + p: user[key as keyof UserInfo] + }; + } + } + + if (Object.keys(json).length) { + await this.sdk.request(`/api/v1/user/profile/${user.guid}`, account, { + errorMsg: 'Failed to update user information', + json, + method: 'put' + }); + + log('Refreshing account information...'); + const acct: Account | undefined = await this.sdk.auth.loadSession(account); + user = acct?.user || null; + } + + return { + changes, + user + }; + } +} diff --git a/packages/amplify-sdk/src/server.js b/packages/amplify-sdk/src/server.ts similarity index 68% rename from packages/amplify-sdk/src/server.js rename to packages/amplify-sdk/src/server.ts index c73aa3eb..e650daac 100644 --- a/packages/amplify-sdk/src/server.js +++ b/packages/amplify-sdk/src/server.ts @@ -1,11 +1,15 @@ import crypto from 'crypto'; -import E from './errors'; +import E from './errors.js'; import ejs from 'ejs'; import fs from 'fs-extra'; import getPort from 'get-port'; -import http from 'http'; +import http, { OutgoingHttpHeaders } from 'http'; import path from 'path'; import snooplogg from 'snooplogg'; +import { fileURLToPath } from 'url'; +import { Socket } from 'net'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const { error, log } = snooplogg('amplify-auth:server'); const { green, highlight, red } = snooplogg.styles; @@ -13,10 +17,41 @@ const { green, highlight, red } = snooplogg.styles; const defaultPort = 3000; const defaultTimeout = 120000; // 2 minutes +type RequestHandler = (req: http.IncomingMessage, res: http.ServerResponse, url: URL) => Promise; + +interface PendingHandler { + handler: RequestHandler, + resolve: (v: any) => void, + reject: (e: Error) => void, + timer: NodeJS.Timeout +} + +interface ServerOptions { + timeout?: number +} + +interface CallbackServer extends http.Server { + destroy: () => Promise +} + +export type CallbackResult = { result: any, url: string }; + +export interface CallbackHandle { + cancel: () => Promise, + start: () => Promise, + url: string +} + /** * An HTTP server to listen for redirect callbacks. */ export default class Server { + pending: Map; + port: number | null; + server: CallbackServer | null; + serverURL: string | null; + timeout: number; + /** * Initializes the server. * @@ -25,7 +60,7 @@ export default class Server { * out. * @access public */ - constructor(opts = {}) { + constructor(opts: ServerOptions = {}) { if (!opts || typeof opts !== 'object') { throw new TypeError('Expected options to be an object'); } @@ -44,7 +79,7 @@ export default class Server { * @returns {Promise} * @access public */ - async createCallback(handler) { + async createCallback(handler: RequestHandler): Promise { const requestId = crypto.randomBytes(4).toString('hex').toUpperCase(); log(`Creating callback: ${requestId}`); @@ -61,7 +96,7 @@ export default class Server { await this.stop(); } }, - start: () => new Promise((resolve, reject) => { + start: () => new Promise<{ result: any, url: string }>((resolve, reject) => { this.pending.set(requestId, { handler, resolve, @@ -87,56 +122,56 @@ export default class Server { * @returns {Promise} * @access private */ - async createServer() { + async createServer(): Promise { if (this.server) { return; } const host = 'localhost'; // this has to be localhost because platform whitelists it const port = this.port = this.port || await getPort({ host, port: defaultPort }); - const connections = {}; + const connections: { [key: string]: Socket } = {}; const callbackRegExp = /^\/callback\/([A-Z0-9]+)/; const serverURL = `http://${host}:${port}`; this.serverURL = serverURL; - await new Promise((resolve, reject) => { - this.server = http.createServer(async (req, res) => { - const url = new URL(req.url, serverURL); - let id; + await new Promise((resolve, reject) => { + this.server = http.createServer(async (req: http.IncomingMessage, res: http.ServerResponse) => { + const url = new URL(req.url as string, serverURL); let request; log(`Incoming request: ${highlight(url.pathname)}`); + const m = url.pathname.match(callbackRegExp); + const id: string | null = m && m[1]; + try { - const m = url.pathname.match(callbackRegExp); - if (!m) { + if (!id) { throw new Error('Bad Request'); } - id = m[1]; request = this.pending.get(id); if (!request) { throw new Error('Invalid Request ID'); } let head = false; - const origWriteHead = res.writeHead; - res.writeHead = function (status, message, headers) { + const origWriteHead = res.writeHead.bind(res); + res.writeHead = function (status: number, message: string, headers: OutgoingHttpHeaders) { head = true; log(`${(status >= 400 ? red : green)(String(status))} ${url.pathname} (${id})`); if (status === 302) { - const h = headers || (typeof message === 'object' && message); - log(`Redirecting client to ${highlight(h?.Location || 'nowhere!')}`); + const h: OutgoingHttpHeaders | { Location: string } = (headers as OutgoingHttpHeaders) || (typeof message === 'object' && message); + log(`Redirecting client to ${highlight(h && h.Location as string || 'nowhere!')}`); } - return origWriteHead.call(res, status, message, headers); - }; + return origWriteHead(status, message, headers); + } as any; let end = false; - const origEnd = res.end; - res.end = function (data, encoding, callback) { + const origEnd = res.end.bind(res); + res.end = function (data: Uint8Array | string, encoding: BufferEncoding, callback?: () => void) { end = true; - return origEnd.call(res, data, encoding, callback); - }; + return origEnd(data, encoding, callback); + } as any; let result; if (typeof request.handler === 'function') { @@ -156,7 +191,7 @@ export default class Server { clearTimeout(request.timer); this.pending.delete(id); request.resolve({ result, url }); - } catch (err) { + } catch (err: any) { log(`${red(err.status || '400')} ${url.pathname}`); error(err); @@ -169,11 +204,13 @@ export default class Server { if (request) { clearTimeout(request.timer); - this.pending.delete(id); + if (id) { + this.pending.delete(id); + } request.reject(err); } } - }); + }) as CallbackServer; this.server.destroy = async function destroy() { const conns = Object.values(connections); @@ -182,12 +219,12 @@ export default class Server { conn.destroy(); } log('Closing HTTP server...'); - await new Promise(resolve => this.close(resolve)); + await new Promise(resolve => this.close(() => resolve())); log('HTTP server closed'); }; this.server - .on('connection', function (conn) { + .on('connection', function (conn: Socket) { const key = `${conn.remoteAddress}:${conn.remotePort}`; connections[key] = conn; conn.on('close', () => { @@ -211,7 +248,7 @@ export default class Server { * @returns {Promise} * @memberof Server */ - async stop(force) { + async stop(force?: boolean) { if (force || this.pending.size === 0) { const { server } = this; if (server) { diff --git a/packages/amplify-sdk/src/stores/file-store.js b/packages/amplify-sdk/src/stores/file-store.ts similarity index 83% rename from packages/amplify-sdk/src/stores/file-store.js rename to packages/amplify-sdk/src/stores/file-store.ts index 00b133d8..df23bef5 100644 --- a/packages/amplify-sdk/src/stores/file-store.js +++ b/packages/amplify-sdk/src/stores/file-store.ts @@ -1,9 +1,10 @@ import crypto from 'crypto'; -import E from '../errors'; +import E from '../errors.js'; import fs from 'fs-extra'; import path from 'path'; import snooplogg from 'snooplogg'; -import TokenStore from './token-store'; +import TokenStore from './token-store.js'; +import { Account } from '../types.js'; import { writeFileSync } from '@axway/amplify-utils'; const { log, warn } = snooplogg('amplify-auth:file-store'); @@ -19,7 +20,7 @@ const algorithm = 'aes-128-cbc'; * The initialization vector for encrypting and decrypting. * @type {Buffer} */ -const iv = new Buffer.alloc(16); +const iv: Buffer = Buffer.alloc(16); /** * A file-based token store. @@ -31,6 +32,14 @@ export default class FileStore extends TokenStore { */ filename = '.tokenstore.v2'; + homeDir: string; + + tokenStoreDir: string; + + tokenStoreFile: string; + + _key!: string; + /** * Initializes the file store. * @@ -40,13 +49,13 @@ export default class FileStore extends TokenStore { * Use `opts.homeDir` instead. * @access public */ - constructor(opts = {}) { + constructor(opts: { homeDir?: string, tokenStoreDir?: string } = {}) { super(opts); - let { homeDir, tokenStoreDir } = opts; + let { homeDir } = opts; if (!homeDir || typeof homeDir !== 'string') { - if (tokenStoreDir && typeof tokenStoreDir === 'string') { - homeDir = tokenStoreDir; + if (opts.tokenStoreDir && typeof opts.tokenStoreDir === 'string') { + homeDir = opts.tokenStoreDir; } else { throw E.MISSING_REQUIRED_PARAMETER('Token store requires a home directory'); } @@ -65,7 +74,7 @@ export default class FileStore extends TokenStore { * @returns {Promise} * @access public */ - async clear(baseUrl) { + async clear(baseUrl?: string): Promise { const { entries, removed } = await super._clear(baseUrl); if (entries.length) { await this.save(entries); @@ -82,18 +91,18 @@ export default class FileStore extends TokenStore { * @returns {Array} * @access private */ - async decode(str) { + async decode(str: string): Promise { let decipher; try { decipher = crypto.createDecipheriv(algorithm, await this.getKey(), iv); - } catch (e) { + } catch (e: any) { e.amplifyCode = 'ERR_BAD_KEY'; throw e; } try { return JSON.parse(decipher.update(str, 'hex', 'utf8') + decipher.final('utf8')); - } catch (e) { + } catch (e: any) { // it's possible that there was a tokenstore on disk that was encrypted with an old key // that no longer exists and the new key can't decode it, so just nuke the tokenstore await this.remove(); @@ -109,7 +118,7 @@ export default class FileStore extends TokenStore { * @returns {Promise} * @access public */ - async delete(accounts, baseUrl) { + async delete(accounts: string | string[], baseUrl?: string): Promise { const { entries, removed } = await super._delete(accounts, baseUrl); if (entries.length) { await this.save(entries); @@ -126,11 +135,11 @@ export default class FileStore extends TokenStore { * @returns {String} * @access private */ - async encode(data) { + async encode(data: Account[]) { let cipher; try { cipher = crypto.createCipheriv(algorithm, await this.getKey(), iv); - } catch (e) { + } catch (e: any) { e.amplifyCode = 'ERR_BAD_KEY'; throw e; } @@ -143,7 +152,7 @@ export default class FileStore extends TokenStore { * @returns {Buffer} * @access private */ - async getKey() { + async getKey(): Promise { if (!this._key) { Object.defineProperty(this, '_key', { value: 'd4be0906bc9fae40' @@ -158,7 +167,7 @@ export default class FileStore extends TokenStore { * @returns {Promise} Resolves an array of tokens. * @access public */ - async list() { + async list(): Promise { if (fs.existsSync(this.tokenStoreFile)) { try { log(`Reading ${highlight(this.tokenStoreFile)}`); @@ -169,7 +178,7 @@ export default class FileStore extends TokenStore { await this.save(validEntries); } return validEntries; - } catch (e) { + } catch (e: any) { // the decode failed (or there was a keytar problem), so just log a warning and // return an empty result warn(e); @@ -184,7 +193,7 @@ export default class FileStore extends TokenStore { * @returns {Promise} * @access private */ - async remove() { + async remove(): Promise { for (let ver = 1; ver <= 2; ver++) { const file = ver === 2 ? this.tokenStoreFile : path.join(this.homeDir, this.filename.replace(/\.v2$/, '')); log(`Removing ${highlight(file)}`); @@ -199,31 +208,23 @@ export default class FileStore extends TokenStore { * @returns {Promise} * @access private */ - async save(entries) { + async save(entries: Account[]): Promise { // Auth SDK v2 changed the structure of the data in the token store, but some dependencies // still rely on Auth SDK v1's structure. We can't change force them to update and we can't // change the structure, so we have to write two versions of the token store. v2 is written // as is, but for v1, the data is translated into Auth SDK v1's structure. for (let ver = 1; ver <= 2; ver++) { - const data = await this.encode(ver === 2 ? entries : entries.map(acct => { - const v1 = { + const data = await this.encode(ver === 2 ? entries : entries.map((acct: Account) => { + const v1: any = { ...acct, ...acct.auth, - org: { - ...acct.org, - org_id: acct.org?.id - }, - orgs: !Array.isArray(acct.orgs) ? [] : acct.orgs.map(org => { - const o = { ...org, org_id: org.id }; - delete o.id; - return o; - }) + org: acct.org, + orgs: !Array.isArray(acct.orgs) ? [] : acct.orgs }; delete v1.auth; - delete v1.org.id; - return v1; + return v1 as Account; })); const file = ver === 2 ? this.tokenStoreFile : path.join(this.homeDir, this.filename.replace(/\.v2$/, '')); log(`Writing ${highlight(file)}`); @@ -238,7 +239,7 @@ export default class FileStore extends TokenStore { * @returns {Promise} * @access public */ - async set(obj) { + async set(obj: Account): Promise { await this.save(await super._set(obj)); } } diff --git a/packages/amplify-sdk/src/stores/memory-store.js b/packages/amplify-sdk/src/stores/memory-store.ts similarity index 78% rename from packages/amplify-sdk/src/stores/memory-store.js rename to packages/amplify-sdk/src/stores/memory-store.ts index 91999d90..2cb38637 100644 --- a/packages/amplify-sdk/src/stores/memory-store.js +++ b/packages/amplify-sdk/src/stores/memory-store.ts @@ -1,4 +1,5 @@ -import TokenStore from './token-store'; +import TokenStore from './token-store.js'; +import { Account } from '../types.js'; /** * A operating-specific secure token store. @@ -9,7 +10,7 @@ export default class MemoryStore extends TokenStore { * * @type {Array.} */ - store = []; + store: Account[] = []; /** * Removes all tokens. @@ -18,7 +19,7 @@ export default class MemoryStore extends TokenStore { * @returns {Promise} * @access public */ - async clear(baseUrl) { + async clear(baseUrl?: string): Promise { const { entries, removed } = await super._clear(baseUrl); this.store = entries; return removed; @@ -32,7 +33,7 @@ export default class MemoryStore extends TokenStore { * @returns {Promise} * @access public */ - async delete(accounts, baseUrl) { + async delete(accounts: string | string[], baseUrl?: string): Promise { const { entries, removed } = await super._delete(accounts, baseUrl); this.store = entries; return removed; @@ -44,7 +45,7 @@ export default class MemoryStore extends TokenStore { * @returns {Promise} Resolves an array of tokens. * @access public */ - async list() { + async list(): Promise { return this.purge(this.store); } @@ -55,7 +56,7 @@ export default class MemoryStore extends TokenStore { * @returns {Promise} * @access public */ - async set(data) { + async set(data: Account): Promise { this.store = await super._set(data); } } diff --git a/packages/amplify-sdk/src/stores/secure-store.js b/packages/amplify-sdk/src/stores/secure-store.ts similarity index 74% rename from packages/amplify-sdk/src/stores/secure-store.js rename to packages/amplify-sdk/src/stores/secure-store.ts index 958d36f0..bc77eccb 100644 --- a/packages/amplify-sdk/src/stores/secure-store.js +++ b/packages/amplify-sdk/src/stores/secure-store.ts @@ -1,10 +1,11 @@ /* eslint-disable security/detect-non-literal-require */ import crypto from 'crypto'; -import E from '../errors'; -import FileStore from './file-store'; +import E from '../errors.js'; +import FileStore from './file-store.js'; import path from 'path'; import snooplogg from 'snooplogg'; +import { RequestOptions } from '@axway/amplify-request'; const { log, warn } = snooplogg('amplify-sdk:auth:secure-store'); @@ -18,6 +19,10 @@ export default class SecureStore extends FileStore { */ filename = '.tokenstore.secure.v2'; + keytar: any; + + serviceName: string; + /** * Loads the `keytar` library and initializes the token file. * @@ -29,7 +34,7 @@ export default class SecureStore extends FileStore { * using this library. * @access public */ - constructor(opts = {}) { + constructor(opts: { homeDir?: string, requestOptions?: RequestOptions, secureServiceName?: string } = {}) { if (!opts || typeof opts !== 'object') { throw E.INVALID_ARGUMENT('Expected opts to be an object'); } @@ -41,7 +46,6 @@ export default class SecureStore extends FileStore { super(opts); - this.keytar = require('keytar'); this.serviceName = opts.secureServiceName || 'Axway AMPLIFY Auth'; this.tokenStoreFile = path.join(this.tokenStoreDir, this.filename); } @@ -53,12 +57,13 @@ export default class SecureStore extends FileStore { * @returns {Array} * @access private */ - async decode(str) { + async decode(str: string) { try { return await super.decode(str); - } catch (e) { + } catch (e: any) { if (e.amplifyCode === 'ERR_BAD_KEY') { - await this.keytar.deletePassword(this.serviceName, this.serviceName); + const keytar = await this.getKeytar(); + await keytar.deletePassword(this.serviceName, this.serviceName); } throw e; } @@ -70,13 +75,14 @@ export default class SecureStore extends FileStore { * @returns {String} * @access private */ - async getKey() { + async getKey(): Promise { if (!this._key) { let key; + const keytar = await this.getKeytar(); try { - key = await this.keytar.getPassword(this.serviceName, this.serviceName); - } catch (err) { + key = await keytar.getPassword(this.serviceName, this.serviceName); + } catch (err: any) { if (process.platform === 'linux') { // this is likely due to d-bus daemon not running (i.e. "Connection refused") or // running in a non-desktop (headless) environment (i.e. "Cannot autolaunch D-Bus without X11") @@ -98,10 +104,23 @@ export default class SecureStore extends FileStore { if (!key) { log('Generating new key...'); key = crypto.randomBytes(16).toString('hex'); - await this.keytar.setPassword(this.serviceName, this.serviceName, key); + await keytar.setPassword(this.serviceName, this.serviceName, key); } Object.defineProperty(this, '_key', { value: Buffer.from(key, 'hex') }); } return this._key; } + + /** + * Loads the `keytar` library if not already loaded. + * + * @returns {Promise} + * @access private + */ + async getKeytar() { + if (!this.keytar) { + this.keytar = (await import('keytar')).default; + } + return this.keytar; + } } diff --git a/packages/amplify-sdk/src/stores/token-store.js b/packages/amplify-sdk/src/stores/token-store.ts similarity index 84% rename from packages/amplify-sdk/src/stores/token-store.js rename to packages/amplify-sdk/src/stores/token-store.ts index a873041e..2b6155c0 100644 --- a/packages/amplify-sdk/src/stores/token-store.js +++ b/packages/amplify-sdk/src/stores/token-store.ts @@ -1,12 +1,18 @@ -/* eslint-disable no-unused-vars */ +/* eslint-disable no-unused-vars, @typescript-eslint/no-unused-vars */ -import E from '../errors'; +import E from '../errors.js'; import pluralize from 'pluralize'; import snooplogg from 'snooplogg'; +import { Account } from '../types.js'; const { log } = snooplogg('amplify-sdk:auth:token-store'); const { highlight } = snooplogg.styles; +export interface StoreMutateResult { + entries: Account[], + removed: Account[] +} + /** * A regex to match a URL protocol. * @type {RegExp} @@ -37,8 +43,8 @@ export default class TokenStore { * @returns {Promise} * @access public */ - async clear(baseUrl) { - return { entries: [], removed: [] }; + async clear(baseUrl?: string): Promise { + return []; } /** @@ -48,7 +54,7 @@ export default class TokenStore { * @returns {Promise} * @access public */ - async _clear(baseUrl) { + async _clear(baseUrl?: string): Promise { const entries = await this.list(); if (!baseUrl) { @@ -80,7 +86,7 @@ export default class TokenStore { * @returns {Promise} * @access public */ - async delete(accounts, baseUrl) { + async delete(accounts: string | string[], baseUrl?: string): Promise { return []; } @@ -92,7 +98,7 @@ export default class TokenStore { * @returns {Promise} * @access public */ - async _delete(accounts, baseUrl) { + async _delete(accounts: string | string[], baseUrl?: string): Promise { const entries = await this.list(); const removed = []; @@ -126,7 +132,7 @@ export default class TokenStore { * @returns {Promise} Resolves the token or `undefined` if not set. * @access public */ - async get({ accountName, baseUrl, hash } = {}) { + async get({ accountName, baseUrl, hash }: { accountName?: string, baseUrl?: string, hash?: string } = {}): Promise { const entries = await this.list(); if (baseUrl) { @@ -141,7 +147,9 @@ export default class TokenStore { log(`Scanning ${highlight(len)} ${pluralize('token', len)} for accountName=${highlight(accountName)} hash=${highlight(hash)} baseUrl=${highlight(baseUrl)}`); for (let i = 0; i < len; i++) { - if (((accountName && entries[i].name === accountName) || (hash && entries[i].hash === hash)) && (!baseUrl || entries[i].auth.baseUrl.replace(protoRegExp, '').replace(/\/$/, '') === baseUrl)) { + const bu = entries[i].auth.baseUrl.replace(protoRegExp, '').replace(/\/$/, ''); + log(` ${i}: ${entries[i].name || 'unknown'} (${entries[i].hash || 'no hash'}) ${bu}`); + if (((accountName && entries[i].name === accountName) || (hash && entries[i].hash === hash)) && (!baseUrl || bu === baseUrl)) { log(`Found account tokens: ${highlight(entries[i].name)}`); return entries[i]; } @@ -158,7 +166,7 @@ export default class TokenStore { * @returns {Promise} Resolves an array of tokens. * @access public */ - async list() { + async list(): Promise { return []; } @@ -169,7 +177,7 @@ export default class TokenStore { * @returns {Array.} * @access private */ - purge(entries) { + purge(entries: Account[]) { if (!entries) { return []; } @@ -213,7 +221,7 @@ export default class TokenStore { * @returns {Promise} * @access private */ - async set(data) { + async set(data: Account): Promise { // noop } @@ -224,7 +232,7 @@ export default class TokenStore { * @returns {Promise} * @access private */ - async _set(data) { + async _set(data: Account) { const entries = await this.list(); for (let i = 0, len = entries.length; i < len; i++) { diff --git a/packages/amplify-sdk/src/telemetry.js b/packages/amplify-sdk/src/telemetry.ts similarity index 71% rename from packages/amplify-sdk/src/telemetry.js rename to packages/amplify-sdk/src/telemetry.ts index 7a007f51..999381f7 100644 --- a/packages/amplify-sdk/src/telemetry.js +++ b/packages/amplify-sdk/src/telemetry.ts @@ -6,24 +6,30 @@ import snooplogg, { createInstanceWithDefaults, StripColors } from 'snooplogg'; import * as request from '@axway/amplify-request'; import * as uuid from 'uuid'; import { arch as _arch, isDir, osInfo, redact, writeFileSync } from '@axway/amplify-utils'; +import { fileURLToPath } from 'url'; +import { RequestOptions } from '@axway/amplify-request'; import { serializeError } from 'serialize-error'; import { spawn } from 'child_process'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const __filename = fileURLToPath(import.meta.url); + const logger = snooplogg('amplify-sdk:telemetry'); const { log } = logger; const { highlight } = snooplogg.styles; /** * A map of known send process exit codes. - * @type {Object} + * @type {Array} */ -const exitCodes = { - 0: 'Success', - 1: 'Error', - 2: 'Already running', - ALREADY_RUNNING: 2, - ERROR: 1 -}; +const exitCodes = [ + 'Success', + 'Error', + 'Already running' +]; + +const CODE_ALREADY_RUNNING = 2; +const CODE_ERROR = 1; /** * The number of milliseconds since the last execution before starting a new session. @@ -43,11 +49,67 @@ const sendBatchSize = 10; */ const telemetryUrl = 'https://gatekeeper.platform.axway.com/v4/event'; +export interface TelemetryOptions { + appGuid: string, + appVersion: string, + cacheDir: string, + environment: string, + requestOptions?: request.RequestOptions, + url?: string +} + +export interface CrashData { + message: string, + stack?: string | string[], + [key: string]: any +} + +export type CrashPayload = CrashData | Error; + +export interface EventPayload { + cpus?: number, + event: string, + memory?: number, + nodePlatform?: string, + nodeVersion?: string, + [key: string]: any +} + +interface EventData { + cpus?: number, + event?: string, + memory?: number, + message: string, + nodePlatform?: string, + nodeVersion?: string +} + /** * Sends anonymous telemetry events for Axway products to help improve our software. * Spec: https://techweb.axway.com/confluence/display/analytics/Analytics+JSON+Payload+V4 */ export default class Telemetry { + appDir: string; + common: { + app: string, + distribution: { + environment: string, + version: string + }, + hardware: { + arch: string, + id: string + }, + os: { + arch: string + }, + version: string + }; + count: number; + requestOptions?: RequestOptions; + sessionId: string; + url: string; + /** * Initializes a telemetry instance. * @@ -62,7 +124,7 @@ export default class Telemetry { * intended for testing purposes. * @access public */ - constructor(opts) { + constructor(opts: TelemetryOptions) { if (!opts || typeof opts !== 'object') { throw new TypeError('Expected telemetry options to be an object'); } @@ -141,7 +203,7 @@ export default class Telemetry { * @param {String} [payload.stack] - The stack trace. * @access public */ - addCrash(payload) { + addCrash(payload: CrashPayload) { if (isTelemetryDisabled() || this.common.distribution.environment !== 'production') { return; } @@ -150,20 +212,18 @@ export default class Telemetry { throw new TypeError('Expected crash payload to be an object'); } - if (payload instanceof Error) { - // we need to clone the error so that it can be serialized - payload = serializeError(payload); - } + // we need to clone the error so that it can be serialized + const data = payload instanceof Error ? serializeError(payload) : payload; - if (!payload.message || typeof payload.message !== 'string') { + if (!data.message || typeof data.message !== 'string') { throw new TypeError('Expected crash payload to have a message'); } const homeDir = os.homedir(); - if (typeof payload.stack === 'string') { - payload.stack = [ - payload.stack.split(/\r\n|\n/).map((line, i) => { + if (typeof data.stack === 'string') { + data.stack = [ + data.stack.split(/\r\n|\n/).map((line, i) => { if (!i) { return line; } @@ -173,7 +233,7 @@ export default class Telemetry { return line; } - let m = line.match(/\(([^:)]*:)/); + let m: RegExpMatchArray | null = line.match(/\(([^:)]*:)/); // istanbul ignore if if (!m) { m = line.match(/at ([^:]*:)/); @@ -183,7 +243,7 @@ export default class Telemetry { } const filename = path.basename(m[1]); - let pkgDir = findDir(m[1], 'package.json'); + const pkgDir = findDir(m[1], 'package.json'); if (!pkgDir) { // no package.json @@ -197,11 +257,11 @@ export default class Telemetry { return line.replace(pkgDir, scrubbed); }).join('\n') ]; - } else if (payload.stack && !Array.isArray(payload.stack)) { - payload.stack = [ payload.stack ]; + } else if (data.stack && !Array.isArray(data.stack)) { + data.stack = [ data.stack ]; } - this.writeEvent('crash.report', payload); + this.writeEvent('crash.report', data as EventData); } /** @@ -211,7 +271,7 @@ export default class Telemetry { * @param {String} payload.event - The event name. * @access public */ - addEvent(payload) { + addEvent(payload: EventPayload) { if (isTelemetryDisabled()) { return; } @@ -220,14 +280,15 @@ export default class Telemetry { throw new TypeError('Expected telemetry payload to be an object'); } - const { event } = payload; - delete payload.event; + const data: EventData = { ...payload } as EventData; + const { event } = data; + delete data.event; if (!event || typeof event !== 'string') { throw new TypeError('Expected telemetry payload to have an event name'); } // write the event to disk - this.writeEvent(event, redact(payload, { + this.writeEvent(event, redact(data, { props: [ 'clientSecret', 'password', 'username' ], replacements: [ [ /\/.+\//, '//' ] @@ -242,7 +303,7 @@ export default class Telemetry { * @returns {Object} * @access private */ - initId(filename) { + initId(filename: string): { id: string, prev: string, ts: number | null } { const file = path.join(this.appDir, filename); let id, prev, ts; try { @@ -255,7 +316,7 @@ export default class Telemetry { prev = id; throw new Error(); } - } catch (err) { + } catch (err: any) { id = uuid.v4(); ts = null; } @@ -272,41 +333,67 @@ export default class Telemetry { * @returns {Promise} * @access public */ - async send(opts) { + async send(opts?: { wait?: boolean }): Promise { if (isTelemetryDisabled()) { return; } - const child = spawn(process.execPath, [ module.filename ], { + const script = path.join(path.dirname(path.dirname(__filename)), 'dist', 'telemetry.js'); + log(`Spawning: ${highlight(`${process.execPath} ${script}`)}`); + const child = spawn(process.execPath, [ script ], { stdio: [ 'pipe', 'pipe', 'pipe', 'ipc' ], windowsHide: true }); - const { pid } = child; - child.send({ - appDir: this.appDir, - requestOptions: this.requestOptions, - url: this.url, - wait: opts?.wait - }); - - if (opts?.wait) { - log(`Forked send process (pid: ${pid}), waiting for exit... `); - await new Promise(resolve => { - child.on('close', code => { - const debugLog = path.join(this.appDir, `debug-${pid}.log`); - if (fs.existsSync(debugLog)) { - logger(`send-${pid}`).log(fs.readFileSync(debugLog, 'utf-8').trim()); - fs.renameSync(debugLog, path.join(this.appDir, 'debug.log')); - } - log(`Send process ${pid} exited with code ${code} (${exitCodes[code] || 'Unknown'})`); + // block until the child process sends us the ready messager + await new Promise(resolve => { + const { pid } = child; + + const timer = setTimeout(() => { + child.kill(); + log(`Send process ${pid} timed out while waiting`); + resolve(); + }, 5000); + + const cleanup = (code: number) => { + log(`Send process ${pid} exited before being ready with code ${code} (${exitCodes[code] || 'Unknown'})`); + resolve(); + }; + child.once('close', cleanup); + + child.once('message', () => { + // child is ready, clear the timeout and close event + clearTimeout(timer); + child.removeListener('close', cleanup); + + const msg = { + appDir: this.appDir, + requestOptions: this.requestOptions, + url: this.url, + wait: !!opts?.wait + }; + + log(`Forked send process (pid: ${pid}) is ready, sending message:`, msg); + child.send(msg); + + if (opts?.wait) { + log(`Forked send process (pid: ${pid}), waiting for exit... `); + child.once('close', (code: number) => { + const debugLog = path.join(this.appDir, `debug-${pid}.log`); + if (fs.existsSync(debugLog)) { + logger(`send-${pid}`).log(fs.readFileSync(debugLog, 'utf-8').trim()); + fs.renameSync(debugLog, path.join(this.appDir, 'debug.log')); + } + log(`Send process ${pid} exited with code ${code} (${exitCodes[code] || 'Unknown'})`); + resolve(); + }); + } else { + log(`Forked send process (pid: ${pid}), unreferencing child process... `); + child.unref(); resolve(); - }); + } }); - } else { - log(`Forked send process (pid: ${pid}), unreferencing child process... `); - child.unref(); - } + }); } /** @@ -316,7 +403,7 @@ export default class Telemetry { * @param {Object} data - The event data payload. * @access private */ - writeEvent(event, data) { + writeEvent(event: string, data: EventData) { const id = uuid.v4(); const now = new Date(); const ts = `${now.toISOString().replace(/[\WZ]*/ig, '').replace('T', '-')}-${String(++this.count).padStart(4, '0')}`; @@ -339,16 +426,24 @@ export default class Telemetry { } } +interface TelemetryMessage { + appDir: string; + requestOptions?: RequestOptions; + url?: string; + wait?: boolean; +} + /** - * When Telemetry::send() is called, it spawns this file using `fork()` which conveniently creates - * an IPC tunnel. The parent then immediately sends this child process a message with the app dir - * and other info so that it can send the actual messages without blocking the parent. + * When Telemetry::send() is called, it spawns this file and sets up an IPC channel. The parent + * must wait for the child process to send a ready event before the parent sends this child process + * a message with the app dir and other info so that it can send the actual messages without + * blocking the parent. * * This child process will not exit until the IPC tunnel has been closed via process.disconnect(). * The only way to get output from this child process is to either set SNOOPLOGG=* and call * Telemetry::send({ wait: true }) -or- look in the app's telemetry data dir for the debug.log file. */ -process.on('message', async msg => { +process.on('message', async (msg: TelemetryMessage) => { // istanbul ignore if if (!msg || !msg.appDir || !isDir(msg.appDir)) { process.disconnect(); @@ -393,7 +488,7 @@ process.on('message', async msg => { writeFileSync(lockFile, String(process.pid), { flag: 'wx' }); log(`Attempt ${i}: Successfully acquired lock`); return true; - } catch (e) { + } catch (e: any) { const contents = fs.readFileSync(lockFile, 'utf-8').trim(); const pid = parseInt(contents, 10); @@ -407,7 +502,7 @@ process.on('message', async msg => { process.kill(pid, 0); log(`Attempt ${i}: Another send process (pid: ${pid}) is currently running`); return false; - } catch (e2) { + } catch (e2: any) { log(`Attempt ${i}: Lock file exists, but has stale pid, continuing...`); fs.removeSync(lockFile); } @@ -422,7 +517,7 @@ process.on('message', async msg => { }; if (!await acquireLock()) { - process.exitCode = exitCodes.ALREADY_RUNNING; + process.exitCode = CODE_ALREADY_RUNNING; return; } @@ -455,7 +550,7 @@ process.on('message', async msg => { if (batch.length >= sendBatchSize) { break; } - } catch (err) { + } catch (err: any) { warn(`Batch ${batchCounter}: Bad event ${filename}, deleting`); fs.removeSync(file); } @@ -468,8 +563,8 @@ process.on('message', async msg => { log(`Batch ${batchCounter}: Sending batch with ${batch.length} event${batch.length !== 1 ? 's' : ''}`); await got.post({ json: batch.map(b => b.event), - retry: 0, - timeout: 10000, + retry: { limit: 0 }, + timeout: { request: 10000 }, url }); log(`Batch ${batchCounter}: Successfully sent ${batch.length} event${batch.length !== 1 ? 's' : ''}`); @@ -479,14 +574,14 @@ process.on('message', async msg => { log(`Removing ${file}`); fs.removeSync(file); } - } catch (err) { + } catch (err: any) { // istanbul ignore next warn(err); } } - } catch (err) { + } catch (err: any) { error(err); - process.exitCode = exitCodes.ERROR; + process.exitCode = CODE_ERROR; } finally { fs.removeSync(lockFile); log(`Finished in ${((Date.now() - startTime) / 1000).toFixed(1)} seconds`); @@ -497,6 +592,13 @@ process.on('message', async msg => { } }); +/** + * If this script is being spawned as a child process, then tell the parent we're ready. + */ +if (process.connected && process.send) { + process.send('ready!'); +} + /** * Scans up the directory tree looking for a specific file. * @@ -504,7 +606,7 @@ process.on('message', async msg => { * @param {String} file - The filename to locate. * @returns {String} */ -function findDir(dir, file) { +function findDir(dir: string, file: string): string | undefined { const { root } = path.parse(dir); let cur = dir; let it; @@ -523,6 +625,6 @@ function findDir(dir, file) { * * @returns {Boolean} */ -function isTelemetryDisabled() { +function isTelemetryDisabled(): boolean { return process.env.AXWAY_TELEMETRY_DISABLED === '1' || (!process.env.AXWAY_TEST && ci.isCI); } diff --git a/packages/amplify-sdk/src/types.ts b/packages/amplify-sdk/src/types.ts new file mode 100644 index 00000000..a77caa9b --- /dev/null +++ b/packages/amplify-sdk/src/types.ts @@ -0,0 +1,342 @@ +import { + PlatformActivityChange, + PlatformActivityEvent, + PlatformEntitlement, + PlatformEntitlements, + PlatformOrgUsageMetric, + PlatformRole +} from './sdk/platform-types.js'; +import { Endpoints } from './endpoints.js'; +import { Got } from 'got'; +import TokenStore from './stores/token-store.js'; +import * as request from '@axway/amplify-request'; + +export interface Account { + auth: AccountAuthInfo, + default?: boolean, + hash: string, + isPlatform?: boolean, + isPlatformTooling?: boolean, + name: string, + org: Org, + orgs: OrgRef[], + role?: string, + roles?: string[], + sid?: string, + team?: Team, + user: User +} + +export interface AccountAuthInfo { + authenticator: string, + baseUrl: string, + clientId: string, + clientSecret?: string, + env: string, + expired?: boolean, + expires: { + access: number, + refresh: number | null + }, + idp?: string, + password?: string, + realm: string, + secret?: string, + tokens: { + access_token: string, + expires_in: number, + id_token: string, + refresh_expires_in: number, + refresh_token: string + }, + username?: string +} + +export type ActivityChange = PlatformActivityChange; + +export type ActivityEvent = PlatformActivityEvent; + +export interface ActivityParams { + from?: string, + month?: string, + org?: OrgLike, + to?: string, + userGuid?: string +} + +export interface ActivityResult { + events: ActivityEvent[], + from: Date, + org?: OrgRef, + to: Date +} + +export interface AmplifySDKOptions { + baseUrl?: string, + clientId?: string, + clientSecret?: string, + env?: string, + got?: Got, + onOpenBrowser?: (p: { url: string }) => void, + password?: string, + platformUrl?: string, + realm?: string, + requestOptions?: request.RequestOptions, + secretFile?: string, + tokenStoreType?: string, + username?: string +} + +export interface AuthenticatorOptions { + accessType?: string; + baseUrl?: string; + clientId: string; + endpoints?: Endpoints; + env?: string; + persistSecrets?: boolean; + got?: Got; + platformUrl: string; + realm: string; + responseType?: string; + scope?: string; + tokenStore: TokenStore; +} + +export interface Client { + client_id: string, + created: string, + description?: string, + guid: string, + method: string, + name: string, + org_guid: string, + roles: string[], + teams: ClientTeam[], + type: string +} + +export interface ClientRef { + client_id: string, + created: string, + guid: string, + method: string, + name: string, + org_guid: string, + roles: string[], + team_count: number, + type: string +} + +export interface ClientTeam { + desc?: string, + guid: string, + name?: string, + roles: string[] +} + +export interface ClientUpdateParams { + client: Client | string, + desc?: string, + name?: string, + publicKey?: string, + roles?: string[], + secret?: string, + teams?: ClientTeam[] +} + +export interface DefaultTeams { + [hash: string]: string +} + +export type Entitlement = PlatformEntitlement; + +export type Entitlements = PlatformEntitlements; + +export interface Environment { + guid?: string, + isProduction: boolean, + name: string +} + +export interface ManualLoginResult { + cancel: () => Promise, + promise: Promise, + url: string +} + +export interface Org extends OrgRef { + active?: boolean, + created?: string, + entitlements: Entitlements, + region: string, + insightUserCount?: number, + partners: { + [key: string]: OrgPartner + }, + seats?: number | null, + subscriptions: Subscription[], + teams: Team[], + teamCount?: number, + userCount?: number, + userRoles?: string[] +} + +export type OrgLike = Org | OrgRef | string | number; + +export interface OrgPartner { + provisioned: boolean +} + +export interface OrgRef { + default?: boolean, + guid: string, + name: string, + org_id: number, + role?: string +} + +export interface OrgUser { + client_id?: string, + email: string, + firstname?: string, + guid: string, + lastname?: string, + name: string, + primary: boolean, + roles: string[] +} + +export type Role = PlatformRole; + +export interface Subscription { + category: string, + edition: string, + endDate: string, // ISO date + expired: boolean, + governance: string, // 'SaaS' + startDate: string, // ISO date + tier: string +} + +export interface Team { + apps: string[], + created: string, // ISO date + default: boolean, + desc?: string, + guid: string, + name: string, + org_guid: string, + tags: string[], + users: TeamUser[] +} + +export interface TeamInfo { + default?: boolean, + desc?: string, + name?: string, + tags?: string[] +} + +export interface TeamInfoChanges { + [key: string]: { + v?: string | string[] | boolean, + p?: string | string[] | boolean + } +} + +export interface TeamUser { + client_id?: string, + email: string, + firstname?: string, + guid: string, + lastname?: string, + name: string + roles: string[], + type: 'client' | 'user' +} + +export interface User { + client_id?: string, + dateJoined?: string, // ISO date + email: string, + firstname: string, + guid: string, + lastname: string +} + +export interface UserChanges { + [key: string]: { + v?: string | string[] | boolean, + p?: string | string[] | boolean + } +} + +export interface UserInfo { + firstname?: string, + lastname?: string +} + +export interface UsageBundleMetric { + envs: { + [guid: string]: { + production: boolean, + quota: number, + tokens: number, + value: number + } + }, + name: string, + tokens: number, + unit: string, + value: number +} + +export type UsageParams = UsageParamsRange & UsageParamsMonth; + +export interface UsageParamsRange { + from: string, + to: string +} + +export interface UsageParamsMonth { + month: string | boolean +} + +export type UsageProductMetric = PlatformOrgUsageMetric; + +// note: this interface is identical to PlatformOrgUsage except `from` and `to` +// are Date objects instead of ISO strings +export interface UsageResult { + basis: string, // 'range' + bundle?: { + edition: string, + end_date: string, // ISO date + metrics?: { + [metric: string]: UsageBundleMetric + }, + name: string, + plan: string, // 'trial' + product: string, // 'Bundle' + ratios: { + [key: string]: number | boolean + }, + start_date: string // ISO date + }, + created: string, // ISO date + ending: string, // ISO date + from: Date + from_ts: number, + org_id: number, + to: Date + to_ts: number, + usage: { + [product: string]: { + name: string, + governance: { + [name: string]: { + [metric: string]: UsageProductMetric + } + } + } + } +} diff --git a/packages/amplify-sdk/src/util.js b/packages/amplify-sdk/src/util.js deleted file mode 100644 index 76d1be6d..00000000 --- a/packages/amplify-sdk/src/util.js +++ /dev/null @@ -1,39 +0,0 @@ -import crypto from 'crypto'; - -/** - * Appends query string parameters to a URL. - * - * @param {String} url - The URL. - * @param {Object} params - A map of query string parameters. - * @returns {String} - */ -export function createURL(url, params) { - return `${url}${url.includes('?') ? '&' : '?'}${prepareForm(params).toString()}`; -} - -/** - * Returns a hex encoded md5 hash of a string or object. - * - * @param {String|Object} it - The object to serialize and hash. - * @returns {String} - */ -export function md5(it) { - return crypto.createHash('md5').update(typeof it === 'string' ? it : JSON.stringify(it)).digest('hex'); -} - -/** - * Copies all params into a new object and converts camelcase property names to underscore case. - * - * @param {Object} params - The query string parameters to stringify. - * @returns {Object} - */ -export function prepareForm(params) { - const form = new URLSearchParams(); - for (const prop of Object.keys(params).sort()) { - if (params[prop] !== undefined) { - const name = prop.replace(/[A-Z]/g, (m, i) => `${i ? '_' : ''}${m.toLowerCase()}`); - form.append(name, params[prop]); - } - } - return form; -} diff --git a/packages/amplify-sdk/src/util.ts b/packages/amplify-sdk/src/util.ts new file mode 100644 index 00000000..de04bc88 --- /dev/null +++ b/packages/amplify-sdk/src/util.ts @@ -0,0 +1,123 @@ +import crypto from 'crypto'; +import E from './errors.js'; + +/** + * Appends query string parameters to a URL. + * + * @param {String} url - The URL. + * @param {Object} params - A map of query string parameters. + * @returns {String} + */ +export function createURL(url: string, params: { [key: string]: string | number | undefined }) { + return `${url}${url.includes('?') ? '&' : '?'}${prepareForm(params).toString()}`; +} + +/** + * Returns a hex encoded md5 hash of a string or object. + * + * @param {String|Object} it - The object to serialize and hash. + * @returns {String} + */ +export function md5(it: string | any) { + return crypto.createHash('md5').update(typeof it === 'string' ? it : JSON.stringify(it)).digest('hex'); +} + +/** + * Copies all params into a new object and converts camelcase property names to underscore case. + * + * @param {Object} params - The query string parameters to stringify. + * @returns {Object} + */ +export function prepareForm(params: { [key: string]: string | number | undefined }): URLSearchParams { + const form = new URLSearchParams(); + for (const prop of (Object.keys(params).sort() as string[])) { + if (params[prop] !== undefined) { + const name = prop.replace(/[A-Z]/g, (m, i) => `${i ? '_' : ''}${m.toLowerCase()}`); + form.append(name, String(params[prop])); + } + } + return form; +} + +export interface DateRange { + from: Date, + to: Date +} + +/** + * Takes two date strings in the format `YYYY-MM-DD` and returns them as date objects. + * + * @param {String} [from] - The range start date. + * @param {String} [to] - The range end date. + * @returns {Object} + */ +export function resolveDateRange(from?: string, to?: string): DateRange { + const r: DateRange = {} as DateRange; + const tsRE = /^\d{4}-\d{2}-\d{2}$/; + let ts; + + if (from) { + if (!tsRE.test(from) || isNaN(ts = Date.parse(`${from} 00:00:00 GMT`))) { + throw E.INVALID_ARGUMENT('Expected "from" date to be in the format YYYY-MM-DD'); + } + r.from = new Date(ts); + } else { + r.from = new Date(Date.now() - (14 * 24 * 60 * 60 * 1000)); // 14 days + } + + if (to) { + if (!tsRE.test(to) || isNaN(ts = Date.parse(`${to} 23:59:59 GMT`))) { + throw E.INVALID_ARGUMENT('Expected "to" date to be in the format YYYY-MM-DD'); + } + r.to = new Date(ts); + } else { + r.to = new Date(); + } + + return r; +} + +/** + * Determines the from and to date range for the specified month or month/year. + * + * @param {String|Number|Boolean} month - The month, year and month, or `""`/`true` for current + * month, to create a date range from. + * @return {Object} + */ +export function resolveMonthRange(month: string | number | boolean): { from: string, to: string } { + const now = new Date(); + let year = now.getUTCFullYear(); + let monthIdx = now.getUTCMonth(); + let monthInt = monthIdx + 1; + + if (typeof month === 'number') { + monthIdx = month - 1; + monthInt = month; + } else if (month !== true && month !== '') { + if (typeof month !== 'string') { + throw E.INVALID_ARGUMENT('Expected month to be in the format YYYY-MM or MM'); + } + + const m = month.match(/^(?:(\d{4})-)?(\d\d?)$/); + if (!m || !m[2]) { + throw E.INVALID_ARGUMENT('Expected month to be in the format YYYY-MM or MM'); + } + + if (m[1]) { + year = parseInt(m[1]); + } + monthInt = parseInt(m[2]); + monthIdx = monthInt - 1; + } + + const days = [ 31, year % 4 === 0 ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + if (!days[monthIdx]) { + throw E.INVALID_MONTH(`Invalid month "${monthInt}"`); + } + + const monthStr = String(monthIdx + 1).padStart(2, '0'); + return { + from: `${year}-${monthStr}-01`, + to: `${year}-${monthStr}-${days[monthIdx]}` + }; +} diff --git a/packages/amplify-sdk/test/common.js b/packages/amplify-sdk/test/common.ts similarity index 71% rename from packages/amplify-sdk/test/common.js rename to packages/amplify-sdk/test/common.ts index 8ea26566..8102ba29 100644 --- a/packages/amplify-sdk/test/common.js +++ b/packages/amplify-sdk/test/common.ts @@ -1,31 +1,45 @@ +/* eslint-disable security/detect-possible-timing-attacks */ + import bodyParser from 'koa-bodyparser'; import fs from 'fs-extra'; import http from 'http'; import jws from 'jws'; import Koa from 'koa'; +import net from 'net'; import path from 'path'; import Router from '@koa/router'; import session from 'koa-session'; import snooplogg from 'snooplogg'; -import { MemoryStore } from '../dist/index'; +import { Account } from '../src/types.js'; +import { fileURLToPath } from 'url'; +import { MemoryStore, TokenStore } from '../src/index.js'; import { v4 as uuidv4 } from 'uuid'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const { error, log } = snooplogg('test:amplify-auth:common'); const { highlight, note } = snooplogg.styles; -function createAPIRoutes(server, data) { +interface HttpTestServer extends http.Server { + accessToken?: string, + refreshToken?: string, + createTokenStore?: (opts: any) => { account: Account, tokenStore: TokenStore }, + destroy?: () => Promise +} + +function createAPIRoutes(server: any, data: any) { const router = new Router(); router.get('/v1/auth/findSession', async (ctx, next) => { - const { authorization } = ctx.req.headers; + const authorization: string | undefined = ctx.req.headers.authorization; const p = authorization ? authorization.indexOf(' ') : -1; - const token = p !== -1 ? authorization.substring(p + 1) : null; + const token = p !== -1 ? authorization?.substring(p + 1) : null; log(`Finding session using token "${token}" or cookie "${ctx.cookies.get('connect.sid')}"`); if (token === 'platform_access_token') { - const user = data.users.find(u => u.guid === '50000'); - const orgs = data.orgs.filter(o => o.users.find(u => u.guid === user.guid)); + const user = data.users.find((u: any) => u.guid === '50000'); + const orgs = data.orgs.filter((o: any) => o.users.find((u: any) => u.guid === user.guid)); ctx.body = { success: true, @@ -40,9 +54,9 @@ function createAPIRoutes(server, data) { success: true, result: null }; - } else if (ctx.session?.userGuid) { - const user = data.users.find(u => u.guid === ctx.session.userGuid); - const orgs = data.orgs.filter(o => o.users.find(u => u.guid === user.guid)); + } else if ((ctx.session as any).userGuid) { + const user = data.users.find((u: any) => u.guid === (ctx.session as any).userGuid); + const orgs = data.orgs.filter((o: any) => o.users.find((u: any) => u.guid === user.guid)); ctx.body = { success: true, @@ -60,9 +74,9 @@ function createAPIRoutes(server, data) { router.post('/v1/auth/login', async ctx => { const { username, password } = ctx.request.body; - const user = data.users.find(u => u.email === username); + const user = data.users.find((u: any) => u.email === username); if (user && password === 'bar') { - ctx.session.userGuid = user.guid; + (ctx.session as any).userGuid = user.guid; ctx.body = { success: true, result: user @@ -74,10 +88,13 @@ function createAPIRoutes(server, data) { }); router.get('/v1/activity', ctx => { - let { from, org_id, to, user_guid } = ctx.query; + const { from: fromStr, to: toStr } = ctx.query; + const { org_id, user_guid } = ctx.query; + let from: number; + let to: number; - if (from) { - from = Date.parse(from); + if (fromStr) { + from = Date.parse(fromStr as string); if (isNaN(from)) { ctx.status = 400; ctx.body = 'Bad from date'; @@ -87,8 +104,8 @@ function createAPIRoutes(server, data) { from = Date.now() - (14 * 24 * 60 * 60 * 1000); // 14 days } - if (to) { - to = Date.parse(to); + if (toStr) { + to = Date.parse(toStr as string); if (isNaN(to)) { ctx.status = 400; ctx.body = 'Bad to date'; @@ -100,26 +117,26 @@ function createAPIRoutes(server, data) { ctx.body = { success: true, - result: data.activity.filter(a => { - return a.ts >= from && - a.ts <= to && - (!org_id || String(a.org_id) === org_id) && - (!user_guid || a.user_guid === user_guid); + result: data.activity.filter((a: any) => { + return a.ts >= from + && a.ts <= to + && (!org_id || String(a.org_id) === org_id) + && (!user_guid || a.user_guid === user_guid); }) }; }); router.get('/v1/client', ctx => { const { org_id } = ctx.query; - const orgGuid = org_id && data.orgs.find(o => String(o.org_id) === org_id)?.guid || null; + const orgGuid = org_id && data.orgs.find((o: any) => String(o.org_id) === org_id)?.guid || null; ctx.body = { success: true, result: data.clients - .filter(c => { + .filter((c: any) => { return !orgGuid || c.org_guid === orgGuid; }) - .map(c => ({ + .map((c: any) => ({ client_id: c.client_id, guid: c.guid, name: c.name, @@ -130,7 +147,7 @@ function createAPIRoutes(server, data) { }); router.get('/v1/client/:id', ctx => { - const result = data.clients.find(c => c.client_id === ctx.params.id); + const result = data.clients.find((c: any) => c.client_id === ctx.params.id); if (result) { ctx.body = { success: true, @@ -140,7 +157,7 @@ function createAPIRoutes(server, data) { }); router.put('/v1/client/:guid', ctx => { - const idx = data.clients.findIndex(c => c.guid === ctx.params.guid); + const idx = data.clients.findIndex((c: any) => c.guid === ctx.params.guid); if (idx !== -1) { const result = data.clients[idx]; for (const key of [ 'name', 'description', 'publicKey', 'roles', 'secret' ]) { @@ -171,7 +188,7 @@ function createAPIRoutes(server, data) { }); router.delete('/v1/client/:id', ctx => { - const idx = data.clients.findIndex(c => c.client_id === ctx.params.id); + const idx = data.clients.findIndex((c: any) => c.client_id === ctx.params.id); if (idx !== -1) { const result = data.clients[idx]; @@ -215,11 +232,17 @@ function createAPIRoutes(server, data) { // add the user data.users.push({ guid: result.guid }); + const org = data.orgs.find((o: any) => o.guid === org_guid); + org.users.push({ + guid, + roles + }); + if (teams) { for (const team of teams) { - const info = data.teams.find(t => t.guid === team.guid); + const info = data.teams.find((t: any) => t.guid === team.guid); info.users.push({ - guid: result.guid, + guid, type: 'client', roles: team.roles }); @@ -259,30 +282,16 @@ function createAPIRoutes(server, data) { }; }); - router.get('/v1/org/:id/family', ctx => { - let org = data.orgs.find(o => String(o.org_id) === ctx.params.id); - if (org?.parent_org_guid) { - org = data.orgs.find(o => o.org_id === org.parent_org_guid); - } - if (org) { - ctx.body = { - success: true, - result: { - ...org, - children: org.children.map(c => data.orgs.find(o => o.guid === c)) - } - }; - } - }); - router.get('/v1/org/:id/usage', ctx => { const { id } = ctx.params; - const org = data.orgs.find(o => String(o.org_id) === id || o.guid === id); + const org = data.orgs.find((o: any) => String(o.org_id) === id || o.guid === id); if (org) { - let { from, to } = ctx.query; + const { from: fromStr, to: toStr } = ctx.query; + let from: number; + let to: number; - if (from) { - from = Date.parse(from); + if (fromStr) { + from = Date.parse(fromStr as string); if (isNaN(from)) { ctx.status = 400; ctx.body = 'Bad from date'; @@ -292,8 +301,8 @@ function createAPIRoutes(server, data) { from = Date.now() - (14 * 24 * 60 * 60 * 1000); // 14 days } - if (to) { - to = Date.parse(to); + if (toStr) { + to = Date.parse(toStr as string); if (isNaN(to)) { ctx.status = 400; ctx.body = 'Bad to date'; @@ -311,8 +320,8 @@ function createAPIRoutes(server, data) { containerPoints: { name: 'Container Points', unit: 'Points' }, eventRateMonth: { name: 'Analytics Events', unit: 'Events' } }; - const usage = data.usage.find(u => u.org_guid === org.guid); - const SaaS = {}; + const usage = data.usage.find((u: any) => u.org_guid === org.guid); + const SaaS: any = {}; for (const [ type, meta ] of Object.entries(types)) { SaaS[type] = { @@ -345,18 +354,30 @@ function createAPIRoutes(server, data) { }); router.get('/v1/org/:id/user', ctx => { - let org = data.orgs.find(o => String(o.org_id) === ctx.params.id); + const { clients } = ctx.query; + const org = data.orgs.find((o: any) => String(o.org_id) === ctx.params.id); if (org) { ctx.body = { success: true, - result: org.users.reduce((users, ou) => { - const user = data.users.find(u => u.guid === ou.guid); + result: org.users.reduce((users: any, ou: any) => { + const user = data.users.find((u: any) => u.guid === ou.guid); if (user) { users.push({ ...user, - ...ou + ...ou, + type: 'user' }); } + if (clients) { + const client = data.clients.find((c: any) => c.guid === ou.guid); + if (client) { + users.push({ + ...client, + ...ou, + type: 'client' + }); + } + } return users; }, []) }; @@ -364,10 +385,10 @@ function createAPIRoutes(server, data) { }); router.post('/v1/org/:id/user', ctx => { - let org = data.orgs.find(o => String(o.org_id) === ctx.params.id); + const org = data.orgs.find((o: any) => String(o.org_id) === ctx.params.id); if (org) { const { email, roles } = ctx.request.body; - const user = data.users.find(u => u.email === email || u.guid === email); + const user = data.users.find((u: any) => u.email === email || u.guid === email); if (!user) { ctx.status = 400; @@ -378,7 +399,7 @@ function createAPIRoutes(server, data) { return; } - if (org.users.find(u => u.guid === user.guid)) { + if (org.users.find((u: any) => u.guid === user.guid)) { ctx.status = 400; ctx.body = { success: false, @@ -391,7 +412,7 @@ function createAPIRoutes(server, data) { guid: user.guid, roles, primary: true - }) + }); ctx.body = { success: true, @@ -401,16 +422,16 @@ function createAPIRoutes(server, data) { }); router.delete('/v1/org/:id/user/:user_guid', ctx => { - let org = data.orgs.find(o => String(o.org_id) === ctx.params.id); + const org = data.orgs.find((o: any) => String(o.org_id) === ctx.params.id); if (org) { const { user_guid } = ctx.params; - const idx = org.users.findIndex(u => u.guid === user_guid); + const idx = org.users.findIndex((u: any) => u.guid === user_guid); if (idx === -1) { ctx.status = 400; ctx.body = { success: false, - message: `"user_guid" contained an invalid value.` + message: '"user_guid" contained an invalid value.' }; return; } @@ -425,16 +446,16 @@ function createAPIRoutes(server, data) { }); router.put('/v1/org/:id/user/:user_guid', ctx => { - let org = data.orgs.find(o => String(o.org_id) === ctx.params.id); + const org = data.orgs.find((o: any) => String(o.org_id) === ctx.params.id); if (org) { const { user_guid } = ctx.params; - const user = org.users.find(u => u.guid === user_guid); + const user = org.users.find((u: any) => u.guid === user_guid); if (!user) { ctx.status = 400; ctx.body = { success: false, - message: `"user_guid" contained an invalid value.` + message: '"user_guid" contained an invalid value.' }; return; } @@ -450,7 +471,7 @@ function createAPIRoutes(server, data) { router.get('/v1/org/:id', ctx => { const { id } = ctx.params; - const org = data.orgs.find(o => String(o.org_id) === id || o.guid === id); + const org = data.orgs.find((o: any) => String(o.org_id) === id || o.guid === id); if (org) { ctx.body = { success: true, @@ -461,7 +482,7 @@ function createAPIRoutes(server, data) { router.put('/v1/org/:id', ctx => { const { id } = ctx.params; - const org = data.orgs.find(o => String(o.org_id) === id || o.guid === id); + const org = data.orgs.find((o: any) => String(o.org_id) === id || o.guid === id); if (org) { org.name = ctx.request.body.name; ctx.body = { @@ -475,20 +496,20 @@ function createAPIRoutes(server, data) { const { team } = ctx.query; ctx.body = { success: true, - result: data.roles.filter(r => team ? r.team : r.org) + result: data.roles.filter((r: any) => team ? r.team : r.org) }; }); router.delete('/v1/team/:guid/user/:user_guid', ctx => { - const team = data.teams.find(t => t.guid === ctx.params.guid); + const team = data.teams.find((t: any) => t.guid === ctx.params.guid); if (team) { - const idx = team.users.findIndex(u => u.guid === ctx.params.user_guid); + const idx = team.users.findIndex((u: any) => u.guid === ctx.params.user_guid); if (idx === -1) { ctx.status = 400; ctx.body = { success: false, - message: `"user_guid" contained an invalid value.` + message: '"user_guid" contained an invalid value.' }; return; } @@ -503,9 +524,12 @@ function createAPIRoutes(server, data) { }); router.post('/v1/team/:guid/user/:user_guid', ctx => { - const team = data.teams.find(t => t.guid === ctx.params.guid); + const team = data.teams.find((t: any) => t.guid === ctx.params.guid); if (team) { - const user = data.users.find(u => u.guid === ctx.params.user_guid); + let user = data.users.find((u: any) => u.guid === ctx.params.user_guid); + if (!user) { + user = data.clients.find((c: any) => c.guid === ctx.params.user_guid); + } if (!user) { ctx.status = 400; @@ -516,7 +540,7 @@ function createAPIRoutes(server, data) { return; } - if (team.users.find(u => u.guid === user.guid)) { + if (team.users.find((u: any) => u.guid === user.guid)) { ctx.status = 400; ctx.body = { success: false, @@ -532,26 +556,27 @@ function createAPIRoutes(server, data) { team.users.push({ guid: user.guid, roles: ctx.request.body.roles, - primary: true - }) + primary: true, + type: user.client_id ? 'client' : 'user' + }); ctx.body = { success: true, - result: { guid: user.guid } + result: team }; } }); router.put('/v1/team/:guid/user/:user_guid', ctx => { - const team = data.teams.find(t => t.guid === ctx.params.guid); + const team = data.teams.find((t: any) => t.guid === ctx.params.guid); if (team) { - const user = team.users.find(u => u.guid === ctx.params.user_guid); + const user = team.users.find((u: any) => u.guid === ctx.params.user_guid); if (!user) { ctx.status = 400; ctx.body = { success: false, - message: `"user_guid" contained an invalid value.` + message: '"user_guid" contained an invalid value.' }; return; } @@ -566,7 +591,7 @@ function createAPIRoutes(server, data) { }); router.delete('/v1/team/:guid', ctx => { - const idx = data.teams.findIndex(t => t.guid === ctx.params.guid); + const idx = data.teams.findIndex((t: any) => t.guid === ctx.params.guid); if (idx !== -1) { data.teams.splice(idx, 1); ctx.body = { @@ -577,7 +602,7 @@ function createAPIRoutes(server, data) { }); router.get('/v1/team/:guid', ctx => { - const team = data.teams.find(t => t.guid === ctx.params.guid); + const team = data.teams.find((t: any) => t.guid === ctx.params.guid); if (team) { ctx.body = { success: true, @@ -587,7 +612,7 @@ function createAPIRoutes(server, data) { }); router.put('/v1/team/:guid', ctx => { - const team = data.teams.find(t => t.guid === ctx.params.guid); + const team = data.teams.find((t: any) => t.guid === ctx.params.guid); if (team) { const info = ctx.request.body; @@ -616,12 +641,12 @@ function createAPIRoutes(server, data) { const { name, org_id } = ctx.query; if (org_id) { - const org = data.orgs.find(o => String(o.org_id) === org_id); + const org = data.orgs.find((o: any) => String(o.org_id) === org_id); if (!org) { return; } - teams = teams.filter(t => t.org_guid === org.guid && - (!name || t.name.toLowerCase().includes(String(name).trim().toLowerCase()))); + teams = teams.filter((t: any) => t.org_guid === org.guid + && (!name || t.name.toLowerCase().includes(String(name).trim().toLowerCase()))); } ctx.body = { @@ -631,8 +656,8 @@ function createAPIRoutes(server, data) { }); router.post('/v1/team', ctx => { - const info = ctx.request.body - const org = data.orgs.find(o => o.guid === info.org_guid); + const info = ctx.request.body; + const org = data.orgs.find((o: any) => o.guid === info.org_guid); if (!org) { throw new Error('Org not found'); @@ -658,9 +683,9 @@ function createAPIRoutes(server, data) { router.put('/v1/user/profile/:id', ctx => { const { id } = ctx.params; - const user = data.users.find(u => u.guid === id); + const user = data.users.find((u: any) => u.guid === id); if (user) { - const { firstname, lastname, phone } = ctx.request.body; + const { firstname, lastname } = ctx.request.body; if (firstname) { user.firstname = firstname; @@ -668,9 +693,6 @@ function createAPIRoutes(server, data) { if (lastname) { user.lastname = lastname; } - if (phone) { - user.phone = phone; - } ctx.body = { success: true, @@ -681,7 +703,7 @@ function createAPIRoutes(server, data) { router.get('/v1/user/:id', ctx => { const { id } = ctx.params; - const user = data.users.find(u => u.guid === id); + const user = data.users.find((u: any) => u.guid === id || u.email === id); if (user) { ctx.body = { success: true, @@ -695,7 +717,7 @@ function createAPIRoutes(server, data) { if (term) { ctx.body = { success: true, - result: data.users.filter(u => u.email === term) + result: data.users.filter((u: any) => u.email === term) }; } }); @@ -703,9 +725,9 @@ function createAPIRoutes(server, data) { return router.routes(); } -function createAuthRoutes(server) { +function createAuthRoutes(server: HttpTestServer) { const router = new Router(); - let counter = 0; + const counter = 0; router.get('/realms/test_realm/protocol/openid-connect/userinfo', ctx => { ctx.body = { @@ -749,19 +771,19 @@ function createAuthRoutes(server) { }); router.get('/realms/test_realm/.well-known/openid-configuration', ctx => { - ctx.body = JSON.parse(fs.readFileSync(path.join(__dirname, 'server-info.json'))); + ctx.body = JSON.parse(fs.readFileSync(path.join(__dirname, 'server-info.json'), 'utf8')); }); return router.routes(); } -export function createServer(opts = {}) { +export function createServer(): Promise { return new Promise((resolve, reject) => { - const connections = {}; - const data = JSON.parse(fs.readFileSync(path.join(__dirname, 'data.json'))); + const connections: { [key: string]: net.Socket } = {}; + const data = JSON.parse(fs.readFileSync(path.join(__dirname, 'data.json'), 'utf8')); const router = new Router(); const app = new Koa(); - const sessions = {}; + const sessions: any = {}; app.keys = [ 'a', 'b' ]; app.use(bodyParser()); @@ -787,7 +809,7 @@ export function createServer(opts = {}) { }); app.use(router.routes()); - const server = app + const server: HttpTestServer = app .listen(1337, '127.0.0.1') .on('connection', conn => { const key = conn.remoteAddress + ':' + conn.remotePort; @@ -805,7 +827,7 @@ export function createServer(opts = {}) { .on('error', reject); router.use('/api', createAPIRoutes(server, data)); - router.use('/auth', createAuthRoutes(server, data)); + router.use('/auth', createAuthRoutes(server)); router.get([ '/', '/success' ], ctx => { ctx.body = ` @@ -826,9 +848,9 @@ export function createServer(opts = {}) { `; }); - server.createTokenStore = (opts = {}) => { - const user = data.users.find(u => u.guid === (opts.userGuid || '50000')); - const orgs = data.orgs.filter(o => o.users.find(u => u.guid === user.guid)); + server.createTokenStore = (opts = {}): { account: Account, tokenStore: TokenStore } => { + const user = data.users.find((u: any) => u.guid === (opts.userGuid || '50000')); + const orgs = data.orgs.filter((o: any) => o.users.find((u: any) => u.guid === user.guid)); const account = JSON.parse(JSON.stringify({ auth: { baseUrl: 'http://127.0.0.1:1337', @@ -845,12 +867,7 @@ export function createServer(opts = {}) { }, name: 'test_client:foo@bar.com', org: orgs[0], - orgs: orgs.map(o => { - const r = { ...o }; - r.id = r.org_id; - delete r.org_id; - return r; - }), + orgs, user })); @@ -878,20 +895,26 @@ export function createServer(opts = {}) { }); } -export async function createLoginServer(opts = {}) { +export async function createLoginServer(opts: any = {}): Promise { let counter = 0; - const handler = opts.handler || (async (req, res) => { + const handler = opts.handler || (async (req: http.IncomingMessage, res: http.ServerResponse) => { try { - const url = new URL(req.url, 'http://127.0.0.1:1337'); + const url = new URL(req.url as string, 'http://127.0.0.1:1337'); let post = {}; if (req.method === 'POST') { post = await new Promise((resolve, reject) => { - const body = []; - req.on('data', chunk => body.push(chunk)); + const body: Buffer[] = []; + req.on('data', (chunk: Buffer) => body.push(chunk)); req.on('error', reject); - req.on('end', () => resolve(Array.from(new URLSearchParams(Buffer.concat(body).toString()).entries()).reduce((p, [k,v]) => (p[k]=v,p), {}))); + req.on('end', () => { + const params = new URLSearchParams(Buffer.concat(body).toString()).entries(); + resolve(Array.from(params).reduce((p, [ k, v ]) => { + p[k] = v; + return p; + }, {} as any)); + }); }); } @@ -969,7 +992,7 @@ export async function createLoginServer(opts = {}) { } res.writeHead(200, { 'Content-Type': 'application/json' }); - res.end(fs.readFileSync(path.join(__dirname, 'server-info.json'), 'utf-8')); + res.end(fs.readFileSync(path.join(__dirname, 'server-info.json'), 'utf8')); break; case '/': @@ -994,20 +1017,20 @@ export async function createLoginServer(opts = {}) { `); break; } - } catch (e) { + } catch (e: any) { error(e); res.writeHead(400, { 'Content-Type': 'text/plain' }); res.end(e.toString()); } }); - const server = http.createServer(handler); - const connections = {}; + const server: HttpTestServer = http.createServer(handler) as HttpTestServer; + const connections: { [key: string]: net.Socket } = {}; - server.destroy = () => { - return Promise.all([ - new Promise(resolve => server.close(resolve)), - new Promise(resolve => { + server.destroy = async (): Promise => { + await Promise.all([ + new Promise(resolve => server.close(() => resolve())), + new Promise(resolve => { for (const conn of Object.values(connections)) { conn.destroy(); } @@ -1035,15 +1058,15 @@ export async function createLoginServer(opts = {}) { return server; } -export async function createTelemetryServer(opts = {}) { - const server = http.createServer(async (req, res) => { +export async function createTelemetryServer(opts: any = {}) { + const server: HttpTestServer = http.createServer(async (req: http.IncomingMessage, res: http.ServerResponse) => { try { - const url = new URL(req.url, 'http://127.0.0.1:13372'); + const url = new URL(req.url as string, 'http://127.0.0.1:13372'); log(`Incoming request: ${req.method} ${highlight(url.pathname)}`); if (req.method === 'POST') { const post = await new Promise((resolve, reject) => { - const body = []; + const body: Buffer[] = []; req.on('data', chunk => body.push(chunk)); req.on('error', reject); req.on('end', () => resolve(JSON.parse(Buffer.concat(body).toString()))); @@ -1059,17 +1082,17 @@ export async function createTelemetryServer(opts = {}) { break; } } - } catch (e) { + } catch (e: any) { res.writeHead(400, { 'Content-Type': 'text/plain' }); res.end(e.toString()); } }); - const connections = {}; + const connections: { [key: string]: net.Socket } = {}; - server.destroy = () => { - return Promise.all([ - new Promise(resolve => server.close(resolve)), - new Promise(resolve => { + server.destroy = async (): Promise => { + await Promise.all([ + new Promise(resolve => server.close(() => resolve())), + new Promise(resolve => { for (const conn of Object.values(connections)) { conn.destroy(); } @@ -1096,7 +1119,7 @@ export async function createTelemetryServer(opts = {}) { return server; } -export async function stopServer() { +export async function stopServer(this: Mocha.Context) { this.timeout(5000); // we need to wait 1 second because after logging in, the browser is redirect to platform and diff --git a/packages/amplify-sdk/test/data.json b/packages/amplify-sdk/test/data.json index 188cd1f9..805a9e31 100644 --- a/packages/amplify-sdk/test/data.json +++ b/packages/amplify-sdk/test/data.json @@ -64,6 +64,10 @@ "guid": "50001", "roles": [ "developer" ], "primary": true + }, + { + "guid": "629e1705-9cd7-4db7-9dfe-08aa47b0f3ad", + "roles": [ "developer" ] } ], "entitlements": { @@ -137,12 +141,13 @@ "users": [ { "guid": "50000", - "roles": [ "administrator" ] + "roles": [ "administrator" ], + "type": "user" }, { "guid": "629e1705-9cd7-4db7-9dfe-08aa47b0f3ad", - "type": "client", - "roles": [ "developer" ] + "roles": [ "developer" ], + "type": "client" } ] }, @@ -155,7 +160,8 @@ "users": [ { "guid": "50000", - "roles": [ "administrator" ] + "roles": [ "administrator" ], + "type": "user" } ] }, @@ -168,7 +174,8 @@ "users": [ { "guid": "50000", - "roles": [ "administrator" ] + "roles": [ "administrator" ], + "type": "user" } ] } @@ -218,24 +225,21 @@ "email": "test1@domain.com", "firstname": "Test1", "lastname": "Tester1", - "phone": "555-5001" + "name": "Test1 Tester1" }, { "guid": "50001", "email": "test2@domain.com", "firstname": "Test2", "lastname": "Tester2", - "phone": "555-5002" + "name": "Test2 Tester2" }, { "guid": "50002", "email": "test3@domain.com", "firstname": "Test3", "lastname": "Tester3", - "phone": "555-5003" - }, - { - "guid": "629e1705-9cd7-4db7-9dfe-08aa47b0f3ad" + "name": "Test3 Tester3" } ] } diff --git a/packages/amplify-sdk/test/test-auth.js b/packages/amplify-sdk/test/test-auth.ts similarity index 82% rename from packages/amplify-sdk/test/test-auth.js rename to packages/amplify-sdk/test/test-auth.ts index b7ed481d..94dc65eb 100644 --- a/packages/amplify-sdk/test/test-auth.js +++ b/packages/amplify-sdk/test/test-auth.ts @@ -1,19 +1,26 @@ -import { Auth } from '../dist/index'; -import { createLoginServer, stopLoginServer } from './common'; -import serverInfo from './server-info.json'; +import fs from 'fs'; +import http from 'http'; +import path from 'path'; import tmp from 'tmp'; +import { Auth } from '../src/index.js'; +import { createLoginServer, stopLoginServer } from './common.js'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; tmp.setGracefulCleanup(); const homeDir = tmp.tmpNameSync({ prefix: 'test-amplify-sdk-' }); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const serverInfo = JSON.parse(fs.readFileSync(path.join(__dirname, '/server-info.json'), 'utf8')); + describe('Auth', () => { describe('Constructor', () => { afterEach(stopLoginServer); it('should error if options is not an object', () => { expect(() => { - new Auth('foo'); + new Auth('foo' as any); }).to.throw(TypeError, 'Expected options to be an object'); }); @@ -24,7 +31,7 @@ describe('Auth', () => { expect(() => { new Auth({ homeDir, - tokenRefreshThreshold: 'foo', + tokenRefreshThreshold: 'foo' as any, tokenStoreType: 'memory' }); }).to.throw(TypeError, 'Expected token refresh threshold to be a number of seconds'); @@ -53,7 +60,7 @@ describe('Auth', () => { baseUrl: 'http://127.0.0.1:1337', clientId: 'test_client', realm: 'test_realm', - tokenStore: 'foo', + tokenStore: 'foo' as any, tokenStoreType: null }); }).to.throw(TypeError, 'Expected the token store to be a "TokenStore" instance'); @@ -84,7 +91,7 @@ describe('Auth', () => { it('should throw error if server returns error', async function () { this.server = await createLoginServer({ - serverinfo(post, req, res) { + serverinfo(post: any, req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(500); res.end('Server error'); return true; @@ -100,7 +107,7 @@ describe('Auth', () => { it('should throw error if server response is invalid', async function () { this.server = await createLoginServer({ - serverinfo(post, req, res) { + serverinfo(post: any, req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(200); res.end('{{{{{{{{{{'); return true; @@ -127,7 +134,7 @@ describe('Auth', () => { const auth = new Auth({ tokenStoreType: null }); - const revoked = await auth.logout(); + const revoked = await auth.logout(undefined as any); expect(revoked).to.have.lengthOf(0); }); @@ -137,8 +144,8 @@ describe('Auth', () => { }); try { - await auth.logout(); - } catch (err) { + await auth.logout(undefined as any); + } catch (err: any) { expect(err).to.be.instanceof(Error); expect(err.message).to.equal('Expected accounts to be a list of accounts'); return; diff --git a/packages/amplify-sdk/test/test-authenticator.js b/packages/amplify-sdk/test/test-authenticator.ts similarity index 91% rename from packages/amplify-sdk/test/test-authenticator.js rename to packages/amplify-sdk/test/test-authenticator.ts index 64434a24..e8a0e1ab 100644 --- a/packages/amplify-sdk/test/test-authenticator.js +++ b/packages/amplify-sdk/test/test-authenticator.ts @@ -1,16 +1,17 @@ -import { Authenticator } from '../dist/index'; +import { Authenticator } from '../src/index.js'; +import { expect } from 'chai'; describe('Authenticator', () => { describe('Constructor', () => { it('should error if options is invalid', () => { expect(() => { - new Authenticator('foo'); + new Authenticator('foo' as any); }).to.throw(TypeError, 'Expected options to be an object'); }); it('should error if base URL is not specified', () => { expect(() => { - new Authenticator({}); + new Authenticator({} as any); }).to.throw(Error, 'Invalid base URL: env or baseUrl required'); }); @@ -18,7 +19,7 @@ describe('Authenticator', () => { expect(() => { new Authenticator({ baseUrl: 123 - }); + } as any); }).to.throw(Error, 'Invalid base URL: env or baseUrl required'); }); @@ -26,14 +27,14 @@ describe('Authenticator', () => { expect(() => { new Authenticator({ baseUrl: 'http://127.0.0.1:1337' - }); + } as any); }).to.throw(TypeError, 'Expected required parameter "clientId" to be a non-empty string'); expect(() => { new Authenticator({ baseUrl: 'http://127.0.0.1:1337', clientId: '' - }); + } as any); }).to.throw(TypeError, 'Expected required parameter "clientId" to be a non-empty string'); }); @@ -44,7 +45,7 @@ describe('Authenticator', () => { clientId: 'test_client', realm: 'test_realm', accessType: 123 - }); + } as any); }).to.throw(TypeError, 'Expected parameter "accessType" to be a string'); }); @@ -55,7 +56,7 @@ describe('Authenticator', () => { clientId: 'test_client', realm: 'test_realm', responseType: 123 - }); + } as any); }).to.throw(TypeError, 'Expected parameter "responseType" to be a string'); }); @@ -66,7 +67,7 @@ describe('Authenticator', () => { clientId: 'test_client', realm: 'test_realm', scope: 123 - }); + } as any); }).to.throw(TypeError, 'Expected parameter "scope" to be a string'); }); @@ -80,7 +81,7 @@ describe('Authenticator', () => { endpoints: { auth: '' } - }); + } as any); }).to.throw(TypeError, 'Expected "auth" endpoint URL to be a non-empty string'); }); @@ -94,7 +95,7 @@ describe('Authenticator', () => { endpoints: { foo: 'bar' } - }); + } as any); }).to.throw(Error, 'Invalid endpoint "foo"'); }); @@ -106,7 +107,7 @@ describe('Authenticator', () => { endpoints: { auth: 'bar' } - }); + } as any); expect(auth.endpoints.auth).to.equal('bar'); }); @@ -118,7 +119,7 @@ describe('Authenticator', () => { clientId: 'test_client', realm: 'test_realm', tokenStore: 'foo' - }); + } as any); }).to.throw(TypeError, 'Expected the token store to be a "TokenStore" instance'); expect(() => { @@ -127,7 +128,7 @@ describe('Authenticator', () => { clientId: 'test_client', realm: 'test_realm', tokenStore: {} - }); + } as any); }).to.throw(TypeError, 'Expected the token store to be a "TokenStore" instance'); }); }); diff --git a/packages/amplify-sdk/test/test-client-secret.js b/packages/amplify-sdk/test/test-client-secret.ts similarity index 90% rename from packages/amplify-sdk/test/test-client-secret.js rename to packages/amplify-sdk/test/test-client-secret.ts index eade67e2..7971d3ad 100644 --- a/packages/amplify-sdk/test/test-client-secret.js +++ b/packages/amplify-sdk/test/test-client-secret.ts @@ -1,7 +1,10 @@ /* eslint-disable max-len */ -import { Auth, Authenticator, ClientSecret } from '../dist/index'; -import { createLoginServer, stopLoginServer } from './common'; +import http from 'http'; +import { Account } from '../src/types.js'; +import { Auth, Authenticator, ClientSecret } from '../src/index.js'; +import { createLoginServer, stopLoginServer } from './common.js'; +import { expect } from 'chai'; const isCI = process.env.CI || process.env.JENKINS; @@ -15,15 +18,15 @@ describe('Client Secret', () => { it('should error if client secret is invalid', () => { expect(() => { - new ClientSecret({}); + new ClientSecret({} as any); }).to.throw(TypeError, 'Expected client secret to be a non-empty string'); expect(() => { - new ClientSecret({ clientSecret: null }); + new ClientSecret({ clientSecret: null } as any); }).to.throw(TypeError, 'Expected client secret to be a non-empty string'); expect(() => { - new ClientSecret({ clientSecret: '' }); + new ClientSecret({ clientSecret: '' } as any); }).to.throw(TypeError, 'Expected client secret to be a non-empty string'); }); }); @@ -46,7 +49,7 @@ describe('Client Secret', () => { it('should error if code is incorrect', async function () { this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(401, { 'Content-Type': 'text/plain' }); res.end('Unauthorized'); } @@ -83,7 +86,7 @@ describe('Client Secret', () => { it('should error if server returns invalid user identity', async function () { this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ // no access token! @@ -122,7 +125,7 @@ describe('Client Secret', () => { tokenStoreType: 'memory' }); - const account = await auth.login(); + const account: Account = await auth.login() as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.name).to.equal('test_client:foo@bar.com'); }); @@ -135,7 +138,7 @@ describe('Client Secret', () => { this.server = await createLoginServer({ expiresIn: 1, - token: post => { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.ClientCredentials); @@ -160,12 +163,12 @@ describe('Client Secret', () => { tokenStoreType: 'memory' }); - let account = await auth.login(); + let account: Account = await auth.login() as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); await new Promise(resolve => setTimeout(resolve, 1200)); - account = await auth.login(); + account = await auth.login() as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); }); }); @@ -183,7 +186,7 @@ describe('Client Secret', () => { tokenStoreType: 'memory' }); - await expect(auth.login('foo')) + await expect(auth.login('foo' as any)) .to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); }); @@ -205,7 +208,7 @@ describe('Client Secret', () => { it('should error if server returns invalid user identity', async function () { this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ // no access token! @@ -256,7 +259,7 @@ describe('Client Secret', () => { tokenStoreType: 'memory' }); - const account = await auth.login(); + const account: Account = await auth.login() as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.name).to.equal('test_client:foo@bar.com'); }); @@ -269,7 +272,7 @@ describe('Client Secret', () => { this.server = await createLoginServer({ expiresIn: 1, - token: post => { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.ClientCredentials); @@ -293,12 +296,12 @@ describe('Client Secret', () => { tokenStoreType: 'memory' }); - let results = await auth.login(); + let results: Account = await auth.login() as Account; expect(results.auth.tokens.access_token).to.equal(this.server.accessToken); await new Promise(resolve => setTimeout(resolve, 1200)); - results = await auth.login(); + results = await auth.login() as Account; expect(results.auth.tokens.access_token).to.equal(this.server.accessToken); }); }); @@ -310,7 +313,7 @@ describe('Client Secret', () => { let counter = 0; this.server = await createLoginServer({ - token: post => { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.ClientCredentials); @@ -335,7 +338,7 @@ describe('Client Secret', () => { tokenStoreType: 'memory' }); - const account = await auth.login(); + const account: Account = await auth.login() as Account; expect(account.name).to.equal('test_client:foo@bar.com'); const revoked = await auth.logout({ accounts: account.name }); diff --git a/packages/amplify-sdk/test/test-endpoints.js b/packages/amplify-sdk/test/test-endpoints.ts similarity index 93% rename from packages/amplify-sdk/test/test-endpoints.js rename to packages/amplify-sdk/test/test-endpoints.ts index c6a43eb3..463a0758 100644 --- a/packages/amplify-sdk/test/test-endpoints.js +++ b/packages/amplify-sdk/test/test-endpoints.ts @@ -1,4 +1,5 @@ -import { getEndpoints } from '../dist/index'; +import { getEndpoints } from '../src/index.js'; +import { expect } from 'chai'; describe('Endpoints', () => { it('should error setting endpoints if baseUrl is invalid', () => { @@ -18,7 +19,7 @@ describe('Endpoints', () => { expect(() => { getEndpoints({ - baseUrl: 123 + baseUrl: 123 as any }); }).to.throw(TypeError, 'Expected baseUrl to be a non-empty string'); }); @@ -40,7 +41,7 @@ describe('Endpoints', () => { expect(() => { getEndpoints({ baseUrl: 'http://localhost/', - realm: 123 + realm: 123 as any }); }).to.throw(TypeError, 'Expected realm to be a non-empty string'); }); diff --git a/packages/amplify-sdk/test/test-owner-password.js b/packages/amplify-sdk/test/test-owner-password.ts similarity index 85% rename from packages/amplify-sdk/test/test-owner-password.js rename to packages/amplify-sdk/test/test-owner-password.ts index 49f05f8f..a394406d 100644 --- a/packages/amplify-sdk/test/test-owner-password.js +++ b/packages/amplify-sdk/test/test-owner-password.ts @@ -1,38 +1,41 @@ /* eslint-disable no-unused-expressions */ +import http from 'http'; import tmp from 'tmp'; -import { Auth, Authenticator, MemoryStore, OwnerPassword } from '../dist/index'; -import { createLoginServer, stopLoginServer } from './common'; +import { Account } from '../src/types.js'; +import { Auth, Authenticator, MemoryStore, OwnerPassword } from '../src/index.js'; +import { createLoginServer, stopLoginServer } from './common.js'; +import { expect } from 'chai'; describe('Owner Password', () => { describe('Constructor', () => { it('should error if options is invalid', () => { expect(() => { - new OwnerPassword(); + new OwnerPassword(undefined as any); }).to.throw(TypeError, 'Expected options to be an object'); }); it('should error if username is invalid', () => { expect(() => { - new OwnerPassword({}); + new OwnerPassword({} as any); }).to.throw(TypeError, 'Expected username to be a non-empty string'); expect(() => { - new OwnerPassword({ username: null }); + new OwnerPassword({ username: null } as any); }).to.throw(TypeError, 'Expected username to be a non-empty string'); expect(() => { - new OwnerPassword({ username: '' }); + new OwnerPassword({ username: '' } as any); }).to.throw(TypeError, 'Expected username to be a non-empty string'); }); it('should error if password is invalid', () => { expect(() => { - new OwnerPassword({ username: 'foo' }); + new OwnerPassword({ username: 'foo' } as any); }).to.throw(TypeError, 'Expected password to be a string'); expect(() => { - new OwnerPassword({ username: 'foo', password: null }); + new OwnerPassword({ username: 'foo', password: null } as any); }).to.throw(TypeError, 'Expected password to be a string'); }); }); @@ -49,8 +52,8 @@ describe('Owner Password', () => { }); try { - await auth.login('foo'); - } catch (err) { + await auth.login('foo' as any); + } catch (err: any) { expect(err).to.be.instanceof(TypeError); expect(err.message).to.equal('Expected options to be an object'); return; @@ -74,7 +77,7 @@ describe('Owner Password', () => { username: 'foo', password: 'bar' }); - } catch (e) { + } catch (e: any) { expect(e).to.be.instanceof(Error); expect(e.message).to.match(/connect ECONNREFUSED 127.0.0.1:133/i); expect(e.code).to.equal('ECONNREFUSED'); @@ -86,7 +89,7 @@ describe('Owner Password', () => { it('should error if username/password is incorrect', async function () { this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(401, { 'Content-Type': 'text/plain' }); res.end('Unauthorized'); } @@ -104,7 +107,7 @@ describe('Owner Password', () => { username: 'foo', password: 'bar' }); - } catch (e) { + } catch (e: any) { expect(e).to.be.instanceof(Error); expect(e.message).to.equal('Authentication failed: Response code 401 (Unauthorized)'); return; @@ -123,10 +126,10 @@ describe('Owner Password', () => { tokenStoreType: null }); - const account = await auth.login({ + const account: Account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.name).to.equal('test_client:foo@bar.com'); expect(account.auth.expired).to.be.false; @@ -140,7 +143,7 @@ describe('Owner Password', () => { this.server = await createLoginServer({ expiresIn: 1, - token(post) { + token(post: any) { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.Password); @@ -164,10 +167,10 @@ describe('Owner Password', () => { tokenStoreType: 'file' }); - let account = await auth.login({ + let account: Account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; const { accessToken } = this.server; expect(account.auth.tokens.access_token).to.equal(accessToken); expect(account.auth.expired).to.be.false; @@ -179,7 +182,7 @@ describe('Owner Password', () => { account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(account.auth.tokens.access_token).to.not.equal(accessToken); expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.auth.expired).to.be.false; @@ -187,7 +190,7 @@ describe('Owner Password', () => { it('should handle bad user info response', async function () { this.server = await createLoginServer({ - userinfo(post, req, res) { + userinfo(post: any, req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('{{{{{{'); return true; @@ -203,10 +206,10 @@ describe('Owner Password', () => { tokenStoreType: null }); - const account = await auth.login({ + const account: Account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(account.auth.tokens.access_token).to.not.equal(accessToken); }); }); @@ -238,12 +241,12 @@ describe('Owner Password', () => { tokenStoreType: 'file' }); - let results = await auth.login({ + const results: Account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; - const account = await auth.find({ accountName: 'test_client:foo@bar.com' }); + const account: Account = await auth.find({ accountName: 'test_client:foo@bar.com' }) as Account; expect(account).to.be.ok; expect(account.name).to.equal(`test_client:${results.user.email}`); expect(account.auth.expired).to.be.false; @@ -258,7 +261,7 @@ describe('Owner Password', () => { this.server = await createLoginServer({ expiresIn: 10, - token(post) { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.Password); @@ -284,7 +287,7 @@ describe('Owner Password', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(account.name).to.equal('test_client:foo@bar.com'); expect(account.auth.expired).to.be.false; @@ -298,7 +301,7 @@ describe('Owner Password', () => { this.server = await createLoginServer({ expiresIn: 10, - token(post) { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.Password); @@ -324,7 +327,7 @@ describe('Owner Password', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(account.name).to.equal('test_client:foo@bar.com'); expect(account.auth.expired).to.be.false; @@ -344,14 +347,14 @@ describe('Owner Password', () => { }); class Foo extends MemoryStore { - async clear(...args) { + async clear(baseUrl: string) { deleteCounter++; - return await super.clear(...args); + return await super.clear(baseUrl); } - async delete(...args) { + async delete(accounts: string | string[], baseUrl?: string) { deleteCounter++; - return await super.delete(...args); + return await super.delete(accounts, baseUrl); } } @@ -379,14 +382,14 @@ describe('Owner Password', () => { }); class Foo extends MemoryStore { - async clear(...args) { + async clear(baseUrl: string) { deleteCounter++; - return await super.clear(...args); + return await super.clear(baseUrl); } - async delete(...args) { + async delete(accounts: string | string[], baseUrl?: string) { deleteCounter++; - return await super.delete(...args); + return await super.delete(accounts, baseUrl); } } diff --git a/packages/amplify-sdk/test/test-pkce.js b/packages/amplify-sdk/test/test-pkce.ts similarity index 87% rename from packages/amplify-sdk/test/test-pkce.js rename to packages/amplify-sdk/test/test-pkce.ts index 54d00108..36f90059 100644 --- a/packages/amplify-sdk/test/test-pkce.js +++ b/packages/amplify-sdk/test/test-pkce.ts @@ -1,7 +1,10 @@ /* eslint-disable max-len */ -import { Auth, Authenticator } from '../dist/index'; -import { createLoginServer, stopLoginServer } from './common'; +import http from 'http'; +import { Account, ManualLoginResult } from '../src/types.js'; +import { Auth, Authenticator } from '../src/index.js'; +import { createLoginServer, stopLoginServer } from './common.js'; +import { expect } from 'chai'; const isCI = process.env.CI || process.env.JENKINS; @@ -17,7 +20,7 @@ describe('PKCE', () => { tokenStoreType: null }); - await expect(auth.login('foo')) + await expect(auth.login('foo' as any)) .to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); }); @@ -29,7 +32,7 @@ describe('PKCE', () => { tokenStoreType: null }); - const { cancel, url } = await auth.login({ manual: true }); + const { cancel, url }: ManualLoginResult = await auth.login({ manual: true }) as ManualLoginResult; await cancel(); expect(url).to.match(/^http:\/\/127\.0\.0\.1:1337\/auth\/realms\/test_realm\/protocol\/openid-connect\/auth\?access_type=offline&client_id=test_client&code_challenge=.+&code_challenge_method=S256&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A\d+%2Fcallback%2F.+&response_type=code&scope=openid$/); }); @@ -48,7 +51,7 @@ describe('PKCE', () => { it('should error if code is incorrect', async function () { this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(401, { 'Content-Type': 'text/plain' }); res.end('Unauthorized'); } @@ -83,7 +86,7 @@ describe('PKCE', () => { let counter = 0; this.server = await createLoginServer({ - token(post) { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.AuthorizationCode); @@ -104,7 +107,7 @@ describe('PKCE', () => { tokenStoreType: null }); - const account = await auth.login({ code: 'foo' }); + const account: Account = await auth.login({ code: 'foo' }) as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); }); @@ -124,7 +127,7 @@ describe('PKCE', () => { it('should error if server returns invalid user identity', async function () { this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ // no access token! @@ -158,7 +161,7 @@ describe('PKCE', () => { tokenStoreType: null }); - const account = await auth.login(); + const account: Account = await auth.login() as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.name).to.equal('test_client:foo@bar.com'); }); @@ -169,7 +172,7 @@ describe('PKCE', () => { this.server = await createLoginServer({ expiresIn: 1, - token(post) { + token(post: any) { expect(post.grant_type).to.equal(Authenticator.GrantTypes.AuthorizationCode); } }); @@ -181,12 +184,12 @@ describe('PKCE', () => { tokenStoreType: 'memory' }); - let results = await auth.login({ code: 'foo' }); + let results: Account = await auth.login({ code: 'foo' }) as Account; expect(results.auth.tokens.access_token).to.equal(this.server.accessToken); await new Promise(resolve => setTimeout(resolve, 1200)); - results = await auth.login({ code: 'foo' }); + results = await auth.login({ code: 'foo' }) as Account; expect(results.auth.tokens.access_token).to.equal(this.server.accessToken); }); @@ -216,7 +219,7 @@ describe('PKCE', () => { let counter = 0; this.server = await createLoginServer({ - token(post) { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.AuthorizationCode); @@ -237,8 +240,8 @@ describe('PKCE', () => { tokenStoreType: 'memory' }); - const account = await auth.login({ code: 'foo' }); - const revoked = await auth.logout({ accounts: account.name }); + const account: Account = await auth.login({ code: 'foo' }) as Account; + const revoked: Account[] = await auth.logout({ accounts: account.name }); expect(revoked).to.have.lengthOf(1); }); diff --git a/packages/amplify-sdk/test/test-sdk.js b/packages/amplify-sdk/test/test-sdk.ts similarity index 79% rename from packages/amplify-sdk/test/test-sdk.js rename to packages/amplify-sdk/test/test-sdk.ts index 3b2e078f..d4b1217c 100644 --- a/packages/amplify-sdk/test/test-sdk.js +++ b/packages/amplify-sdk/test/test-sdk.ts @@ -1,9 +1,13 @@ -import AmplifySDK from '../dist/index'; +import AmplifySDK from '../src/index.js'; import fs from 'fs'; import path from 'path'; -import { createServer, stopServer } from './common'; -import { resovleMonthRange } from '../dist/amplify-sdk'; +import { Account, UsageParams, User } from '../src/types.js'; +import { createServer, stopServer } from './common.js'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; +import { resolveMonthRange } from '../src/util.js'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const baseUrl = 'http://127.0.0.1:1337'; const isCI = process.env.CI || process.env.JENKINS; @@ -22,7 +26,7 @@ describe('amplify-sdk', () => { describe('Error Handling', () => { it('should error if options is not an object', () => { expect(() => { - new AmplifySDK('foo'); + new AmplifySDK('foo' as any); }).to.throw(TypeError, 'Expected options to be an object'); }); @@ -44,7 +48,7 @@ describe('amplify-sdk', () => { describe('Error Handling', () => { it('should error creating client if token store is invalid', () => { expect(() => { - const client = createSDK({ tokenStore: 'foo' }).authClient; + const client = createSDK({ tokenStore: 'foo' }).auth.client; expect(client).to.be.an('object'); }).to.throw(TypeError, 'Expected the token store to be a "TokenStore" instance'); }); @@ -60,7 +64,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const acct = await sdk.auth.find('test_client:foo@bar.com'); + const acct = await sdk.auth.find('test_client:foo@bar.com') as Account; expect(acct.auth).to.deep.equal({ baseUrl, expires: account.auth.expires, @@ -86,7 +90,7 @@ describe('amplify-sdk', () => { }); const sdk = createSDK({ tokenStore }); - const acct = await sdk.auth.find('test_client:foo@bar.com'); + const acct = await sdk.auth.find('test_client:foo@bar.com') as Account; expect(acct.auth).to.deep.equal({ baseUrl, expires: account.auth.expires, @@ -104,7 +108,7 @@ describe('amplify-sdk', () => { const sdk = createSDK(); const account = await sdk.auth.find('bar'); - expect(account).to.equal(null); + expect(account).to.equal(undefined); }); }); @@ -118,7 +122,7 @@ describe('amplify-sdk', () => { const { tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.auth.findSession()).to.eventually.be.rejectedWith(TypeError, 'Account required'); + await expect(sdk.auth.findSession(undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Account required'); }); }); @@ -131,14 +135,14 @@ describe('amplify-sdk', () => { const sdk = createSDK(); - let account = await sdk.auth.login(); + const account = await sdk.auth.login() as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.name).to.equal('test_client:foo@bar.com'); // try to log in again await expect(sdk.auth.login()).to.eventually.be.rejectedWith(Error, 'Account already authenticated'); - await expect(sdk.auth.logout({ accounts: 'foo' })).to.eventually.be.rejectedWith(TypeError, 'Expected accounts to be a list of accounts'); + await expect(sdk.auth.logout({ accounts: 'foo' } as any)).to.eventually.be.rejectedWith(TypeError, 'Expected accounts to be a list of accounts'); await sdk.auth.logout({ accounts: [] }); await sdk.auth.logout({ all: true }); }); @@ -162,7 +166,7 @@ describe('amplify-sdk', () => { const sdk = createSDK(); await expect(sdk.auth.login({ - username: 123, + username: 123 as any, clientSecret: '###', serviceAccount: true })).to.eventually.be.rejectedWith(TypeError, 'Expected username to be an email address'); @@ -192,7 +196,7 @@ describe('amplify-sdk', () => { password: 'bar', clientSecret: '###', serviceAccount: true - }); + }) as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.isPlatform).to.equal(true); @@ -226,7 +230,7 @@ describe('amplify-sdk', () => { const sdk = createSDK(); - const account = await sdk.auth.switchOrg(); + const account = await sdk.auth.switchOrg() as Account; expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); expect(account.name).to.equal('test_client:foo@bar.com'); @@ -249,7 +253,7 @@ describe('amplify-sdk', () => { }); const sdk = createSDK({ tokenStore }); - const acct = await sdk.auth.switchOrg(account); + const acct = await sdk.auth.switchOrg(account) as Account; expect(acct.auth.tokens.access_token).to.equal(this.server.accessToken); expect(acct.name).to.equal('test_client:foo@bar.com'); }); @@ -261,12 +265,12 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const acct = await sdk.auth.switchOrg(account); + const acct = await sdk.auth.switchOrg(account) as Account; expect(acct.name).to.equal('test_client:foo@bar.com'); }); (isCI ? it.skip : it)('should fail to switch org if access token is bad', async function () { - this.timeout(10000); + this.timeout(20000); this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore({ @@ -300,32 +304,32 @@ describe('amplify-sdk', () => { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.create(account, 100, null)).to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); - await expect(sdk.client.create(account, 100, 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); + await expect(sdk.client.create(account, 100, null as any)).to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); + await expect(sdk.client.create(account, 100, 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); }); it('should error if name is invalid', async function () { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.create(account, 100, {})).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); - await expect(sdk.client.create(account, 100, { name: 123 })).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); + await expect(sdk.client.create(account, 100, {} as any)).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); + await expect(sdk.client.create(account, 100, { name: 123 } as any)).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); }); it('should error if description is invalid', async function () { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.create(account, 100, { name: 'foo', desc: [] })).to.eventually.be.rejectedWith(TypeError, 'Expected description to be a string'); - await expect(sdk.client.create(account, 100, { name: 'foo', desc: 123 })).to.eventually.be.rejectedWith(TypeError, 'Expected description to be a string'); + await expect(sdk.client.create(account, 100, { name: 'foo', desc: [] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected description to be a string'); + await expect(sdk.client.create(account, 100, { name: 'foo', desc: 123 as any })).to.eventually.be.rejectedWith(TypeError, 'Expected description to be a string'); }); it('should error if public key is invalid', async function () { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.create(account, 100, { name: 'foo', publicKey: [] })).to.eventually.be.rejectedWith(TypeError, 'Expected public key to be a string'); - await expect(sdk.client.create(account, 100, { name: 'foo', publicKey: 123 })).to.eventually.be.rejectedWith(TypeError, 'Expected public key to be a string'); + await expect(sdk.client.create(account, 100, { name: 'foo', publicKey: [] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected public key to be a string'); + await expect(sdk.client.create(account, 100, { name: 'foo', publicKey: 123 as any })).to.eventually.be.rejectedWith(TypeError, 'Expected public key to be a string'); await expect(sdk.client.create(account, 100, { name: 'foo', publicKey: 'baz' })).to.eventually.be.rejectedWith(Error, 'Expected public key to be PEM formatted'); }); @@ -333,8 +337,8 @@ describe('amplify-sdk', () => { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: [] })).to.eventually.be.rejectedWith(TypeError, 'Expected secret to be a string'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 123 })).to.eventually.be.rejectedWith(TypeError, 'Expected secret to be a string'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: [] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected secret to be a string'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 123 as any })).to.eventually.be.rejectedWith(TypeError, 'Expected secret to be a string'); }); it('should error if no public key or secret', async function () { @@ -348,23 +352,23 @@ describe('amplify-sdk', () => { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', roles: 123 })).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', roles: 'pow' })).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', roles: 123 as any })).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', roles: 'pow' as any })).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); }); it('should error if teams are invalid', async function () { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: 123 })).to.eventually.be.rejectedWith(TypeError, 'Expected teams to be an array'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: 'pow' })).to.eventually.be.rejectedWith(TypeError, 'Expected teams to be an array'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: 123 as any })).to.eventually.be.rejectedWith(TypeError, 'Expected teams to be an array'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: 'pow' as any })).to.eventually.be.rejectedWith(TypeError, 'Expected teams to be an array'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ 'pow' ] })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ {} ] })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 123 } ] })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 'abc' } ] })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 'abc', roles: 123 } ] })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); - await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 'abc', roles: [] } ] })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ 'pow' ] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ {} ] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 123 } ] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 'abc' } ] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 'abc', roles: 123 } ] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); + await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 'abc', roles: [] } ] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected team to be an object containing a guid and array of roles'); await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: 'abc', roles: [ 'def' ] } ] })).to.eventually.be.rejectedWith(Error, 'Invalid team "abc"'); await expect(sdk.client.create(account, 100, { name: 'foo', secret: 'baz', teams: [ { guid: '60000', roles: [ 'def' ] } ] })).to.eventually.be.rejectedWith(Error, 'Invalid team role "def"'); @@ -386,7 +390,6 @@ describe('amplify-sdk', () => { const sdk = createSDK({ tokenStore }); const { team } = await sdk.team.create(account, 100, 'C Team', { desc: 'The C Team' }); - let { client } = await sdk.client.create(account, 100, { name: 'foo', secret: 'baz', @@ -492,7 +495,7 @@ describe('amplify-sdk', () => { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.remove(account, 100, {})).to.eventually.be.rejectedWith(TypeError, 'Expected client to be an object or client id'); + await expect(sdk.client.remove(account, 100, {} as any)).to.eventually.be.rejectedWith(TypeError, 'Expected client to be an object or client id'); }); it('should error removing a service account if not found', async function () { @@ -536,14 +539,14 @@ describe('amplify-sdk', () => { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.update(account, 100, 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); + await expect(sdk.client.update(account, 100, 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected options to be an object'); }); it('should error updaing a service account if client id is invalid', async function () { this.server = await createServer(); const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.client.update(account, 100, { client: {} })).to.eventually.be.rejectedWith(TypeError, 'Expected client to be an object or client id'); + await expect(sdk.client.update(account, 100, { client: {} } as any)).to.eventually.be.rejectedWith(TypeError, 'Expected client to be an object or client id'); }); it('should error updating a service account if not found', async function () { @@ -601,7 +604,7 @@ describe('amplify-sdk', () => { await expect(sdk.client.update(account, 100, { client: 'test_629e1705-9cd7-4db7-9dfe-08aa47b0f3ad', - name: [] + name: [] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); }); @@ -612,7 +615,7 @@ describe('amplify-sdk', () => { await expect(sdk.client.update(account, 100, { client: 'test_629e1705-9cd7-4db7-9dfe-08aa47b0f3ad', - desc: [] + desc: [] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected description to be a string'); }); @@ -623,7 +626,7 @@ describe('amplify-sdk', () => { await expect(sdk.client.update(account, 100, { client: 'test_629e1705-9cd7-4db7-9dfe-08aa47b0f3ad', - publicKey: [] + publicKey: [] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected public key to be a string'); await expect(sdk.client.update(account, 100, { @@ -639,7 +642,7 @@ describe('amplify-sdk', () => { await expect(sdk.client.update(account, 100, { client: 'test_629e1705-9cd7-4db7-9dfe-08aa47b0f3ad', - secret: [] + secret: [] as any })).to.eventually.be.rejectedWith(TypeError, 'Expected secret to be a string'); }); @@ -684,8 +687,8 @@ describe('amplify-sdk', () => { const { tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.list()).to.eventually.be.rejectedWith(TypeError, 'Account required'); - await expect(sdk.org.list({})).to.eventually.be.rejectedWith(Error, 'Account must be a platform account'); + await expect(sdk.org.list(undefined as any, undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Account required'); + await expect(sdk.org.list({} as any, undefined as any)).to.eventually.be.rejectedWith(Error, 'Account must be a platform account'); }); it('should error if default org is invalid', async function () { @@ -695,28 +698,11 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.list(account, {})).to.eventually.be.rejectedWith(TypeError, 'Expected organization identifier'); + await expect(sdk.org.list(account, {} as any)).to.eventually.be.rejectedWith(TypeError, 'Expected organization identifier'); await expect(sdk.org.list(account, 'wiz')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "wiz"'); }); }); - describe('family()', () => { - afterEach(stopServer); - - it('should get org family', async function () { - this.timeout(10000); - this.server = await createServer(); - - const { account, tokenStore } = this.server.createTokenStore(); - const sdk = createSDK({ tokenStore }); - - const family = await sdk.org.family(account, 100); - expect(family).to.be.an('object'); - expect(family.children).to.be.an('array'); - expect(family.children).to.have.lengthOf(1); - }); - }); - describe('find()', () => { afterEach(stopServer); @@ -753,10 +739,12 @@ describe('amplify-sdk', () => { const envs = await sdk.org.environments(account); expect(envs).to.deep.equal([ { + guid: undefined, name: 'production', isProduction: true }, { + guid: undefined, name: 'development', isProduction: false } @@ -785,8 +773,8 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.rename(account, 100)).to.eventually.be.rejectedWith(TypeError, 'Organization name must be a non-empty string'); - await expect(sdk.org.rename(account, 100, 123)).to.eventually.be.rejectedWith(TypeError, 'Organization name must be a non-empty string'); + await expect(sdk.org.rename(account, 100, undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Organization name must be a non-empty string'); + await expect(sdk.org.rename(account, 100, 123 as any)).to.eventually.be.rejectedWith(TypeError, 'Organization name must be a non-empty string'); await expect(sdk.org.rename(account, 100, '')).to.eventually.be.rejectedWith(TypeError, 'Organization name must be a non-empty string'); }); }); @@ -878,7 +866,7 @@ describe('amplify-sdk', () => { let { usage } = await sdk.org.usage(account, 100, { from: '2021-02-04', to: '2021-02-10' - }); + } as UsageParams); expect(usage.SaaS).to.deep.equal({ apiRateMonth: { name: 'API Calls', quota: 5000, value: 784, unit: 'Calls' }, pushRateMonth: { name: 'Push Notifications', quota: 2000, value: 167, unit: 'Calls' }, @@ -891,7 +879,7 @@ describe('amplify-sdk', () => { ({ usage } = await sdk.org.usage(account, 100, { from: '2021-02-01', to: '2021-02-20' - })); + } as UsageParams)); expect(usage.SaaS).to.deep.equal({ apiRateMonth: { name: 'API Calls', quota: 5000, value: 1294, unit: 'Calls' }, pushRateMonth: { name: 'Push Notifications', quota: 2000, value: 1211, unit: 'Calls' }, @@ -919,8 +907,8 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.usage(account, 100, { from: 'foo' })).to.eventually.be.rejectedWith(Error, 'Expected "from" date to be in the format YYYY-MM-DD'); - await expect(sdk.org.usage(account, 100, { to: 'foo' })).to.eventually.be.rejectedWith(Error, 'Expected "to" date to be in the format YYYY-MM-D'); + await expect(sdk.org.usage(account, 100, { from: 'foo' } as any)).to.eventually.be.rejectedWith(Error, 'Expected "from" date to be in the format YYYY-MM-DD'); + await expect(sdk.org.usage(account, 100, { to: 'foo' } as any)).to.eventually.be.rejectedWith(Error, 'Expected "to" date to be in the format YYYY-MM-D'); }); }); @@ -935,38 +923,51 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - let { users } = await sdk.org.user.list(account); + let { users } = await sdk.org.userList(account); expect(users).to.deep.equal([ { + client_id: undefined, guid: '50000', email: 'test1@domain.com', firstname: 'Test1', lastname: 'Tester1', - phone: '555-5001', - roles: [ 'administrator' ], - primary: true + name: 'Test1 Tester1', + primary: true, + roles: [ 'administrator' ] }, { + client_id: undefined, guid: '50001', email: 'test2@domain.com', firstname: 'Test2', lastname: 'Tester2', - phone: '555-5002', - roles: [ 'developer' ], - primary: true + name: 'Test2 Tester2', + primary: true, + roles: [ 'developer' ] + }, + { + client_id: 'test_629e1705-9cd7-4db7-9dfe-08aa47b0f3ad', + email: undefined, + firstname: undefined, + guid: '629e1705-9cd7-4db7-9dfe-08aa47b0f3ad', + lastname: undefined, + name: 'Test', + primary: undefined, + roles: [ 'developer' ] } ]); - ({ users } = await sdk.org.user.list(account, '2000')); + ({ users } = await sdk.org.userList(account, '2000')); expect(users).to.deep.equal([ { + client_id: undefined, guid: '50000', email: 'test1@domain.com', firstname: 'Test1', lastname: 'Tester1', - phone: '555-5001', - roles: [ 'administrator' ], - primary: true + name: 'Test1 Tester1', + primary: true, + roles: [ 'administrator' ] } ]); }); @@ -978,7 +979,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.list(account, 300)).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); + await expect(sdk.org.userList(account, 300)).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); }); }); @@ -992,15 +993,16 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const user = await sdk.org.user.find(account, 100, '50000'); + const user = await sdk.org.userFind(account, 100, '50000'); expect(user).to.deep.equal({ + client_id: undefined, guid: '50000', email: 'test1@domain.com', firstname: 'Test1', lastname: 'Tester1', - phone: '555-5001', - roles: [ 'administrator' ], - primary: true + name: 'Test1 Tester1', + primary: true, + roles: [ 'administrator' ] }); }); @@ -1011,15 +1013,16 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const user = await sdk.org.user.find(account, 100, 'test2@domain.com'); + const user = await sdk.org.userFind(account, 100, 'test2@domain.com'); expect(user).to.deep.equal({ + client_id: undefined, guid: '50001', email: 'test2@domain.com', firstname: 'Test2', lastname: 'Tester2', - phone: '555-5002', - roles: [ 'developer' ], - primary: true + name: 'Test2 Tester2', + primary: true, + roles: [ 'developer' ] }); }); @@ -1030,7 +1033,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const user = await sdk.org.user.find(account, 100, '12345'); + const user = await sdk.org.userFind(account, 100, '12345'); expect(user).to.be.undefined; }); }); @@ -1045,22 +1048,23 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - expect(await sdk.org.user.find(account, 100, 'test3@domain.com')).to.be.undefined; + expect(await sdk.org.userFind(account, 100, 'test3@domain.com')).to.be.undefined; - const { user } = await sdk.org.user.add(account, 100, 'test3@domain.com', [ 'developer' ]); - expect(user.guid).to.deep.equal('50002'); + const { user } = await sdk.org.userAdd(account, 100, 'test3@domain.com', [ 'developer' ]); + expect((user as User).guid).to.deep.equal('50002'); - expect(await sdk.org.user.find(account, 100, 'test3@domain.com')).to.deep.equal({ + expect(await sdk.org.userFind(account, 100, 'test3@domain.com')).to.deep.equal({ + client_id: undefined, guid: '50002', email: 'test3@domain.com', firstname: 'Test3', lastname: 'Tester3', - phone: '555-5003', - roles: [ 'developer' ], - primary: true + name: 'Test3 Tester3', + primary: true, + roles: [ 'developer' ] }); - await expect(sdk.org.user.add(account, 100, 'test3@domain.com', [ 'developer' ])).to.eventually.be + await expect(sdk.org.userAdd(account, 100, 'test3@domain.com', [ 'developer' ])).to.eventually.be .rejectedWith(Error, 'Failed to add user to organization: User is already a member of this org. (400)'); }); @@ -1071,7 +1075,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.add(account, 300)).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); + await expect(sdk.org.userAdd(account, 300, '', [])).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); }); it('should error if roles are invalid', async function () { @@ -1081,10 +1085,10 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.add(account, 100, '12345')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.org.user.add(account, 100, '12345', 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.org.user.add(account, 100, '12345', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); - await expect(sdk.org.user.add(account, 100, '12345', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer, some_admin'); + await expect(sdk.org.userAdd(account, 100, '12345', undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.org.userAdd(account, 100, '12345', 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.org.userAdd(account, 100, '12345', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); + await expect(sdk.org.userAdd(account, 100, '12345', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer, some_admin'); }); it('should error if roles does not include a default role', async function () { @@ -1094,7 +1098,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.add(account, 100, '12345', [ 'some_admin' ])).to.eventually.be.rejectedWith(Error, 'You must specify a default role: administrator, developer'); + await expect(sdk.org.userAdd(account, 100, '12345', [ 'some_admin' ])).to.eventually.be.rejectedWith(Error, 'You must specify a default role: administrator, developer'); }); }); @@ -1108,15 +1112,16 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const { user } = await sdk.org.user.update(account, 100, '50001', [ 'administrator' ]); + const { user } = await sdk.org.userUpdate(account, 100, '50001', [ 'administrator' ]); expect(user).to.deep.equal({ + client_id: undefined, guid: '50001', email: 'test2@domain.com', firstname: 'Test2', lastname: 'Tester2', - phone: '555-5002', - roles: [ 'administrator' ], - primary: true + name: 'Test2 Tester2', + primary: true, + roles: [ 'administrator' ] }); }); @@ -1127,7 +1132,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.update(account, 300, '50001', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); + await expect(sdk.org.userUpdate(account, 300, '50001', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); }); it('should error update user role for user not in an org', async function () { @@ -1137,7 +1142,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.update(account, 100, '50002', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); + await expect(sdk.org.userUpdate(account, 100, '50002', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); }); it('should error if roles are invalid', async function () { @@ -1147,10 +1152,10 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.update(account, 100, '50001')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.org.user.update(account, 100, '50001', 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.org.user.update(account, 100, '50001', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); - await expect(sdk.org.user.update(account, 100, '50001', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer, some_admin'); + await expect(sdk.org.userUpdate(account, 100, '50001', undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.org.userUpdate(account, 100, '50001', 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.org.userUpdate(account, 100, '50001', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); + await expect(sdk.org.userUpdate(account, 100, '50001', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer, some_admin'); }); }); @@ -1164,9 +1169,9 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - expect((await sdk.org.user.list(account, 100)).users).to.have.lengthOf(2); - await sdk.org.user.remove(account, 100, '50001'); - expect((await sdk.org.user.list(account, 100)).users).to.have.lengthOf(1); + expect((await sdk.org.userList(account, 100)).users).to.have.lengthOf(3); + await sdk.org.userRemove(account, 100, '50001'); + expect((await sdk.org.userList(account, 100)).users).to.have.lengthOf(2); }); it('should error removing a user from a non-existing org', async function () { @@ -1176,7 +1181,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.remove(account, 300, '50001')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); + await expect(sdk.org.userRemove(account, 300, '50001')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "300"'); }); it('should error removing a user that does not currently belong to an org', async function () { @@ -1186,7 +1191,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.org.user.remove(account, 100, '50002')).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); + await expect(sdk.org.userRemove(account, 100, '50002')).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); }); }); }); @@ -1276,7 +1281,7 @@ describe('amplify-sdk', () => { this.server = await createServer(); const sdk = createSDK(); - await expect(sdk.role.list({})).to.eventually.be.rejectedWith(Error, 'Failed to get roles'); + await expect(sdk.role.list({} as any)).to.eventually.be.rejectedWith(Error, 'Failed to get roles'); }); }); @@ -1350,7 +1355,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.find(account, 'abc')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); + await expect(sdk.team.find(account, 'abc', undefined as any)).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); }); it('should error if team is invalid', async function () { @@ -1360,8 +1365,8 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.find(account, 100)).to.eventually.be.rejectedWith(TypeError, 'Expected team to be a name or guid'); - await expect(sdk.team.find(account, 100, 123)).to.eventually.be.rejectedWith(TypeError, 'Expected team to be a name or guid'); + await expect(sdk.team.find(account, 100, undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Expected team to be a name or guid'); + await expect(sdk.team.find(account, 100, 123 as any)).to.eventually.be.rejectedWith(TypeError, 'Expected team to be a name or guid'); }); it('should error if team not found', async function () { @@ -1402,8 +1407,8 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.create(account, 100)).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); - await expect(sdk.team.create(account, 100, 123)).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); + await expect(sdk.team.create(account, 100, undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); + await expect(sdk.team.create(account, 100, 123 as any)).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); await expect(sdk.team.create(account, 100, '')).to.eventually.be.rejectedWith(TypeError, 'Expected name to be a non-empty string'); }); @@ -1414,7 +1419,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.create(account, 'abc')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); + await expect(sdk.team.create(account, 'abc', '', {})).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); }); it('should error if team info is invalid', async function () { @@ -1424,8 +1429,8 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.create(account, 100, 'C Team', 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected team info to be an object'); - await expect(sdk.team.create(account, 100, 'C Team', { tags: 'foo' })).to.eventually.be.rejectedWith(TypeError, 'Expected team tags to be an array of strings'); + await expect(sdk.team.create(account, 100, 'C Team', 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected team info to be an object'); + await expect(sdk.team.create(account, 100, 'C Team', { tags: 'foo' } as any)).to.eventually.be.rejectedWith(TypeError, 'Expected team tags to be an array of strings'); }); }); @@ -1468,7 +1473,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const { team } = await sdk.team.update(account, 100, 'A Team'); + const { team } = await sdk.team.update(account, 100, 'A Team', {}); expect(team.name).to.equal('A Team'); expect(team.desc).to.equal(undefined); expect(team.guid).to.equal('60000'); @@ -1483,7 +1488,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.update(account, 'abc', 'A Team')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); + await expect(sdk.team.update(account, 'abc', 'A Team', {})).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); }); it('should error if team is not found', async function () { @@ -1493,7 +1498,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.update(account, 100, 'C Team')).to.eventually.be.rejectedWith(Error, 'Unable to find team "C Team" in the "Foo org" organization'); + await expect(sdk.team.update(account, 100, 'C Team', {})).to.eventually.be.rejectedWith(Error, 'Unable to find team "C Team" in the "Foo org" organization'); }); }); @@ -1548,10 +1553,10 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - let { users } = await sdk.team.user.list(account, 100, '60000'); + let { users } = await sdk.team.userList(account, 100, '60000'); expect(users).to.have.lengthOf(2); - ({ users } = await sdk.team.user.list(account, 200, '60001')); + ({ users } = await sdk.team.userList(account, 200, '60001')); expect(users).to.have.lengthOf(1); }); @@ -1562,7 +1567,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.list(account, 'abc', '60000')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); + await expect(sdk.team.userList(account, 'abc', '60000')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); }); it('should error getting users if team is not found', async function () { @@ -1572,7 +1577,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.list(account, 100, 'Z Team')).to.eventually.be.rejectedWith(Error, 'Unable to find team "Z Team" in the "Foo org" organization'); + await expect(sdk.team.userList(account, 100, 'Z Team')).to.eventually.be.rejectedWith(Error, 'Unable to find team "Z Team" in the "Foo org" organization'); }); }); @@ -1586,16 +1591,15 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const { user } = await sdk.team.user.find(account, 100, '60000', '50000'); + const { user } = await sdk.team.userFind(account, 100, '60000', '50000'); expect(user).to.deep.equal({ + client_id: undefined, guid: '50000', email: 'test1@domain.com', firstname: 'Test1', lastname: 'Tester1', name: 'Test1 Tester1', - phone: '555-5001', roles: [ 'administrator' ], - primary: true, type: 'user' }); }); @@ -1607,16 +1611,15 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const { user } = await sdk.team.user.find(account, 100, '60000', 'test1@domain.com'); + const { user } = await sdk.team.userFind(account, 100, '60000', 'test1@domain.com'); expect(user).to.deep.equal({ + client_id: undefined, guid: '50000', email: 'test1@domain.com', firstname: 'Test1', lastname: 'Tester1', name: 'Test1 Tester1', - phone: '555-5001', roles: [ 'administrator' ], - primary: true, type: 'user' }); }); @@ -1628,7 +1631,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const { user } = await sdk.team.user.find(account, 100, '60000', '12345'); + const { user } = await sdk.team.userFind(account, 100, '60000', '12345'); expect(user).to.be.undefined; }); }); @@ -1643,24 +1646,23 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - expect((await sdk.team.user.find(account, 100, '60000', 'test2@domain.com')).user).to.be.undefined; + expect((await sdk.team.userFind(account, 100, '60000', 'test2@domain.com')).user).to.be.undefined; - const { user } = await sdk.team.user.add(account, 100, '60000', 'test2@domain.com', [ 'developer' ]); + const { user } = await sdk.team.userAdd(account, 100, '60000', 'test2@domain.com', [ 'developer' ]); expect(user.guid).to.deep.equal('50001'); - expect((await sdk.team.user.find(account, 100, '60000', 'test2@domain.com')).user).to.deep.equal({ + expect((await sdk.team.userFind(account, 100, '60000', 'test2@domain.com')).user).to.deep.equal({ + client_id: undefined, guid: '50001', email: 'test2@domain.com', firstname: 'Test2', lastname: 'Tester2', name: 'Test2 Tester2', - phone: '555-5002', roles: [ 'developer' ], - primary: true, type: 'user' }); - await expect(sdk.team.user.add(account, 100, '60000', 'test2@domain.com', [ 'developer' ])).to.eventually.be + await expect(sdk.team.userAdd(account, 100, '60000', 'test2@domain.com', [ 'developer' ])).to.eventually.be .rejectedWith(Error, 'Failed to add user to organization: User is already a member of this team. (400)'); }); @@ -1671,24 +1673,23 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - expect((await sdk.team.user.find(account, 100, '60000', '50001')).user).to.be.undefined; + expect((await sdk.team.userFind(account, 100, '60000', '50001')).user).to.be.undefined; - const { user } = await sdk.team.user.add(account, 100, '60000', '50001', [ 'developer' ]); + const { user } = await sdk.team.userAdd(account, 100, '60000', '50001', [ 'developer' ]); expect(user.guid).to.deep.equal('50001'); - expect((await sdk.team.user.find(account, 100, '60000', '50001')).user).to.deep.equal({ + expect((await sdk.team.userFind(account, 100, '60000', '50001')).user).to.deep.equal({ + client_id: undefined, guid: '50001', email: 'test2@domain.com', firstname: 'Test2', lastname: 'Tester2', name: 'Test2 Tester2', - phone: '555-5002', roles: [ 'developer' ], - primary: true, type: 'user' }); - await expect(sdk.team.user.add(account, 100, '60000', '50001', [ 'developer' ])).to.eventually.be + await expect(sdk.team.userAdd(account, 100, '60000', '50001', [ 'developer' ])).to.eventually.be .rejectedWith(Error, 'Failed to add user to organization: User is already a member of this team. (400)'); }); @@ -1699,7 +1700,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.add(account, 'abc')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); + await expect(sdk.team.userAdd(account, 'abc', '', '', [])).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); }); it('should error if roles are invalid', async function () { @@ -1709,10 +1710,10 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.add(account, 100, '60000', '50001')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.team.user.add(account, 100, '60000', '50001', 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.team.user.add(account, 100, '60000', '50001', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); - await expect(sdk.team.user.add(account, 100, '60000', '50001', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer'); + await expect(sdk.team.userAdd(account, 100, '60000', '50001', undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.team.userAdd(account, 100, '60000', '50001', 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.team.userAdd(account, 100, '60000', '50001', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); + await expect(sdk.team.userAdd(account, 100, '60000', '50001', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer'); }); }); @@ -1726,16 +1727,15 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - const { user } = await sdk.team.user.update(account, 100, '60000', '50000', [ 'developer' ]); + const { user } = await sdk.team.userUpdate(account, 100, '60000', '50000', [ 'developer' ]); expect(user).to.deep.equal({ + client_id: undefined, guid: '50000', email: 'test1@domain.com', firstname: 'Test1', lastname: 'Tester1', name: 'Test1 Tester1', - phone: '555-5001', roles: [ 'developer' ], - primary: true, type: 'user' }); }); @@ -1747,7 +1747,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.update(account, 'abc', '60000', '50001', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); + await expect(sdk.team.userUpdate(account, 'abc', '60000', '50001', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); }); it('should error update user\'s team role for user not in an org', async function () { @@ -1757,7 +1757,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.update(account, 100, '60000', '50002', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); + await expect(sdk.team.userUpdate(account, 100, '60000', '50002', [ 'administrator' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); }); it('should error if roles are invalid', async function () { @@ -1767,10 +1767,10 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.update(account, 100, '60000', '50000')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.team.user.update(account, 100, '60000', '50000', 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); - await expect(sdk.team.user.update(account, 100, '60000', '50000', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); - await expect(sdk.team.user.update(account, 100, '60000', '50000', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer'); + await expect(sdk.team.userUpdate(account, 100, '60000', '50000', undefined as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.team.userUpdate(account, 100, '60000', '50000', 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected roles to be an array'); + await expect(sdk.team.userUpdate(account, 100, '60000', '50000', [])).to.eventually.be.rejectedWith(Error, 'Expected at least one of the following roles:'); + await expect(sdk.team.userUpdate(account, 100, '60000', '50000', [ 'foo' ])).to.eventually.be.rejectedWith(Error, 'Invalid role "foo", expected one of the following: administrator, developer'); }); it('should error if user not apart of the team', async function () { @@ -1780,7 +1780,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.update(account, 100, '60000', '50002', [ 'developer' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); + await expect(sdk.team.userUpdate(account, 100, '60000', '50002', [ 'developer' ])).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); }); it('should error updating user if team is not found', async function () { @@ -1790,7 +1790,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.update(account, 100, 'Z Team', '50000', [ 'developer' ])).to.eventually.be.rejectedWith(Error, 'Unable to find team "Z Team" in the "Foo org" organization'); + await expect(sdk.team.userUpdate(account, 100, 'Z Team', '50000', [ 'developer' ])).to.eventually.be.rejectedWith(Error, 'Unable to find team "Z Team" in the "Foo org" organization'); }); }); @@ -1804,9 +1804,9 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - expect((await sdk.team.user.list(account, 100, '60000')).users).to.have.lengthOf(2); - await sdk.team.user.remove(account, 100, '60000', '50000'); - expect((await sdk.team.user.list(account, 100, '60000')).users).to.have.lengthOf(1); + expect((await sdk.team.userList(account, 100, '60000')).users).to.have.lengthOf(2); + await sdk.team.userRemove(account, 100, '60000', '50000'); + expect((await sdk.team.userList(account, 100, '60000')).users).to.have.lengthOf(1); }); it('should error removing a user from a non-existing org', async function () { @@ -1816,7 +1816,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.remove(account, 'abc', '60000', '50001')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); + await expect(sdk.team.userRemove(account, 'abc', '60000', '50001')).to.eventually.be.rejectedWith(Error, 'Unable to find the organization "abc"'); }); it('should error removing a user that does not currently belong to an org', async function () { @@ -1826,7 +1826,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.team.user.remove(account, 100, '60000', '50002')).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); + await expect(sdk.team.userRemove(account, 100, '60000', '50002')).to.eventually.be.rejectedWith(Error, 'Unable to find the user "50002"'); }); }); }); @@ -1847,21 +1847,18 @@ describe('amplify-sdk', () => { expect(user.guid).to.equal('50000'); expect(user.firstname).to.equal('Test1'); expect(user.lastname).to.equal('Tester1'); - expect(user.phone).to.equal('555-5001'); expect(user.email).to.equal('test1@domain.com'); user = await sdk.user.find(account, '50001'); expect(user.guid).to.equal('50001'); expect(user.firstname).to.equal('Test2'); expect(user.lastname).to.equal('Tester2'); - expect(user.phone).to.equal('555-5002'); expect(user.email).to.equal('test2@domain.com'); user = await sdk.user.find(account, user); expect(user.guid).to.equal('50001'); expect(user.firstname).to.equal('Test2'); expect(user.lastname).to.equal('Tester2'); - expect(user.phone).to.equal('555-5002'); expect(user.email).to.equal('test2@domain.com'); }); @@ -1876,14 +1873,12 @@ describe('amplify-sdk', () => { expect(user.guid).to.equal('50000'); expect(user.firstname).to.equal('Test1'); expect(user.lastname).to.equal('Tester1'); - expect(user.phone).to.equal('555-5001'); expect(user.email).to.equal('test1@domain.com'); user = await sdk.user.find(account, 'test2@domain.com'); expect(user.guid).to.equal('50001'); expect(user.firstname).to.equal('Test2'); expect(user.lastname).to.equal('Tester2'); - expect(user.phone).to.equal('555-5002'); expect(user.email).to.equal('test2@domain.com'); }); @@ -1911,8 +1906,7 @@ describe('amplify-sdk', () => { const { changes } = await sdk.user.update(account, { firstname: 'Foo', - lastname: 'Bar', - phone: '555-0000' + lastname: 'Bar' }); expect(changes).to.deep.equal({ @@ -1923,17 +1917,12 @@ describe('amplify-sdk', () => { lastname: { v: 'Bar', p: 'Tester1' - }, - phone: { - v: '555-0000', - p: '555-5001' } }); const user = await sdk.user.find(account, '50000'); expect(user.firstname).to.equal('Foo'); expect(user.lastname).to.equal('Bar'); - expect(user.phone).to.equal('555-0000'); }); it('should not error if no info to update', async function () { @@ -1960,7 +1949,7 @@ describe('amplify-sdk', () => { const { account, tokenStore } = this.server.createTokenStore(); const sdk = createSDK({ tokenStore }); - await expect(sdk.user.update(account, 'foo')).to.eventually.be.rejectedWith(TypeError, 'Expected user info to be an object'); + await expect(sdk.user.update(account, 'foo' as any)).to.eventually.be.rejectedWith(TypeError, 'Expected user info to be an object'); }); }); @@ -2011,59 +2000,59 @@ describe('amplify-sdk', () => { }); }); - describe('resovleMonthRange', () => { + describe('resolveMonthRange', () => { it('should error if month is invalid', () => { expect(() => { - resovleMonthRange(); + resolveMonthRange(undefined as any); }).to.throw(TypeError, 'Expected month to be in the format YYYY-MM or MM'); expect(() => { - resovleMonthRange({}); + resolveMonthRange({} as any); }).to.throw(TypeError, 'Expected month to be in the format YYYY-MM or MM'); expect(() => { - resovleMonthRange('foo'); + resolveMonthRange('foo'); }).to.throw(TypeError, 'Expected month to be in the format YYYY-MM or MM'); }); it('should return current month', () => { - const r = resovleMonthRange(true); + const r = resolveMonthRange(true); expect(r.from).to.match(/^\d{4}-\d{2}-01$/); expect(r.to).to.match(/^\d{4}-\d{2}-\d{2}$/); }); it('should return range from single digit month', () => { - const r = resovleMonthRange('3'); + const r = resolveMonthRange('3'); expect(r.from).to.match(/^\d{4}-03-01$/); expect(r.to).to.match(/^\d{4}-03-31$/); }); it('should return range from single numeric digit month', () => { - const r = resovleMonthRange(6); + const r = resolveMonthRange(6); expect(r.from).to.match(/^\d{4}-06-01$/); expect(r.to).to.match(/^\d{4}-06-30$/); }); it('should return range from leading zero single digit month', () => { - const r = resovleMonthRange('04'); + const r = resolveMonthRange('04'); expect(r.from).to.match(/^\d{4}-04-01$/); expect(r.to).to.match(/^\d{4}-04-30$/); }); it('should return range from year and month', () => { - const r = resovleMonthRange('2020-05'); + const r = resolveMonthRange('2020-05'); expect(r.from).to.equal('2020-05-01'); expect(r.to).to.equal('2020-05-31'); }); it('should error if month is out of range', () => { expect(() => { - resovleMonthRange('13'); + resolveMonthRange('13'); }).to.throw(RangeError, 'Invalid month "13"'); }); it('should handle leap year', () => { - const r = resovleMonthRange('2020-02'); + const r = resolveMonthRange('2020-02'); expect(r.from).to.equal('2020-02-01'); expect(r.to).to.equal('2020-02-29'); }); diff --git a/packages/amplify-sdk/test/test-server-info.js b/packages/amplify-sdk/test/test-server-info.js deleted file mode 100644 index ca826c7e..00000000 --- a/packages/amplify-sdk/test/test-server-info.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Auth } from '../dist/index'; -import { createServer, stopServer } from './common'; -import serverInfo from './server-info.json'; - -describe('Server Info', () => { - afterEach(stopServer); - - it('should fetch server info', async function () { - this.server = await createServer(); - - const auth = new Auth({ - baseUrl: 'http://127.0.0.1:1337', - clientId: 'test_client', - realm: 'test_realm', - tokenStoreType: null - }); - - const info = await auth.serverInfo(); - expect(info).to.deep.equal(serverInfo); - }); -}); diff --git a/packages/amplify-sdk/test/test-server-info.ts b/packages/amplify-sdk/test/test-server-info.ts new file mode 100644 index 00000000..2978d4bc --- /dev/null +++ b/packages/amplify-sdk/test/test-server-info.ts @@ -0,0 +1,27 @@ +import fs from 'fs'; +import path from 'path'; +import { Auth } from '../src/index.js'; +import { createServer, stopServer } from './common.js'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const serverInfo = JSON.parse(fs.readFileSync(path.join(__dirname, '/server-info.json'), 'utf8')); + +describe('Server Info', () => { + afterEach(stopServer); + + it('should fetch server info', async function () { + this.server = await createServer(); + + const auth = new Auth({ + baseUrl: 'http://127.0.0.1:1337', + clientId: 'test_client', + realm: 'test_realm', + tokenStoreType: null as any + }); + + const info = await auth.serverInfo(); + expect(info).to.deep.equal(serverInfo); + }); +}); diff --git a/packages/amplify-sdk/test/test-server.js b/packages/amplify-sdk/test/test-server.ts similarity index 85% rename from packages/amplify-sdk/test/test-server.js rename to packages/amplify-sdk/test/test-server.ts index 874bf29d..dc7c5d3e 100644 --- a/packages/amplify-sdk/test/test-server.js +++ b/packages/amplify-sdk/test/test-server.ts @@ -1,6 +1,8 @@ import got from 'got'; -import { Auth } from '../dist/index'; import snooplogg from 'snooplogg'; +import { Auth } from '../src/index.js'; +import { expect } from 'chai'; +import { ManualLoginResult } from '../src/types.js'; const { log } = snooplogg('test:amplify-sdk:server'); const { highlight } = snooplogg.styles; @@ -17,13 +19,13 @@ describe('Server', () => { tokenStoreType: null }); - const { cancel, url } = await auth.login({ manual: true }); - const redirect_uri = new URL(new URL(url).searchParams.get('redirect_uri')); + const { cancel, url } = await auth.login({ manual: true }) as ManualLoginResult; + const redirect_uri = new URL(new URL(url).searchParams.get('redirect_uri') as string); try { log(`Requesting ${highlight(`${redirect_uri.origin}/callback`)}`); await got(`${redirect_uri.origin}/callback`); - } catch (error) { + } catch (error: any) { if (error.response) { expect(error.response.statusCode).to.equal(400); } else { @@ -45,14 +47,14 @@ describe('Server', () => { tokenStoreType: null }); - const { cancel, url } = await auth.login({ manual: true }); - const redirect_uri = new URL(url).searchParams.get('redirect_uri'); + const { cancel, url } = await auth.login({ manual: true }) as ManualLoginResult; + const redirect_uri = new URL(url).searchParams.get('redirect_uri') as string; const redirectURL = redirect_uri.replace(/(\/callback)\/.+$/, '$1') + '?code=123'; try { log(`Requesting ${highlight(redirectURL)}`); await got(redirectURL); - } catch (error) { + } catch (error: any) { if (error.response) { expect(error.response.statusCode).to.equal(400); } else { @@ -74,14 +76,14 @@ describe('Server', () => { tokenStoreType: null }); - const { cancel, url } = await auth.login({ manual: true }); - const redirect_uri = new URL(url).searchParams.get('redirect_uri'); + const { cancel, url } = await auth.login({ manual: true }) as ManualLoginResult; + const redirect_uri = new URL(url).searchParams.get('redirect_uri') as string; const redirectURL = redirect_uri.replace(/(\/callback)\/.+$/, '$1/foo') + '?code=123'; try { log(`Requesting ${highlight(redirectURL)}`); await got(redirectURL); - } catch (error) { + } catch (error: any) { if (error.response) { expect(error.response.statusCode).to.equal(400); } else { @@ -103,7 +105,7 @@ describe('Server', () => { tokenStoreType: null }); - const { cancel, promise, url } = await auth.login({ manual: true }); + const { cancel, promise, url } = await auth.login({ manual: true }) as ManualLoginResult; const redirect_uri = new URL(url).searchParams.get('redirect_uri'); const redirectUrl = `${redirect_uri}?code=123`; @@ -114,7 +116,7 @@ describe('Server', () => { log(`Requesting: ${highlight(redirectUrl)}`); await got(redirectUrl); throw new Error('Expected request to fail'); - } catch (error) { + } catch (error: any) { if (error.response) { expect(error.response.statusCode).to.equal(400); return; @@ -138,13 +140,13 @@ describe('Server', () => { tokenStoreType: null }); - const { cancel, url } = await auth.login({ manual: true }); - const redirect_uri = new URL(new URL(url).searchParams.get('redirect_uri')); + const { cancel, url } = await auth.login({ manual: true }) as ManualLoginResult; + const redirect_uri = new URL(new URL(url).searchParams.get('redirect_uri') as string); try { log(`Requesting: ${highlight(redirect_uri.origin)}`); await got(redirect_uri.origin); - } catch (error) { + } catch (error: any) { if (error.response) { expect(error.response.statusCode).to.equal(400); } else { @@ -166,7 +168,7 @@ describe('Server', () => { tokenStoreType: null }); - const { cancel, promise } = await auth.login({ manual: true }); + const { cancel, promise } = await auth.login({ manual: true }) as ManualLoginResult; await cancel(); diff --git a/packages/amplify-sdk/test/test-signed-jwt.js b/packages/amplify-sdk/test/test-signed-jwt.ts similarity index 85% rename from packages/amplify-sdk/test/test-signed-jwt.js rename to packages/amplify-sdk/test/test-signed-jwt.ts index 5ed3f8e2..db4c6aef 100644 --- a/packages/amplify-sdk/test/test-signed-jwt.js +++ b/packages/amplify-sdk/test/test-signed-jwt.ts @@ -1,6 +1,12 @@ +import http from 'http'; import path from 'path'; -import { Auth, Authenticator, SignedJWT } from '../dist/index'; -import { createLoginServer, stopLoginServer } from './common'; +import { Account } from '../src/types.js'; +import { Auth, Authenticator, SignedJWT } from '../src/index.js'; +import { createLoginServer, stopLoginServer } from './common.js'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); describe('Signed JWT', () => { describe('Constructor', () => { @@ -12,35 +18,35 @@ describe('Signed JWT', () => { it('should error if secret is invalid', () => { expect(() => { - new SignedJWT({}); + new SignedJWT({} as any); }).to.throw(Error, 'Expected either a private key or private key file to be an object'); expect(() => { - new SignedJWT({ secret: null }); + new SignedJWT({ secret: null } as any); }).to.throw(Error, 'Expected either a private key or private key file to be an object'); expect(() => { - new SignedJWT({ secret: '' }); + new SignedJWT({ secret: '' } as any); }).to.throw(Error, 'Expected either a private key or private key file to be an object'); expect(() => { - new SignedJWT({ secret: 123 }); + new SignedJWT({ secret: 123 } as any); }).to.throw(TypeError, 'Expected private key to be a string'); expect(() => { - new SignedJWT({ secretFile: null }); + new SignedJWT({ secretFile: null } as any); }).to.throw(Error, 'Expected either a private key or private key file to be an object'); expect(() => { - new SignedJWT({ secretFile: '' }); + new SignedJWT({ secretFile: '' } as any); }).to.throw(Error, 'Expected either a private key or private key file to be an object'); expect(() => { - new SignedJWT({ secretFile: 123 }); + new SignedJWT({ secretFile: 123 } as any); }).to.throw(Error, 'Expected private key file path to be a string'); expect(() => { - new SignedJWT({ secretFile: __dirname }); + new SignedJWT({ secretFile: __dirname } as any); }).to.throw(Error, /^Specified private key is not a file:/); }); }); @@ -61,7 +67,7 @@ describe('Signed JWT', () => { try { await auth.login(); - } catch (err) { + } catch (err: any) { expect(err).to.be.instanceof(Error); expect(err.message).to.equal(`Specified private key file does not exist: ${secretFile}`); return; @@ -80,8 +86,8 @@ describe('Signed JWT', () => { }); try { - await auth.login('foo'); - } catch (err) { + await auth.login('foo' as any); + } catch (err: any) { expect(err).to.be.instanceof(TypeError); expect(err.message).to.equal('Expected options to be an object'); return; @@ -103,7 +109,7 @@ describe('Signed JWT', () => { try { await auth.login(); - } catch (e) { + } catch (e: any) { expect(e).to.be.instanceof(Error); expect(e.message).to.match(/connect ECONNREFUSED 127.0.0.1:133/i); expect(e.code).to.equal('ECONNREFUSED'); @@ -115,7 +121,7 @@ describe('Signed JWT', () => { it('should error if JWT token is incorrect', async function () { this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(401, { 'Content-Type': 'text/plain' }); res.end('Unauthorized'); } @@ -131,7 +137,7 @@ describe('Signed JWT', () => { try { await auth.login(); - } catch (e) { + } catch (e: any) { expect(e).to.be.instanceof(Error); expect(e.message).to.equal('Authentication failed: Response code 401 (Unauthorized)'); return; @@ -150,7 +156,7 @@ describe('Signed JWT', () => { }); this.server = await createLoginServer({ - handler(req, res) { + handler(req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ access_token: 'foo', @@ -163,7 +169,7 @@ describe('Signed JWT', () => { try { await auth.login(); - } catch (e) { + } catch (e: any) { expect(e).to.be.instanceof(Error); expect(e.message).to.equal('Authentication failed: Invalid server response'); return; @@ -176,7 +182,7 @@ describe('Signed JWT', () => { let counter = 0; this.server = await createLoginServer({ - token(post) { + token(post: any) { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.ClientCredentials); @@ -198,7 +204,7 @@ describe('Signed JWT', () => { tokenStoreType: 'memory' }); - const account = await auth.login(); + const account: Account = await auth.login() as Account; expect(account.name).to.equal('test_client:foo@bar.com'); expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); }); @@ -211,7 +217,7 @@ describe('Signed JWT', () => { this.server = await createLoginServer({ expiresIn: 1, - token(post) { + token(post: any) { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.ClientCredentials); @@ -232,13 +238,13 @@ describe('Signed JWT', () => { tokenStoreType: 'memory' }); - let results = await auth.login(); + let results: Account = await auth.login() as Account; const { accessToken } = this.server; expect(results.auth.tokens.access_token).to.equal(accessToken); await new Promise(resolve => setTimeout(resolve, 1500)); - results = await auth.login(); + results = await auth.login() as Account; expect(results.auth.tokens.access_token).to.not.equal(accessToken); expect(results.auth.tokens.access_token).to.equal(this.server.accessToken); }); @@ -247,7 +253,7 @@ describe('Signed JWT', () => { let counter = 0; this.server = await createLoginServer({ - token(post) { + token(post: any) { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.ClientCredentials); @@ -259,7 +265,7 @@ describe('Signed JWT', () => { break; } }, - userinfo(post, req, res) { + userinfo(post: any, req: http.IncomingMessage, res: http.ServerResponse) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Server error'); return true; @@ -274,7 +280,7 @@ describe('Signed JWT', () => { tokenStoreType: 'memory' }); - const account = await auth.login(); + const account: Account = await auth.login() as Account; expect(account.name).to.equal('test_client:foo@bar.com'); expect(account.auth.tokens.access_token).to.equal(this.server.accessToken); }); @@ -288,7 +294,7 @@ describe('Signed JWT', () => { this.server = await createLoginServer({ expiresIn: 10, - token(post) { + token: (post: any) => { switch (++counter) { case 1: expect(post.grant_type).to.equal(Authenticator.GrantTypes.ClientCredentials); @@ -310,7 +316,7 @@ describe('Signed JWT', () => { tokenStoreType: 'memory' }); - const account = await auth.login(); + const account: Account = await auth.login() as Account; const revoked = await auth.logout({ accounts: account.name }); expect(revoked).to.have.lengthOf(1); }); diff --git a/packages/amplify-sdk/test/test-telemetry.js b/packages/amplify-sdk/test/test-telemetry.ts similarity index 87% rename from packages/amplify-sdk/test/test-telemetry.js rename to packages/amplify-sdk/test/test-telemetry.ts index e1e719b7..0bbbe6dd 100644 --- a/packages/amplify-sdk/test/test-telemetry.js +++ b/packages/amplify-sdk/test/test-telemetry.ts @@ -1,8 +1,9 @@ import fs from 'fs-extra'; import path from 'path'; import tmp from 'tmp'; -import { createTelemetryServer, stopServer } from './common'; -import { Telemetry } from '../dist/index'; +import { createTelemetryServer, stopServer } from './common.js'; +import { expect } from 'chai'; +import { Telemetry } from '../src/index.js'; tmp.setGracefulCleanup(); @@ -14,59 +15,59 @@ describe('Telemetry', () => { it('should error if options are invalid', () => { expect(() => { - new Telemetry(); + new Telemetry(undefined as any); }).to.throw(TypeError, 'Expected telemetry options to be an object'); expect(() => { - new Telemetry(123); + new Telemetry(123 as any); }).to.throw(TypeError, 'Expected telemetry options to be an object'); }); it('should error if app guid is invalid', () => { expect(() => { - new Telemetry({}); + new Telemetry({} as any); }).to.throw(TypeError, 'Expected app guid to be a non-empty string'); expect(() => { - new Telemetry({ appGuid: '' }); + new Telemetry({ appGuid: '' } as any); }).to.throw(TypeError, 'Expected app guid to be a non-empty string'); expect(() => { - new Telemetry({ appGuid: 123 }); + new Telemetry({ appGuid: 123 } as any); }).to.throw(TypeError, 'Expected app guid to be a non-empty string'); }); it('should error if app version is invalid', () => { expect(() => { - new Telemetry({ appGuid: 'foo' }); + new Telemetry({ appGuid: 'foo' } as any); }).to.throw(TypeError, 'Expected app version to be a non-empty string'); expect(() => { - new Telemetry({ appGuid: 'foo', appVersion: '' }); + new Telemetry({ appGuid: 'foo', appVersion: '' } as any); }).to.throw(TypeError, 'Expected app version to be a non-empty string'); expect(() => { - new Telemetry({ appGuid: 'foo', appVersion: 123 }); + new Telemetry({ appGuid: 'foo', appVersion: 123 } as any); }).to.throw(TypeError, 'Expected app version to be a non-empty string'); }); it('should error if cache dir is invalid', () => { expect(() => { - new Telemetry({ appGuid: 'foo', appVersion: '1.0.0' }); + new Telemetry({ appGuid: 'foo', appVersion: '1.0.0' } as any); }).to.throw(TypeError, 'Expected telemetry cache dir to be a non-empty string'); expect(() => { - new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: '' }); + new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: '' } as any); }).to.throw(TypeError, 'Expected telemetry cache dir to be a non-empty string'); expect(() => { - new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: 123 }); + new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: 123 } as any); }).to.throw(TypeError, 'Expected telemetry cache dir to be a non-empty string'); }); it('should error if environment is invalid', () => { expect(() => { - new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: 'bar' }); + new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: 'bar' } as any); }).to.throw(TypeError, 'Expected environment to be a non-empty string'); expect(() => { @@ -74,7 +75,7 @@ describe('Telemetry', () => { }).to.throw(TypeError, 'Expected environment to be a non-empty string'); expect(() => { - new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: 'bar', environment: 123 }); + new Telemetry({ appGuid: 'foo', appVersion: '1.0.0', cacheDir: 'bar', environment: 123 } as any); }).to.throw(TypeError, 'Expected environment to be a non-empty string'); }); @@ -86,7 +87,7 @@ describe('Telemetry', () => { cacheDir: 'bar', environment: 'test', requestOptions: 'baz' - }); + } as any); }).to.throw(TypeError, 'Expected telemetry request options to be an object'); expect(() => { @@ -96,7 +97,7 @@ describe('Telemetry', () => { cacheDir: 'bar', environment: 'test', requestOptions: 123 - }); + } as any); }).to.throw(TypeError, 'Expected telemetry request options to be an object'); }); @@ -104,15 +105,15 @@ describe('Telemetry', () => { const { telemetry } = createTelemetry(); expect(() => { - telemetry.addEvent(); + telemetry.addEvent(undefined as any); }).to.throw(TypeError, 'Expected telemetry payload to be an object'); expect(() => { - telemetry.addEvent(123); + telemetry.addEvent(123 as any); }).to.throw(TypeError, 'Expected telemetry payload to be an object'); expect(() => { - telemetry.addEvent('foo'); + telemetry.addEvent('foo' as any); }).to.throw(TypeError, 'Expected telemetry payload to be an object'); }); @@ -120,7 +121,7 @@ describe('Telemetry', () => { const { telemetry } = createTelemetry(); expect(() => { - telemetry.addEvent({}); + telemetry.addEvent({} as any); }).to.throw(TypeError, 'Expected telemetry payload to have an event name'); expect(() => { @@ -128,7 +129,7 @@ describe('Telemetry', () => { }).to.throw(TypeError, 'Expected telemetry payload to have an event name'); expect(() => { - telemetry.addEvent({ event: 123 }); + telemetry.addEvent({ event: 123 } as any); }).to.throw(TypeError, 'Expected telemetry payload to have an event name'); }); @@ -136,15 +137,15 @@ describe('Telemetry', () => { const { telemetry } = createTelemetry({ environment: 'production' }); expect(() => { - telemetry.addCrash(); + telemetry.addCrash(undefined as any); }).to.throw(TypeError, 'Expected crash payload to be an object'); expect(() => { - telemetry.addCrash(123); + telemetry.addCrash(123 as any); }).to.throw(TypeError, 'Expected crash payload to be an object'); expect(() => { - telemetry.addCrash('foo'); + telemetry.addCrash('foo' as any); }).to.throw(TypeError, 'Expected crash payload to be an object'); }); @@ -152,7 +153,7 @@ describe('Telemetry', () => { const { telemetry } = createTelemetry({ environment: 'production' }); expect(() => { - telemetry.addCrash({}); + telemetry.addCrash({} as any); }).to.throw(TypeError, 'Expected crash payload to have a message'); expect(() => { @@ -160,13 +161,13 @@ describe('Telemetry', () => { }).to.throw(TypeError, 'Expected crash payload to have a message'); expect(() => { - telemetry.addCrash({ message: 123 }); + telemetry.addCrash({ message: 123 } as any); }).to.throw(TypeError, 'Expected crash payload to have a message'); }); it('should not add crash if not production', () => { const { telemetry } = createTelemetry(); - telemetry.addCrash(); + telemetry.addCrash(new Error()); }); }); @@ -179,12 +180,12 @@ describe('Telemetry', () => { }); it('should not send if no events', async function () { - this.timeout(10000); + this.timeout(1000000); this.slow(8000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -209,9 +210,9 @@ describe('Telemetry', () => { this.timeout(10000); this.slow(8000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -223,13 +224,13 @@ describe('Telemetry', () => { telemetry.addEvent({ event: 'foo.bar', meaningOfLife: 42 - }); + } as any); - let files = fs.readdirSync(appDir); + const files = fs.readdirSync(appDir); expect(files).to.have.lengthOf(4); telemetry.send(); - await new Promise(resolve => setTimeout(() => resolve(), 5000)); + await new Promise(resolve => setTimeout(() => resolve(), 5000)); expect(fs.readdirSync(appDir)).to.have.lengthOf(3); expect(posts).to.have.lengthOf(1); @@ -243,9 +244,9 @@ describe('Telemetry', () => { this.timeout(5000); this.slow(4000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -282,9 +283,9 @@ describe('Telemetry', () => { this.timeout(5000); this.slow(4000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -295,7 +296,10 @@ describe('Telemetry', () => { telemetry.addCrash(new Error('This is an error')); class CustomError extends Error { - constructor(message, code, data) { + code?: string | number; + data?: any; + + constructor(message: string, code?: string | number, data?: any) { super(message); this.code = code; this.data = data; @@ -350,9 +354,9 @@ describe('Telemetry', () => { this.timeout(10000); this.slow(8000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -378,9 +382,9 @@ describe('Telemetry', () => { this.timeout(10000); this.slow(8000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -396,7 +400,7 @@ describe('Telemetry', () => { try { process.kill(luckyPid, 0); // try again :( - } catch (e) { + } catch (e: any) { // bingo! fs.writeFileSync(path.join(appDir, '.lock'), String(luckyPid)); break; @@ -415,9 +419,9 @@ describe('Telemetry', () => { this.timeout(10000); this.slow(8000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -448,7 +452,7 @@ describe('Telemetry', () => { const posts = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -480,9 +484,9 @@ describe('Telemetry', () => { this.timeout(10000); this.slow(8000); - const posts = []; + const posts: any = []; this.server = await createTelemetryServer({ - onEvent(payload) { + onEvent(payload: any) { posts.push(payload); } }); @@ -493,7 +497,7 @@ describe('Telemetry', () => { // rewrite the .sid to be expired const json = fs.readJsonSync(path.join(appDir, '.sid')); const { id } = json; - json.ts = new Date(new Date(json.ts) - 72 * 60 * 60 * 1000).toISOString(); + json.ts = new Date(Date.parse(json.ts) - 72 * 60 * 60 * 1000).toISOString(); fs.writeJsonSync(path.join(appDir, '.sid'), json); ({ appDir, telemetry } = createTelemetry()); @@ -515,7 +519,7 @@ describe('Telemetry', () => { this.slow(4000); // eslint-disable-next-line no-unused-vars - let { appDir, telemetry } = createTelemetry(); + let { appDir } = createTelemetry(); for (const filename of fs.readdirSync(appDir)) { if (filename.endsWith('.json')) { @@ -528,7 +532,7 @@ describe('Telemetry', () => { json.id = 'foo'; fs.writeJsonSync(path.join(appDir, '.sid'), json); - ({ appDir, telemetry } = createTelemetry()); + ({ appDir } = createTelemetry()); expect(fs.readdirSync(appDir)).to.have.lengthOf(3); // .hid, .sid (new), session.start json = fs.readJsonSync(path.join(appDir, '.sid')); expect(json.id).to.not.equal('foo'); @@ -540,7 +544,7 @@ describe('Telemetry', () => { process.env.AXWAY_TELEMETRY_DISABLED = '1'; - let { appDir, telemetry } = createTelemetry(); + const { appDir, telemetry } = createTelemetry(); expect(fs.readdirSync(appDir)).to.have.lengthOf(2); telemetry.addEvent({ event: 'foo.bar' }); diff --git a/packages/amplify-sdk/test/test-token-store.js b/packages/amplify-sdk/test/test-token-store.ts similarity index 92% rename from packages/amplify-sdk/test/test-token-store.js rename to packages/amplify-sdk/test/test-token-store.ts index 8b5a82bf..52f33088 100644 --- a/packages/amplify-sdk/test/test-token-store.js +++ b/packages/amplify-sdk/test/test-token-store.ts @@ -1,9 +1,11 @@ -/* eslint-disable no-unused-expressions */ +/* eslint-disable no-unused-expressions, node/no-unsupported-features/es-syntax, @typescript-eslint/no-unused-vars */ import fs from 'fs-extra'; import tmp from 'tmp'; -import { Auth, MemoryStore, TokenStore } from '../dist/index'; -import { createLoginServer, stopLoginServer } from './common'; +import { Auth, FileStore, MemoryStore, TokenStore } from '../src/index.js'; +import { createLoginServer, stopLoginServer } from './common.js'; +import { expect } from 'chai'; +import { Account } from '../src/types.js'; const isCI = process.env.CI || process.env.JENKINS; @@ -58,7 +60,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; tokens = await auth.list(); expect(tokens).to.have.lengthOf(1); @@ -92,7 +94,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; tokens = await auth.list(); expect(tokens).to.have.lengthOf(1); @@ -126,7 +128,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; tokens = await auth.list(); expect(tokens).to.have.lengthOf(1); @@ -162,7 +164,7 @@ describe('Token Store', () => { await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; tokens = await auth.list(); expect(tokens).to.have.lengthOf(1); @@ -177,7 +179,7 @@ describe('Token Store', () => { const store = new MemoryStore(); try { await store.get(); - } catch (e) { + } catch (e: any) { expect(e).to.be.instanceof(Error); expect(e.message).to.equal('Must specify either the account name or authenticator hash'); return; @@ -218,7 +220,7 @@ describe('Token Store', () => { tokenStoreDir, tokenStoreType: 'file' }); - const { tokenStoreFile } = auth.tokenStore; + const { tokenStoreFile } = auth.tokenStore as FileStore; let tokens = await auth.list(); expect(tokens).to.have.lengthOf(0); @@ -228,7 +230,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(fs.existsSync(tokenStoreFile)).to.be.true; @@ -259,7 +261,7 @@ describe('Token Store', () => { tokenStoreDir, tokenStoreType: 'file' }); - const { tokenStoreFile } = auth.tokenStore; + const { tokenStoreFile } = auth.tokenStore as FileStore; let tokens = await auth.list(); expect(tokens).to.have.lengthOf(0); @@ -269,7 +271,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(fs.existsSync(tokenStoreFile)).to.be.true; @@ -304,7 +306,7 @@ describe('Token Store', () => { tokenStoreDir, tokenStoreType: 'file' }); - const { tokenStoreFile } = auth.tokenStore; + const { tokenStoreFile } = auth.tokenStore as FileStore; let tokens = await auth.list(); expect(tokens).to.have.lengthOf(0); @@ -335,7 +337,8 @@ describe('Token Store', () => { afterEach(async () => { if (!isCI || process.platform !== 'linux') { - await require('keytar').deletePassword(secureServiceName, secureServiceName); + const { default: keytar }: any = await import('keytar'); + await keytar.deletePassword(secureServiceName, secureServiceName); } }); @@ -349,7 +352,7 @@ describe('Token Store', () => { tokenStoreDir: tmp.tmpNameSync({ prefix: 'test-amplify-sdk-' }), tokenStoreType: 'secure' }); - } catch (e) { + } catch (e: any) { expect(e).to.be.instanceof(TypeError); expect(e.message).to.equal('Secure store requires the home directory to be specified'); return; @@ -382,7 +385,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; tokens = await auth.list(); expect(tokens).to.have.lengthOf(1); @@ -423,7 +426,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; tokens = await auth.list(); expect(tokens).to.have.lengthOf(1); @@ -450,7 +453,7 @@ describe('Token Store', () => { baseUrl: 'http://127.0.0.1:1337', clientId: 'test_client', realm: 'test_realm', - tokenStore: '123' + tokenStore: '123' as any }); }).to.throw(TypeError, 'Expected the token store to be a "TokenStore" instance'); }); @@ -462,11 +465,12 @@ describe('Token Store', () => { let delCounter = 0; class Foo extends TokenStore { - delete() { + async delete(accounts: string | string[], baseUrl?: string): Promise { delCounter++; + return [] as Account[]; } - set() { + async set(data: Account): Promise { setCounter++; } } @@ -485,7 +489,7 @@ describe('Token Store', () => { const account = await auth.login({ username: 'foo', password: 'bar' - }); + }) as Account; expect(setCounter).to.equal(1); expect(delCounter).to.equal(0); diff --git a/packages/amplify-sdk/test/tsconfig.json b/packages/amplify-sdk/test/tsconfig.json new file mode 100644 index 00000000..40f5a110 --- /dev/null +++ b/packages/amplify-sdk/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": ".." + }, + "include": [ "./**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-sdk/tsconfig.json b/packages/amplify-sdk/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/amplify-sdk/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-utils/.gitignore b/packages/amplify-utils/.gitignore deleted file mode 100644 index 5882231e..00000000 --- a/packages/amplify-utils/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.DS_Store -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log diff --git a/packages/amplify-utils/.npmignore b/packages/amplify-utils/.npmignore index ecfa0b9f..31e4a680 100644 --- a/packages/amplify-utils/.npmignore +++ b/packages/amplify-utils/.npmignore @@ -1,4 +1,5 @@ ._* +.babelrc .DS_Store .eslintrc .git* @@ -11,8 +12,8 @@ junit.xml node_modules npm-debug.log retire_output.json +tsconfig.json +yarn.lock yarn-error.log -/sample /src /test -yarn.lock diff --git a/packages/amplify-utils/CHANGELOG.md b/packages/amplify-utils/CHANGELOG.md index 1e943d17..1975628a 100644 --- a/packages/amplify-utils/CHANGELOG.md +++ b/packages/amplify-utils/CHANGELOG.md @@ -1,3 +1,7 @@ +# v2.0.0 + + * BREAKING CHANGE: Dropped support for Node.js 12 and older. + # v1.0.9 (May 11, 2022) * chore: Updated dependencies. diff --git a/packages/amplify-utils/README.md b/packages/amplify-utils/README.md index 8bfd21c8..51843006 100644 --- a/packages/amplify-utils/README.md +++ b/packages/amplify-utils/README.md @@ -13,7 +13,9 @@ import { existsSync, isDir, isFile, - locate + mkdirpSync, + moveSync, + writeFileSync } from '@axway/amplify-utils'; console.log(existsSync('/path/to/something')); @@ -21,24 +23,17 @@ console.log(existsSync('/path/to/something')); console.log(isDir('/path/to/some/dir')); console.log(isFile('/path/to/some/file')); - -// recursively search a directory for a file up to a specified depth -console.log(locate('/path/to/some/dir', 'somefile', 2)); ``` ## path ```js import { - expandPath, - real + expandPath } from '@axway/amplify-utils'; // replace ~ with the user's home path and join any additional segments console.log(expandPath('~/foo', 'bar')); - -// resolves symlinks to real path, even if symlink is broken -console.log(real('/some/path')); ``` ## utils @@ -49,76 +44,6 @@ import { arch } from '@axway/amplify-utils'; console.log(arch()); // 'x86' or 'x64' ``` -```js -import { arrayify } from '@axway/amplify-utils'; - -console.log(arrayify('foo')); // [ 'foo' ] - -console.log(arrayify([ 'a', '', null, 'b' ], true)); // [ 'a', 'b' ] -``` - -```js -import { assertNodeEngineVersion } from '@axway/amplify-utils'; - -// throw an exception if current node version doesn't satisfy the `engines.node` version -assertNodeEngineVersion(require('package.json')); -``` - -```js -import { cache } from '@axway/amplify-utils'; - -const now = () => Date.now(); - -const first = await cache('my namespace', now); -const second = await cache('my namespace', now); -assert(first === second); - -const third = await cache('my namespace', true, now); -assert(first !== third && second !== third); -``` - -```js -import { cacheSync } from '@axway/amplify-utils'; - -const now = () => Date.now(); - -const first = cacheSync('my namespace', now); -const second = cacheSync('my namespace', now); -assert(first === second); - -const third = cacheSync('my namespace', true, now); -assert(first !== third && second !== third); -``` - -Debouncer that returns a promise and that can be cancelled. - -```js -import { debounce } from '@axway/amplify-utils'; - -const fn = debounce(() => { - console.log(new Date()); -}); - -// schedule the callback to be called in 200ms -fn().then(() => { - console.log('Function called'); -}); - -// cancel the debounce -fn.cancel(); -``` - -```js -import { formatNumber } from '@axway/amplify-utils'; - -console.log(formatNumber(12)); // 12 -console.log(formatNumber(123)); // 123 -console.log(formatNumber(1234)); // 1,234 -console.log(formatNumber(12345)); // 12,345 -console.log(formatNumber(123456)); // 123,456 -console.log(formatNumber(1234567)); // 1,234,567 -``` - ```js import { get } from '@axway/amplify-utils'; @@ -130,26 +55,6 @@ console.log(get(obj, 'foo')); // 'bar' console.log(get(obj, 'baz', 'pow')); // 'pow' ``` -Get all open sockets, [net] servers, timers, child processes, filesystem watchers, and other -handles. - -```js -import { getActiveHandles } from '@axway/amplify-utils'; - -console.log(getActiveHandles()); -``` - -```js -import { inherits } from '@axway/amplify-utils'; - -class A {} -class B extends A {} -class C {} - -console.log(inherits(B, A)); // true -console.log(inherits(B, C)); // false -``` - ```js import { mergeDeep } from '@axway/amplify-utils'; @@ -169,15 +74,9 @@ console.log(mergeDeep(obj1, obj2)); // { a: { b: 'c', d: 'e' } } ``` ```js -import { mutex } from '@axway/amplify-utils'; +import { osInfo } from '@axway/amplify-utils'; -const fn = () => { - return mutex('my mutex', () => { - console.log('foo!'); - }); -}; - -await Promise.all([ fn(), fn(), fn() ]); +console.log(osInfo()); ``` ```js @@ -187,36 +86,22 @@ console.log(randomBytes(20)); ``` ```js -import { sha1 } from '@axway/amplify-utils'; - -console.log(sha1('foo')); -``` - -```js -import { sleep } from '@axway/amplify-utils'; - -await sleep(1000); // sleep for 1 second -``` - -Block multiple simultaneous callers until the first caller finishes, then all queued up 'tailgaters' -are resolved with the result. - -```js -import { tailgate } from '@axway/amplify-utils'; +import { redact } from '@axway/amplify-utils'; -const fn = () => { - return tailgate('my tailgate', async () => { - console.log('I will only be called once'); - }); -}; - -await Promise.all([ fn(), fn(), fn() ]); -``` - -```js -import { unique } from '@axway/amplify-utils'; - -console.log(unique([ 'a', 'b', 'a', 'b' ])); // [ 'a', 'b' ] +console.log(redact({ + info: { + username: 'chris', + password: '123456', + desktop: '/Users/chris/Desktop' + } +})); +// { +// info: { +// username: '', // matches process.env.USER +// password: '', // matches blocked property +// desktop: '~/Desktop' // matches process.env.HOME +// } +// } ``` ## Legal diff --git a/packages/amplify-utils/gulpfile.js b/packages/amplify-utils/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/amplify-utils/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/amplify-utils/package.json b/packages/amplify-utils/package.json index 830e3305..94544be2 100644 --- a/packages/amplify-utils/package.json +++ b/packages/amplify-utils/package.json @@ -5,6 +5,9 @@ "access": "public" }, "description": "Axway Amplify utility library", + "type": "module", + "exports": "./dist/index.js", + "types": "./dist", "author": "Axway, Inc. ", "maintainers": [ "Chris Barber " @@ -14,23 +17,22 @@ "axway", "amplify" ], - "main": "./dist/index", "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "c8 npm run test", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:test npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:test": "eslint --parser-options=project:'test/tsconfig.json' test/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "ts-mocha -n loader=ts-node/esm test/**/test-*.ts --require ../../test/setup.js --reporter spec" }, "dependencies": { "lodash.get": "^4.4.2", "lodash.set": "^4.3.2", - "semver": "^7.3.7", - "source-map-support": "^0.5.21", - "tmp": "^0.2.1" + "semver": "^7.3.7" }, "devDependencies": { - "@axway/gulp-tasks": "^4.1.4", "fs-extra": "^10.1.0", "tmp": "^0.2.1" }, @@ -38,6 +40,6 @@ "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/amplify-utils", "engines": { - "node": ">=12.13.0" + "node": ">=14.15.0" } } diff --git a/packages/amplify-utils/src/fs.js b/packages/amplify-utils/src/fs.ts similarity index 68% rename from packages/amplify-utils/src/fs.js rename to packages/amplify-utils/src/fs.ts index 5152e20d..2267d9c4 100644 --- a/packages/amplify-utils/src/fs.js +++ b/packages/amplify-utils/src/fs.ts @@ -1,6 +1,12 @@ import fs from 'fs'; import path from 'path'; +type ExecuteOptions = { + applyOwner?: boolean, + gid?: number, + uid?: number +} + /** * Determines owner of existing parent directory, calls the operation's function, then applies the * owner to the destination and its newly created parent directories. @@ -13,7 +19,7 @@ import path from 'path'; * @param {Number} [opts.uid] - The user id to apply to the file when assigning an owner. * @param {Function} fn - A function to call to perform the original filesystem operation. */ -function execute(dest, opts, fn) { +function execute(dest: string, opts: ExecuteOptions, fn: (opts: ExecuteOptions) => void) { if (opts.applyOwner === false || process.platform === 'win32' || !process.getuid || process.getuid() !== 0) { fn(opts); return; @@ -42,7 +48,7 @@ function execute(dest, opts, fn) { let stat = fs.lstatSync(dest); while (dest !== origin && stat.uid !== opts.uid) { try { - chownSync(dest, opts.uid, opts.gid); + chownSync(dest, opts.uid as number, opts.gid as number); dest = path.dirname(dest); stat = fs.lstatSync(dest); } catch (e) { @@ -57,7 +63,7 @@ function execute(dest, opts, fn) { * @param {String} file - The full path to check if exists. * @returns {Boolean} */ -export function existsSync(file) { +export function existsSync(file: string) { try { fs.statSync(file); return true; @@ -72,7 +78,7 @@ export function existsSync(file) { * @param {String} dir - The directory to check. * @returns {Boolean} */ -export function isDir(dir) { +export function isDir(dir: string) { try { return fs.statSync(dir).isDirectory(); } catch (e) { @@ -87,7 +93,7 @@ export function isDir(dir) { * @param {String} file - The file to check. * @returns {Boolean} */ -export function isFile(file) { +export function isFile(file: string) { try { return fs.statSync(file).isFile(); } catch (e) { @@ -96,42 +102,6 @@ export function isFile(file) { return false; } -/** - * Scan a directory for a specified file. - * - * @param {String} dir - The directory to start searching from. - * @param {String|RegExp} filename - The name of the file to look for. - * @param {Number} depth - Optional search depth, default 1 level. - * @returns {String|null} - */ -export function locate(dir, filename, depth) { - try { - if (fs.statSync(dir).isDirectory()) { - for (const name of fs.readdirSync(dir)) { - const file = path.join(dir, name); - try { - /* eslint-disable max-depth */ - if (fs.statSync(file).isDirectory()) { - if (typeof depth === 'undefined' || depth > 0) { - const result = locate(file, filename, typeof depth === 'undefined' ? undefined : depth - 1); - if (result) { - return result; - } - } - } else if ((typeof filename === 'string' && name === filename) || (filename instanceof RegExp && filename.test(name))) { - return file; - } - } catch (e) { - // probably a permission issue, go to next file - } - } - } - } catch (e) { - // dir does not exist or permission issue - } - return null; -} - /** * Creates a directory and any parent directories if needed. * @@ -142,7 +112,7 @@ export function locate(dir, filename, depth) { * @param {Number} [opts.gid] - The group id to apply to the file when assigning an owner. * @param {Number} [opts.uid] - The user id to apply to the file when assigning an owner. */ -export function mkdirpSync(dest, opts = {}) { +export function mkdirpSync(dest: string, opts = {}) { execute(dest, opts, opts => { fs.mkdirSync(dest, { mode: 0o777, ...opts, recursive: true }); }); @@ -160,42 +130,13 @@ export function mkdirpSync(dest, opts = {}) { * @param {Number} [opts.gid] - The group id to apply to the file when assigning an owner. * @param {Number} [opts.uid] - The user id to apply to the file when assigning an owner. */ -export function moveSync(src, dest, opts = {}) { +export function moveSync(src: string, dest: string, opts = {}) { execute(dest, opts, opts => { mkdirpSync(path.dirname(dest), opts); fs.renameSync(src, dest); }); } -/** - * Read a directory including scoped packages as a single entry in the Array - * and filtering out all files. - * - * @param {String} dir - Directory to read. - * @returns {Array} - */ -export function readdirScopedSync(dir) { - const children = []; - - for (const name of fs.readdirSync(dir)) { - const childPath = path.join(dir, name); - if (!isDir(childPath)) { - continue; - } - if (name.charAt(0) === '@') { - for (const scopedPackage of fs.readdirSync(childPath)) { - if (isDir(path.join(childPath, scopedPackage))) { - children.push(`${name}/${scopedPackage}`); - } - } - } else { - children.push(name); - } - } - - return children; -} - /** * Writes a file to disk. * @@ -208,9 +149,9 @@ export function readdirScopedSync(dir) { * @param {Number} [opts.gid] - The group id to apply to the file when assigning an owner. * @param {Number} [opts.uid] - The user id to apply to the file when assigning an owner. */ -export function writeFileSync(dest, contents, opts = {}) { +export function writeFileSync(dest: string, contents: string, opts = {}) { execute(dest, opts, opts => { mkdirpSync(path.dirname(dest), { ...opts, mode: undefined }); - fs.writeFileSync(dest, contents, opts); + fs.writeFileSync(dest, contents, opts as object); }); } diff --git a/packages/amplify-utils/src/index.js b/packages/amplify-utils/src/index.js deleted file mode 100644 index d08a7820..00000000 --- a/packages/amplify-utils/src/index.js +++ /dev/null @@ -1,9 +0,0 @@ -/* istanbul ignore if */ -if (!Error.prepareStackTrace) { - require('source-map-support/register'); -} - -export * from './fs'; -export * from './path'; -export * from './util'; - diff --git a/packages/amplify-utils/src/index.ts b/packages/amplify-utils/src/index.ts new file mode 100644 index 00000000..c1af26c5 --- /dev/null +++ b/packages/amplify-utils/src/index.ts @@ -0,0 +1,3 @@ +export * from './fs.js'; +export * from './path.js'; +export * from './util.js'; diff --git a/packages/amplify-utils/src/path.js b/packages/amplify-utils/src/path.js deleted file mode 100644 index 728c8d51..00000000 --- a/packages/amplify-utils/src/path.js +++ /dev/null @@ -1,67 +0,0 @@ -import fs from 'fs'; -import _path from 'path'; - -const homeDirRegExp = /^~([\\|/].*)?$/; -const winRegExp = /^win/; -const winEnvVarRegExp = /(%([^%]*)%)/g; - -/** - * Resolves a path into an absolute path. - * - * @param {...String} segments - The path segments to join and resolve. - * @returns {String} - */ -export function expandPath(...segments) { - const platform = process.env.AXWAY_TEST_PLATFORM || process.platform; - segments[0] = segments[0].replace(homeDirRegExp, (process.env.HOME || process.env.USERPROFILE) + '$1'); - if (winRegExp.test(platform)) { - return _path.resolve(_path.join.apply(null, segments).replace(winEnvVarRegExp, (s, m, n) => { - return process.env[n] || m; - })); - } - return _path.resolve.apply(null, segments); -} - -/** - * Determines a path's real path by walking from the root to target while resolving symlinks and - * reconstructing the path. If a path does not exist, it simply appends everything - * - * @param {String} path - The path to resolve. - * @returns {String} - */ -export function real(path) { - path = expandPath(path); - - const { root } = _path.parse(path); - const dirs = []; - let dir; - - // chop up the path - while (path !== root) { - dirs.unshift(_path.basename(path)); - path = _path.dirname(path); - } - - // reset path to the root - path = root; - - // walk the dirs and construct the real path - while (dir = dirs.shift()) { - const current = _path.join(path, dir); - try { - if (fs.lstatSync(current).isSymbolicLink()) { - const link = fs.readlinkSync(current); - path = _path.isAbsolute(link) ? real(link) : _path.resolve(path, link); - } else { - path = current; - } - } catch (e) { - // current does not exist which means all subdirectories also do not exist, so just - // stitch everything back together - return _path.resolve(current, ...dirs); - } - } - - // resolve any relative symlinks we joined together - return path; -} diff --git a/packages/amplify-utils/src/path.ts b/packages/amplify-utils/src/path.ts new file mode 100644 index 00000000..69c93e00 --- /dev/null +++ b/packages/amplify-utils/src/path.ts @@ -0,0 +1,22 @@ +import _path from 'path'; + +const homeDirRegExp = /^~([\\|/].*)?$/; +const winRegExp = /^win/; +const winEnvVarRegExp = /(%([^%]*)%)/g; + +/** + * Resolves a path into an absolute path. + * + * @param {...String} segments - The path segments to join and resolve. + * @returns {String} + */ +export function expandPath(...segments: string[]) : string { + const platform = process.env.AXWAY_TEST_PLATFORM || process.platform; + segments[0] = segments[0].replace(homeDirRegExp, (process.env.HOME || process.env.USERPROFILE) + '$1'); + if (winRegExp.test(platform)) { + return _path.resolve(_path.join.apply(null, segments).replace(winEnvVarRegExp, (s, m, n) => { + return process.env[n] || m; + })); + } + return _path.resolve.apply(null, segments); +} diff --git a/packages/amplify-utils/src/util.js b/packages/amplify-utils/src/util.js deleted file mode 100644 index 97c72a84..00000000 --- a/packages/amplify-utils/src/util.js +++ /dev/null @@ -1,905 +0,0 @@ -/* eslint-disable node/no-deprecated-api, no-new-func */ - -import crypto from 'crypto'; -import fs from 'fs'; -import get from 'lodash.get'; -import set from 'lodash.set'; -import semver from 'semver'; - -import { ChildProcess, execSync, spawnSync } from 'child_process'; -import { EventEmitter } from 'events'; -import { homedir } from 'os'; -import { isFile } from './fs'; -import { Server, Socket } from 'net'; - -function getBinding(name) { - try { - return process.binding(name); - } catch (e) { - // squelch - } - return {}; -} -const { FSEvent } = getBinding('fs_event_wrap'); -const { Timer } = getBinding('timer_wrap'); - -let archCache = null; - -/** - * Returns the current machine's architecture. Possible values are `x64` for 64-bit and `x86` for - * 32-bit (i386/ia32) systems. - * - * @param {Boolean} bypassCache=false - When true, re-detects the system architecture, though it - * will never change. - * @returns {String} - */ -export function arch(bypassCache) { - if (archCache && !bypassCache) { - return archCache; - } - - // we cache the architecture since it never changes - const platform = process.env.AXWAY_TEST_PLATFORM || process.platform; - archCache = process.env.AXWAY_TEST_ARCH || process.arch; - - if (archCache === 'ia32') { - if ((platform === 'win32' && process.env.PROCESSOR_ARCHITEW6432) - || (platform === 'linux' && /64/.test(execSync('getconf LONG_BIT')))) { - // it's actually 64-bit - archCache = 'x64'; - } else { - archCache = 'x86'; - } - } - - return archCache; -} - -/** - * Ensures that a value is an array. If not, it wraps the value in an array. - * - * @param {*} it - The value to ensure is an array. - * @param {Boolean} [removeFalsey=false] - When `true`, filters out all falsey items. - * @returns {Array} - */ -export function arrayify(it, removeFalsey) { - const arr = typeof it === 'undefined' ? [] : it instanceof Set ? Array.from(it) : Array.isArray(it) ? it : [ it ]; - return removeFalsey ? arr.filter(v => typeof v !== 'undefined' && v !== null && v !== '' && v !== false && (typeof v !== 'number' || !isNaN(v))) : arr; -} - -/** - * Validates that the current Node.js version strictly equals the Node engine version in the - * specified package.json. - * - * @param {Object|String} pkgJson - The pkgJson object or the path to the package.json file. - * @returns {Boolean} Returns `true` if the current Node.js version is the exact version required, - * otherwise throws an error. - * @throws {Error} Either the package.json cannot be parsed or the current Node.js version does not - * satisfy the required version. - */ -export function assertNodeEngineVersion(pkgJson) { - if (!pkgJson) { - throw new TypeError('Expected pkgJson to be an object or string to a package.json file'); - } - - if (typeof pkgJson === 'string') { - if (!isFile(pkgJson)) { - throw new Error(`File does not exist: ${pkgJson}`); - } - - try { - pkgJson = JSON.parse(fs.readFileSync(pkgJson, 'utf8')); - } catch (e) { - throw new Error(`Unable to parse package.json: ${e.message}`); - } - } else if (typeof pkgJson !== 'object' || Array.isArray(pkgJson)) { - throw new TypeError('Expected pkgJson to be an object or string to a package.json file'); - } - - const current = process.env.AXWAY_TEST_NODE_VERSION || process.version; - const required = pkgJson?.engines?.node; - - try { - if (!required || semver.eq(current, required)) { - return true; - } - } catch (e) { - throw new Error(`Invalid Node engine version in package.json: ${required}`); - } - - throw new Error(`Requires Node.js '${required}', but the current version is '${current}'`); -} - -/** - * A map of store names to cached results. - * @type {Object} - */ -const cacheStore = {}; - -/** - * Calls a function and caches the result for future calls. - * - * @param {String} name - The name to cache the result under. - * @param {Boolean} [force] - When `true` skips the cache and invokes the function. - * @param {Function} callback - A function to call to get results. - * @returns {Promise<*>} Resolves whatever value `callback` returns/resolves. - */ -export async function cache(name, force, callback) { - await new Promise(setImmediate); - - if (typeof force === 'function') { - callback = force; - force = false; - } - - if (!force && cacheStore[name]) { - return cacheStore[name]; - } - - return cacheStore[name] = await tailgate(name, callback); -} - -/** - * Calls a synchronous function and caches the result for future calls. - * - * @param {String} name - The name to cache the result under. - * @param {Boolean} [force] - When `true` skips the cache and invokes the function. - * @param {Function} callback - A function to call to get results. - * @returns {*} Returns whatever value `callback` returns. - */ -export function cacheSync(name, force, callback) { - if (typeof force === 'function') { - callback = force; - force = false; - } - - if (typeof name !== 'string' || !name) { - throw new TypeError('Expected name to be a non-empty string'); - } - - if (typeof callback !== 'function') { - throw new TypeError('Expected callback to be a function'); - } - - if (!force && cacheStore[name]) { - return cacheStore[name]; - } - - return cacheStore[name] = callback(); -} - -/** - * Prevents a function from being called too many times. This function returns a function that can - * be used in a promise chain. - * - * @param {Function} fn - The function to debounce. - * @param {Number} [wait=200] - The number of milliseconds to wait between calls to the returned - * function before firing the specified `fn`. - * @returns {Function} - */ -export function debounce(fn, wait = 200) { - let timer; - wait = Math.max(~~wait, 0); - - let resolveFn; - let rejectFn; - const promise = new Promise((resolve, reject) => { - resolveFn = resolve; - rejectFn = reject; - }); - - function debouncer(...args) { - const ctx = this; - clearTimeout(timer); - - timer = setTimeout(() => { - timer = null; - Promise.resolve() - .then(() => fn.apply(ctx, args)) - .then(resolveFn) - .catch(rejectFn); - }, wait); - - return promise; - } - - debouncer.cancel = function cancel() { - clearTimeout(timer); - timer = null; - }; - - return debouncer; -} - -/** - * Decodes an string with octals to a utf-8 string. - * - * @param {String} input - The string to decode - * @returns {String} The decoded string - */ -export function decodeOctalUTF8(input) { - let result = ''; - let i = 0; - const l = input.length; - let c; - let octByte; - - for (; i < l; i++) { - c = input.charAt(i); - if (c === '\\') { - octByte = input.substring(i + 1, i + 4); - try { - result += String.fromCharCode(parseInt(octByte, 8)); - i += 3; - } catch (e) { - result += '\\'; - input = octByte + input; - } - } else { - result += c; - } - } - - return decodeURIComponent(escape(result)); -} - -/** - * Formats a number using commas. - * - * @param {Number} n - The number to format. - * @returns {String} - */ -export function formatNumber(n) { - return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ','); -} - -/** - * Re-export of lodash's `get()` function. - * - * For more information, visit {@link https://www.npmjs.com/package/lodash.get} or - * {@link https://lodash.com/docs/4.17.15#get}. - * - * @param {Object} obj - The object to query. - * @param {Array.|String} [path] - The path of the property to get. - * @param {*} [defaultValue] - The value returned for `undefined` resolved values. - * @returns {*} - */ -export { get }; - -/** - * Returns an object with active socket, server, timer, and other handles. - * - * @returns {Object} - */ -export function getActiveHandles() { - const handles = { sockets: [], servers: [], timers: [], childProcesses: [], fsWatchers: [], other: [] }; - - if (typeof process._getActiveHandles === 'function') { - for (let handle of process._getActiveHandles()) { - if (Timer && handle instanceof Timer) { - const timerList = handle._list || handle; - let t = timerList._idleNext; - while (t !== timerList) { - handles.timers.push(t); - t = t._idleNext; - } - } else if (handle instanceof Socket) { - handles.sockets.push(handle); - } else if (handle instanceof Server) { - handles.servers.push(handle); - } else if (handle instanceof ChildProcess) { - handles.childProcesses.push(handle); - } else if (handle instanceof EventEmitter && typeof handle.start === 'function' && typeof handle.close === 'function' && FSEvent && handle._handle instanceof FSEvent) { - handles.fsWatchers.push(handle); - } else { - handles.other.push(handle); - } - } - } - - return handles; -} - -/** - * Determines if a class extends another class. - * - * @param {Class|Function} subject - The class to check. - * @param {Class|Function|null} base - The base class to look for. - * @returns {Boolean} - */ -export function inherits(subject, base) { - if (typeof subject !== 'function') { - throw new TypeError('Expected subject to be a function object'); - } - - if (base !== null && typeof base !== 'function') { - throw new TypeError('Expected base class to be a function object'); - } - - let proto = Object.getPrototypeOf(subject); - while (proto !== Function.prototype) { - if (proto === base) { - return true; - } - proto = Object.getPrototypeOf(proto); - } - - if (base === Object.getPrototypeOf(subject.prototype)) { - return true; - } - - return false; -} - -/** - * Removes non-serializable properties and circular references from a value such that it can be - * printed, sent over an IPC channel, or JSON stringified. - * - * @param {*} it - The value to serialize. - * @returns {*} - */ -export function makeSerializable(it) { - return (function dupe (src, chain = []) { - const type = typeof src; - - if (type === 'number' && isNaN(src)) { - return null; - } - - if (src === null || type === 'string' || type === 'number' || type === 'boolean' || src instanceof Date) { - return src; - } - - if (type === 'object') { - if (chain.includes(src)) { - return; - } - - let result; - - chain.push(src); - - if (Array.isArray(src)) { - result = src.map(it => dupe(it, chain)); - } else { - result = {}; - for (let [ key, value ] of Object.entries(src)) { - result[key] = dupe(value, chain); - } - } - - chain.pop(); - - return result; - } - }(it)); -} - -/** - * Deeply merges two JavaScript objects. - * - * @param {Object} dest - The object to copy the source into. - * @param {Object} src - The object to copy. - * @returns {Object} Returns the dest object. - */ -export function mergeDeep(dest, src) { - if (typeof dest !== 'object' || dest === null || Array.isArray(dest)) { - dest = {}; - } - - if (typeof src !== 'object' || src === null || Array.isArray(src)) { - return dest; - } - - for (const key of Object.keys(src)) { - const value = src[key]; - if (Array.isArray(value)) { - if (Array.isArray(dest[key])) { - dest[key].push.apply(dest[key], value); - } else { - dest[key] = value.slice(); - } - } else if (typeof value === 'object' && value !== null) { - if (typeof dest[key] !== 'object' || dest[key] === null || Array.isArray(dest[key])) { - dest[key] = {}; - } - mergeDeep(dest[key], value); - } else if (typeof value !== 'undefined') { - dest[key] = value; - } - } - - return dest; -} - -/** - * A map of mutex names to each caller's function and promise callbacks. - * @type {Object} - */ -export const pendingMutexes = {}; - -/** - * Ensures that a function is only executed by a single task at a time. If the function is currently - * being run, then additional requests are queued and areexecuted in order when the function - * completes. - * - * @param {String} name - The mutex name. - * @param {Function} callback - A function to call mutually exclusive. - * @returns {Promise} Resolves whatever value `callback` returns/resolves. - */ -export async function mutex(name, callback) { - return new Promise((resolve, reject) => { - // we want this promise to resolve as soon as `callback()` finishes - if (typeof name !== 'string' || !name) { - return reject(new TypeError('Expected name to be a non-empty string')); - } - - if (typeof callback !== 'function') { - return reject(new TypeError('Expected callback to be a function')); - } - - // if another function is current running, add this function to the queue and wait - if (pendingMutexes[name]) { - pendingMutexes[name].push({ callback, resolve, reject }); - return; - } - - // init the queue - pendingMutexes[name] = [ { callback, resolve, reject } ]; - - // start a recursive function that drains the queue - (async function next() { - const pending = pendingMutexes[name] && pendingMutexes[name].shift(); - if (!pending) { - // all done - delete pendingMutexes[name]; - return; - } - - // call the function - try { - const result = await pending.callback(); - pending.resolve(result); - } catch (err) { - pending.reject(err); - } finally { - next(); - } - }()); - }); -} - -/** - * Tries to resolve the operating system name and version. - * - * @returns {Object} - */ -export function osInfo() { - let name = null; - let version = null; - - switch (process.platform) { - case 'darwin': - { - const stdout = spawnSync('sw_vers').stdout.toString(); - let m = stdout.match(/ProductName:\s+(.+)/i); - if (m) { - name = m[1]; - } - m = stdout.match(/ProductVersion:\s+(.+)/i); - if (m) { - version = m[1]; - } - } - break; - - case 'linux': - name = 'GNU/Linux'; - - if (isFile('/etc/lsb-release')) { - const contents = fs.readFileSync('/etc/lsb-release', 'utf8'); - let m = contents.match(/DISTRIB_DESCRIPTION=(.+)/i); - if (m) { - name = m[1].replace(/"/g, ''); - } - m = contents.match(/DISTRIB_RELEASE=(.+)/i); - if (m) { - version = m[1].replace(/"/g, ''); - } - } else if (isFile('/etc/system-release')) { - const parts = fs.readFileSync('/etc/system-release', 'utf8').split(' '); - if (parts[0]) { - name = parts[0]; - } - if (parts[2]) { - version = parts[2]; - } - } - break; - - case 'win32': - { - const stdout = spawnSync('wmic', [ 'os', 'get', 'Caption,Version' ]).stdout.toString(); - const s = stdout.split('\n')[1].split(/ {2,}/); - if (s.length > 0) { - name = s[0].trim() || 'Windows'; - } - if (s.length > 1) { - version = s[1].trim() || ''; - } - } - break; - } - - return { - name, - version - }; -} - -/** - * Returns the specified number of random bytes as a hex string. - * - * @param {Number} howMany - The number of random bytes to generate. Must be greater than or equal - * to zero. - * @returns {String} - */ -export function randomBytes(howMany) { - return crypto.randomBytes(Math.max(~~howMany, 0)).toString('hex'); -} - -/** - * A lookup of various properties that must be redacted during log message serialization. - * @type {Array.} - */ -const mandatoryRedactedProps = [ - /clientsecret/i, - /password/i -]; - -/** - * A list of regexes that will trigger the entire string to be redacted. - * @type {Array.} - */ -const mandatoryRedactionTriggers = [ - /password/i -]; - -/** - * A list of string replacement arguments. - * @type {Array.} - */ -const mandatoryReplacements = [ - [ homedir(), '' ], - process.env.USER, // macOS, Linux - process.env.USERNAME, // Windows - /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g // email address -]; - -/** - * Scrubs any potentially sensitive data from a value. By default, if the source is an object, it - * will be mutated. Redacted properties or elements will not be removed. - * - * @param {*} data - The source object to copy from. - * @param {Object} [opts] - Various options. - * @param {Boolean} [opts.clone] - When `true`, objects and arrays are cloned instead of mutated. - * @param {Array|Set} [opts.props] - A list of properties to redact. - * @param {String} [opts.redacted=""] - The string to replace redacted words with. - * @param {Array|Set} [opts.replacements] - A list of replacement criteria and an optional value. - * @param {Array|Set} [opts.triggers] - A list of keywords that cause an entire string to be - * redacted. - * @returns {*} - * - * @example - * > redact('foo') - * 'foo' - * - * @example - * > redact('my password is 123456') - * '' - * - * @example - * > redact({ - * info: { - * username: 'chris', - * password: '123456, - * desktop: '/Users/chris/Desktop' - * } - * }) - * { - * info: { - * username: '', // matches process.env.USER - * password: '', // matches blocked property - * desktop: '~/Desktop' // matches process.env.HOME - * } - * } - */ -export function redact(data, opts = {}) { - if (!opts || typeof opts !== 'object') { - throw new TypeError('Expected options to be an object'); - } - - const redacted = opts.redacted || ''; - - const init = (key, value) => { - if (Array.isArray(opts[key]) || opts[key] instanceof Set) { - for (const item of opts[key]) { - if (item && typeof item === 'string') { - value.push(new Function('s', `return s === ${JSON.stringify(item.toLowerCase())}`)); - } else if (item instanceof RegExp) { - value.push(item.test.bind(item)); - } else { - throw new TypeError(`Expected ${key} to be a set or array of strings or regexes`); - } - } - } else if (opts[key]) { - throw new TypeError(`Expected ${key} to be a set or array of strings or regexes`); - } - return value; - }; - - const props = init('props', mandatoryRedactedProps.map(re => re.test.bind(re))); - const triggers = init('triggers', mandatoryRedactionTriggers.map(re => re.test.bind(re))); - - // init the replacements - const replacementMap = new Map(); - const addReplacement = replacements => { - if (Array.isArray(replacements) || replacements instanceof Set) { - for (const replacement of replacements) { - let pattern, value; - if (!replacement) { - continue; - } else if (Array.isArray(replacement)) { - ([ pattern, value ] = replacement); - } else if (replacement && (typeof replacement === 'string' || replacement instanceof RegExp)) { - pattern = replacement; - } else { - throw new TypeError('Expected replacements to be an array of replace arguments'); - } - const key = pattern; - if (!(pattern instanceof RegExp)) { - // eslint-disable-next-line security/detect-non-literal-regexp - pattern = new RegExp(pattern.replace(/\\/g, '\\\\'), 'ig'); - } - if (value === undefined || value === null) { - value = redacted; - } - replacementMap.set(key, s => s.replace(pattern, value)); - } - } else if (replacements) { - throw new TypeError('Expected replacements to be an array of replace arguments'); - } - }; - addReplacement(mandatoryReplacements); - addReplacement(opts.replacements); - const replacements = Array.from(replacementMap.values()); - - // recursively walk the value and return the result - return (function scrub(src) { - let dest = src; - if (Array.isArray(src)) { - dest = opts.clone ? [] : src; - for (let i = 0, len = src.length; i < len; i++) { - dest[i] = scrub(src[i]); - } - } else if (src && typeof src === 'object') { - dest = opts.clone ? {} : src; - for (const [ key, value ] of Object.entries(src)) { - let match = false; - for (const test of props) { - if (match = test(key)) { - dest[key] = redacted; - break; - } - } - // if we found a match, then we just redacted the whole string and there's no need - // to scrub it - if (!match) { - dest[key] = scrub(value); - } - } - } else if (src && typeof src === 'string') { - for (const replace of replacements) { - dest = replace(dest); - if (dest === redacted) { - break; - } - } - for (const test of triggers) { - if (test(dest)) { - dest = redacted; - break; - } - } - } - return dest; - }(data)); -} - -/** - * Re-export of lodash's `set()` function. - * - * For more information, visit {@link https://www.npmjs.com/package/lodash.set} or - * {@link https://lodash.com/docs/4.17.15#set}. - * - * @param {Object} obj - The object to modify. - * @param {Array.|String} [path] - The path of the property to set. - * @param {*} [defaultValue] - The value to set. - * @returns {*} - */ -export { set }; - -/** - * Returns the sha1 of the specified buffer or string. - * - * @param {Buffer|String} data - The buffer or string to hash. - * @returns {String} - */ -export function sha1(data) { - return crypto.createHash('sha1').update(Buffer.isBuffer(data) || typeof data === 'string' ? data : JSON.stringify(data)).digest('hex'); -} - -/** - * Waits a number of milliseconds, then resolves the promise. - * - * @param {Number} ms - The number of milliseconds to wait. - * @returns {Promise} - */ -export function sleep(ms) { - return new Promise(resolve => { - if (typeof ms !== 'number') { - throw new TypeError('Expected timeout milliseconds to be a number'); - } - - if (ms < 0) { - throw new RangeError('Expected timeout milliseconds to be greater than or equal to zero'); - } - - setTimeout(() => resolve(), ms); - }); -} - -/** - * A map of tailgate names to each caller's promise callbacks. - * @type {Object} - */ -export const pendingTailgaters = {}; - -/** - * Ensures that only a function is executed by a single task at a time. If a task is already - * running, then additional requests are queued. When the task completes, the result is immediately - * shared with the queued up callers. - * - * @param {String} name - The tailgate name. - * @param {Function} callback - A function to call to get results. - * @returns {Promise} Resolves whatever value `callback` returns/resolves. - */ -export function tailgate(name, callback) { - // ensure this function is async - return new Promise((resolve, reject) => { - // we want this promise to resolve as soon as `callback()` finishes - if (typeof name !== 'string' || !name) { - return reject(new TypeError('Expected name to be a non-empty string')); - } - - if (typeof callback !== 'function') { - return reject(new TypeError('Expected callback to be a function')); - } - - // if another function is current running, add this function to the queue and wait - if (pendingTailgaters[name]) { - pendingTailgaters[name].push({ resolve, reject }); - return; - } - - // init the queue - pendingTailgaters[name] = [ { resolve, reject } ]; - - const dispatch = (type, result) => { - const pending = pendingTailgaters[name]; - delete pendingTailgaters[name]; - for (const p of pending) { - p[type](result); - } - }; - - // call the function - let result; - try { - result = callback(); - } catch (err) { - return dispatch('reject', err); - } - - if (result instanceof Promise) { - result - .then(result => dispatch('resolve', result)) - .catch(err => dispatch('reject', err)); - } else { - dispatch('resolve', result); - } - }); -} - -let activeTimers = {}; -let trackTimerAsyncHook; -let trackTimerWatchers = 0; - -/** - * Starts tracking all active timers. Calling the returned callback will stop watching and return - * a list of all active timers. - * - * @returns {Function} - */ -export function trackTimers() { - if (!trackTimerAsyncHook) { - try { - // try to initialize the async hook - trackTimerAsyncHook = require('async_hooks') - .createHook({ - init(asyncId, type, triggerAsyncId, resource) { - if (type === 'Timeout') { - activeTimers[asyncId] = resource; - } - }, - destroy(asyncId) { - delete activeTimers[asyncId]; - } - }); - } catch (e) { - // squelch - } - } - - if (trackTimerAsyncHook && trackTimerWatchers === 0) { - trackTimerAsyncHook.enable(); - } - - trackTimerWatchers++; - - // result cache just in case stop is called multiple times - let result; - - // return the stop tracking callback - return () => { - if (!result) { - trackTimerWatchers--; - - if (trackTimerAsyncHook) { - result = Object.values(activeTimers); - if (trackTimerWatchers === 0) { - trackTimerAsyncHook.disable(); - // reset the active timers now that we disabled the async hook - activeTimers = {}; - } - } else { - result = getActiveHandles().timers; - } - } - - return result; - }; -} - -/** - * Removes duplicates from an array and returns a new array. - * - * @param {Array} arr - The array to remove duplicates. - * @returns {Array} - */ -export function unique(arr) { - const len = Array.isArray(arr) ? arr.length : 0; - - if (len === 0) { - return []; - } - - return arr.reduce((prev, cur) => { - if (typeof cur !== 'undefined' && cur !== null) { - if (prev.indexOf(cur) === -1) { - prev.push(cur); - } - } - return prev; - }, []); -} diff --git a/packages/amplify-utils/src/util.ts b/packages/amplify-utils/src/util.ts new file mode 100644 index 00000000..b0ebd271 --- /dev/null +++ b/packages/amplify-utils/src/util.ts @@ -0,0 +1,374 @@ +/* eslint-disable node/no-deprecated-api, no-new-func */ + +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import get from 'lodash.get'; +import set from 'lodash.set'; + +import { execSync, spawnSync } from 'child_process'; +import { homedir } from 'os'; +import { isFile } from './fs.js'; + +let archCache: string | null = null; + +/** + * Returns the current machine's architecture. Possible values are `x64` for 64-bit and `x86` for + * 32-bit (i386/ia32) systems. + * + * @param {Boolean} bypassCache=false - When true, re-detects the system architecture, though it + * will never change. + * @returns {String} + */ +export function arch(bypassCache = false) : string { + if (archCache && !bypassCache) { + return archCache; + } + + // we cache the architecture since it never changes + const platform = process.env.AXWAY_TEST_PLATFORM || process.platform; + archCache = process.env.AXWAY_TEST_ARCH || process.arch; + + if (archCache === 'ia32') { + if ((platform === 'win32' && process.env.PROCESSOR_ARCHITEW6432) + || (platform === 'linux' && /64/.test(execSync('getconf LONG_BIT', { encoding: 'utf8' })))) { + // it's actually 64-bit + archCache = 'x64'; + } else { + archCache = 'x86'; + } + } + + return archCache; +} + +/** + * Re-export of lodash's `get()` function. + * + * For more information, visit {@link https://www.npmjs.com/package/lodash.get} or + * {@link https://lodash.com/docs/4.17.15#get}. + * + * @param {Object} obj - The object to query. + * @param {Array.|String} [path] - The path of the property to get. + * @param {*} [defaultValue] - The value returned for `undefined` resolved values. + * @returns {*} + */ +export { get }; + +type MergeTarget = { [key: string]: any }; +type MergeSource = { [key: string]: any }; + +/** + * Deeply merges two JavaScript objects. + * + * @param {Object} dest - The object to copy the source into. + * @param {Object} src - The object to copy. + * @returns {Object} Returns the dest object. + */ +export function mergeDeep(dest?: T, src?: T2): T { + if (typeof dest !== 'object' || dest === null || Array.isArray(dest)) { + dest = {} as T; + } + + if (typeof src !== 'object' || src === null || Array.isArray(src)) { + return dest; + } + + for (const key of Object.keys(src)) { + const value = src[key]; + if (Array.isArray(value)) { + if (Array.isArray(dest[key])) { + dest[key].push(...value); + } else { + (dest as any)[key] = value.slice(); // clone the original array + } + } else if (typeof value === 'object' && value !== null) { + if (typeof dest[key] !== 'object' || dest[key] === null || Array.isArray(dest[key])) { + (dest as any)[key] = {}; + } + mergeDeep(dest[key], value); + } else if (typeof value !== 'undefined') { + (dest as any)[key] = value; + } + } + + return dest; +} + +/** + * Tries to resolve the operating system name and version. + * + * @returns {Object} + */ +export function osInfo(): object { + let name = null; + let version = null; + + switch (process.platform) { + case 'darwin': + { + const stdout = spawnSync('sw_vers').stdout.toString(); + let m = stdout.match(/ProductName:\s+(.+)/i); + if (m) { + name = m[1]; + } + m = stdout.match(/ProductVersion:\s+(.+)/i); + if (m) { + version = m[1]; + } + } + break; + + case 'linux': + name = 'GNU/Linux'; + + if (isFile('/etc/lsb-release')) { + const contents = fs.readFileSync('/etc/lsb-release', 'utf8'); + let m = contents.match(/DISTRIB_DESCRIPTION=(.+)/i); + if (m) { + name = m[1].replace(/"/g, ''); + } + m = contents.match(/DISTRIB_RELEASE=(.+)/i); + if (m) { + version = m[1].replace(/"/g, ''); + } + } else if (isFile('/etc/system-release')) { + const parts = fs.readFileSync('/etc/system-release', 'utf8').split(' '); + if (parts[0]) { + name = parts[0]; + } + if (parts[2]) { + version = parts[2]; + } + } + break; + + case 'win32': + { + const stdout = spawnSync('wmic', [ 'os', 'get', 'Caption,Version' ]).stdout.toString(); + const s = stdout.split('\n')[1].split(/ {2,}/); + if (s.length > 0) { + name = s[0].trim() || 'Windows'; + } + if (s.length > 1) { + version = s[1].trim() || ''; + } + } + break; + } + + return { + name, + version + }; +} + +/** + * Returns the specified number of random bytes as a hex string. + * + * @param {Number} howMany - The number of random bytes to generate. Must be greater than or equal + * to zero. + * @returns {String} + */ +export function randomBytes(howMany: number) : string { + return crypto.randomBytes(Math.max(~~howMany, 0)).toString('hex'); +} + +type ReplacementPattern = string | RegExp; +type ReplacementValue = string | RegExp; +type ReplacementItem = [ReplacementPattern, ReplacementValue] | ReplacementPattern | undefined; +type ReplacementList = Array | Set; + +interface RedactOptions { + clone?: boolean; + props?: Array | Set; + redacted?: string; + replacements?: ReplacementList; + triggers?: Array | Set; + [key: string]: any; +} + +/** + * A lookup of various properties that must be redacted during log message serialization. + * @type {Array.} + */ +const mandatoryRedactedProps = [ + /clientsecret/i, + /password/i +]; + +/** + * A list of regexes that will trigger the entire string to be redacted. + * @type {Array.} + */ +const mandatoryRedactionTriggers = [ + /password/i +]; + +/** + * A list of string replacement arguments. + * @type {Array.} + */ +const mandatoryReplacements: ReplacementList = [ + [ homedir(), '' ], + process.env.USER, // macOS, Linux + process.env.USERNAME, // Windows + /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g // email address +]; + +/** + * Scrubs any potentially sensitive data from a value. By default, if the source is an object, it + * will be mutated. Redacted properties or elements will not be removed. + * + * @param {*} data - The source object to copy from. + * @param {Object} [opts] - Various options. + * @param {Boolean} [opts.clone] - When `true`, objects and arrays are cloned instead of mutated. + * @param {Array|Set} [opts.props] - A list of properties to redact. + * @param {String} [opts.redacted=""] - The string to replace redacted words with. + * @param {Array|Set} [opts.replacements] - A list of replacement criteria and an optional value. + * @param {Array|Set} [opts.triggers] - A list of keywords that cause an entire string to be + * redacted. + * @returns {*} + * + * @example + * > redact('foo') + * 'foo' + * + * @example + * > redact('my password is 123456') + * '' + * + * @example + * > redact({ + * info: { + * username: 'chris', + * password: '123456', + * desktop: '/Users/chris/Desktop' + * } + * }) + * { + * info: { + * username: '', // matches process.env.USER + * password: '', // matches blocked property + * desktop: '~/Desktop' // matches process.env.HOME + * } + * } + */ +export function redact(data: any, opts: RedactOptions = {}) : any { + if (!opts || typeof opts !== 'object') { + throw new TypeError('Expected options to be an object'); + } + + const redacted = opts.redacted || ''; + + type TestFunction = (s: string) => boolean; + + const init = (key: string, value: TestFunction[]) => { + if (Array.isArray(opts[key]) || opts[key] instanceof Set) { + for (const item of opts[key]) { + if (item && typeof item === 'string') { + value.push((s: string) => s === item.toLowerCase()); + } else if (item instanceof RegExp) { + value.push(item.test.bind(item)); + } else { + throw new TypeError(`Expected ${key} to be a set or array of strings or regexes`); + } + } + } else if (opts[key]) { + throw new TypeError(`Expected ${key} to be a set or array of strings or regexes`); + } + return value; + }; + + const props = init('props', mandatoryRedactedProps.map(re => re.test.bind(re))); + const triggers = init('triggers', mandatoryRedactionTriggers.map(re => re.test.bind(re))); + + // init the replacements + const replacementMap = new Map(); + + const addReplacement = (replacements: ReplacementList | undefined) => { + if (Array.isArray(replacements) || replacements instanceof Set) { + for (const replacement of (replacements as ReplacementList)) { + let pattern: ReplacementPattern; + let value: ReplacementValue | null = null; + if (!replacement) { + continue; + } else if (Array.isArray(replacement)) { + ([ pattern, value ] = replacement); + } else if (replacement && (typeof replacement === 'string' || replacement instanceof RegExp)) { + pattern = replacement; + } else { + throw new TypeError('Expected replacements to be an array of replace arguments'); + } + const key: string | RegExp = pattern; + if (!(pattern instanceof RegExp)) { + // eslint-disable-next-line security/detect-non-literal-regexp + pattern = new RegExp(pattern.replace(/\\/g, '\\\\'), 'ig'); + } + if (value === undefined || value === null) { + value = redacted; + } + replacementMap.set(key, (s: string) => s.replace(pattern, value as string)); + } + } else if (replacements) { + throw new TypeError('Expected replacements to be an array of replace arguments'); + } + }; + + addReplacement(mandatoryReplacements); + addReplacement(opts.replacements); + const replacements = Array.from(replacementMap.values()); + + // recursively walk the value and return the result + return (function scrub(src) { + let dest = src; + if (Array.isArray(src)) { + dest = opts.clone ? [] : src; + for (let i = 0, len = src.length; i < len; i++) { + dest[i] = scrub(src[i]); + } + } else if (src && typeof src === 'object') { + dest = opts.clone ? {} : src; + for (const [ key, value ] of Object.entries(src)) { + let match = false; + for (const test of props) { + if (match = test(key)) { + dest[key] = redacted; + break; + } + } + // if we found a match, then we just redacted the whole string and there's no need + // to scrub it + if (!match) { + dest[key] = scrub(value); + } + } + } else if (src && typeof src === 'string') { + for (const replace of replacements) { + dest = replace(dest); + if (dest === redacted) { + break; + } + } + for (const test of triggers) { + if (test(dest)) { + dest = redacted; + break; + } + } + } + return dest; + }(data)); +} + +/** + * Re-export of lodash's `set()` function. + * + * For more information, visit {@link https://www.npmjs.com/package/lodash.set} or + * {@link https://lodash.com/docs/4.17.15#set}. + * + * @param {Object} obj - The object to modify. + * @param {Array.|String} [path] - The path of the property to set. + * @param {*} [defaultValue] - The value to set. + * @returns {*} + */ +export { set }; diff --git a/packages/amplify-utils/test/test-fs.js b/packages/amplify-utils/test/test-fs.ts similarity index 60% rename from packages/amplify-utils/test/test-fs.js rename to packages/amplify-utils/test/test-fs.ts index edd22e3c..0f5ab9d0 100644 --- a/packages/amplify-utils/test/test-fs.js +++ b/packages/amplify-utils/test/test-fs.ts @@ -1,23 +1,26 @@ import fs from 'fs'; import path from 'path'; import tmp from 'tmp'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; import { existsSync, isDir, isFile, - locate, mkdirpSync, moveSync, - readdirScopedSync, writeFileSync -} from '../dist/index'; +} from '../src/index.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const __filename = fileURLToPath(import.meta.url); const { name: tmpDir, removeCallback } = tmp.dirSync({ - mode: '755', + mode: 0o755, prefix: 'amplify-utils-fs-test-', unsafeCleanup: true }); @@ -65,46 +68,6 @@ describe('fs', () => { }); }); - describe('locate()', () => { - const baseDir = path.resolve(__dirname, './fixtures/locate'); - - it('should find a file with no depth', () => { - let result = locate(baseDir, 'foo.txt'); - expect(result).to.be.a('string'); - expect(result).to.equal(path.join(baseDir, 'subdir1', 'foo.txt')); - - result = locate(baseDir, 'bar.txt'); - expect(result).to.be.a('string'); - expect(result).to.equal(path.join(baseDir, 'subdir1', 'subdir2', 'bar.txt')); - }); - - it('should find a file using a regex', () => { - let result = locate(baseDir, /foo\.txt/); - expect(result).to.be.a('string'); - expect(result).to.equal(path.join(baseDir, 'subdir1', 'foo.txt')); - - result = locate(baseDir, /bar\.txt/); - expect(result).to.be.a('string'); - expect(result).to.equal(path.join(baseDir, 'subdir1', 'subdir2', 'bar.txt')); - }); - - it('should find a file with depth', () => { - const result = locate(baseDir, 'foo.txt', 1); - expect(result).to.be.a('string'); - expect(result).to.equal(path.join(baseDir, 'subdir1', 'foo.txt')); - }); - - it('should not find non-existant file', () => { - const result = locate(baseDir, 'baz.txt'); - expect(result).to.be.null; - }); - - it('should not find a file with depth', () => { - const result = locate(baseDir, 'bar.txt', 1); - expect(result).to.be.null; - }); - }); - describe('mkdirpSync()', () => { afterEach(() => { try { @@ -148,19 +111,6 @@ describe('fs', () => { }); }); - describe('readdirScoped', () => { - const baseDir = path.resolve(__dirname, './fixtures/readdirScopedSync'); - it('should read dir and have scoped packages as a single entry', () => { - const dirs = readdirScopedSync(baseDir); - expect(dirs).to.deep.equal([ '@test/bar', '@test/foo', 'bar', 'foo' ]); - }); - - it('should work normally when no scopes exists and filter files out', () => { - const dirs = readdirScopedSync(__dirname); - expect(dirs).to.deep.equal([ 'fixtures' ]); - }); - }); - describe('writeFileSync()', () => { afterEach(() => { try { diff --git a/packages/amplify-utils/test/test-path.js b/packages/amplify-utils/test/test-path.js deleted file mode 100644 index e9e739e6..00000000 --- a/packages/amplify-utils/test/test-path.js +++ /dev/null @@ -1,110 +0,0 @@ -import fs from 'fs-extra'; -import tmp from 'tmp'; -import _path from 'path'; - -import * as path from '../dist/index'; - -const isWin = /^win/.test(process.platform); - -describe('path', () => { - describe('expandPath()', () => { - beforeEach(function () { - this.HOME = process.env.HOME; - this.USERPROFILE = process.env.USERPROFILE; - this.SystemRoot = process.env.SystemRoot; - }); - - afterEach(function () { - this.HOME && (process.env.HOME = this.HOME); - this.USERPROFILE && (process.env.USERPROFILE = this.USERPROFILE); - this.SystemRoot && (process.env.SystemRoot = this.SystemRoot); - delete process.env.AXWAY_TEST_PLATFORM; - }); - - it('should resolve the home directory using HOME', () => { - process.env.HOME = isWin ? 'C:\\Users\\username' : '/Users/username'; - delete process.env.USERPROFILE; - - const p = path.expandPath('~/foo'); - expect(p).to.equal(isWin ? 'C:\\Users\\username\\foo' : '/Users/username/foo'); - }); - - it('should resolve the home directory using USERPROFILE', () => { - delete process.env.HOME; - process.env.USERPROFILE = isWin ? 'C:\\Users\\username' : '/Users/username'; - - const p = path.expandPath('~/foo'); - expect(p).to.equal(isWin ? 'C:\\Users\\username\\foo' : '/Users/username/foo'); - }); - - it('should collapse relative segments', () => { - const p = path.expandPath('/path/./to/../foo'); - expect(p).to.match(isWin ? /^\w:\\path\\foo$/ : /^\/path\/foo$/); - }); - - it('should resolve environment paths (Windows)', () => { - process.env.AXWAY_TEST_PLATFORM = 'win32'; - process.env.SystemRoot = 'C:\\WINDOWS'; - const p = path.expandPath('%SystemRoot%\\foo'); - expect(isWin ? p : p.substring(process.cwd().length + 1)).to.equal('C:\\WINDOWS\\foo'); - }); - }); - - describe('real()', () => { - it('should figure out the real path for a non-symlinked existing file', () => { - expect(path.real(__filename)).to.equal(__filename); - }); - - it('should figure out the real path for a symlinked existing file', () => { - const tmpObj = tmp.dirSync({ - mode: '755', - prefix: 'amplify-utils-path-test-' - }); - const dir = _path.join(tmpObj.name, 'bar'); - const filename = _path.join(tmpObj.name, 'foo.txt'); - const symFilename = _path.join(tmpObj.name, 'bar', 'foo.txt'); - - fs.writeFileSync(filename, 'foo!'); - fs.mkdirSync(dir); - fs.symlinkSync(filename, symFilename); - - try { - expect(path.real(symFilename)).to.equal(fs.realpathSync(filename)); - } finally { - fs.removeSync(tmpObj.name); - } - }); - - it('should figure out the real path for a non-symlinked non-existent file', () => { - const tmpObj = tmp.dirSync({ - mode: '755', - prefix: 'amplify-utils-path-test-' - }); - const filename = _path.join(tmpObj.name, 'foo.txt'); - - try { - expect(path.real(filename)).to.equal(_path.join(fs.realpathSync(tmpObj.name), 'foo.txt')); - } finally { - fs.removeSync(tmpObj.name); - } - }); - - it('should figure out the real path for a symlinked nested non-existent directory', () => { - const dir = tmp.dirSync({ - mode: '755', - prefix: 'amplify-utils-path-test-' - }).name; - - const foo = _path.join(dir, 'foo'); - const bar = _path.join(dir, 'bar'); - - const foobaz = _path.join(dir, 'foo', 'baz'); - const barbaz = _path.join(fs.realpathSync(dir), 'bar', 'baz'); - - // link foo to bar - fs.symlinkSync(bar, foo); - - expect(path.real(foobaz)).to.equal(barbaz); - }); - }); -}); diff --git a/packages/amplify-utils/test/test-path.ts b/packages/amplify-utils/test/test-path.ts new file mode 100644 index 00000000..ce5981ba --- /dev/null +++ b/packages/amplify-utils/test/test-path.ts @@ -0,0 +1,49 @@ +import { expect } from 'chai'; +import * as path from '../src/index.js'; + +const isWin = /^win/.test(process.platform); + +describe('path', () => { + describe('expandPath()', () => { + beforeEach(function () { + this.HOME = process.env.HOME; + this.USERPROFILE = process.env.USERPROFILE; + this.SystemRoot = process.env.SystemRoot; + }); + + afterEach(function () { + this.HOME && (process.env.HOME = this.HOME); + this.USERPROFILE && (process.env.USERPROFILE = this.USERPROFILE); + this.SystemRoot && (process.env.SystemRoot = this.SystemRoot); + delete process.env.AXWAY_TEST_PLATFORM; + }); + + it('should resolve the home directory using HOME', () => { + process.env.HOME = isWin ? 'C:\\Users\\username' : '/Users/username'; + delete process.env.USERPROFILE; + + const p = path.expandPath('~/foo'); + expect(p).to.equal(isWin ? 'C:\\Users\\username\\foo' : '/Users/username/foo'); + }); + + it('should resolve the home directory using USERPROFILE', () => { + delete process.env.HOME; + process.env.USERPROFILE = isWin ? 'C:\\Users\\username' : '/Users/username'; + + const p = path.expandPath('~/foo'); + expect(p).to.equal(isWin ? 'C:\\Users\\username\\foo' : '/Users/username/foo'); + }); + + it('should collapse relative segments', () => { + const p = path.expandPath('/path/./to/../foo'); + expect(p).to.match(isWin ? /^\w:\\path\\foo$/ : /^\/path\/foo$/); + }); + + it('should resolve environment paths (Windows)', () => { + process.env.AXWAY_TEST_PLATFORM = 'win32'; + process.env.SystemRoot = 'C:\\WINDOWS'; + const p = path.expandPath('%SystemRoot%\\foo'); + expect(isWin ? p : p.substring(process.cwd().length + 1)).to.equal('C:\\WINDOWS\\foo'); + }); + }); +}); diff --git a/packages/amplify-utils/test/test-util.js b/packages/amplify-utils/test/test-util.js deleted file mode 100644 index 3dfb1006..00000000 --- a/packages/amplify-utils/test/test-util.js +++ /dev/null @@ -1,1044 +0,0 @@ -import path from 'path'; - -import * as util from '../dist/index'; - -describe('util', () => { - - describe('arch()', () => { - beforeEach(function () { - this.PROCESSOR_ARCHITEW6432 = process.env.PROCESSOR_ARCHITEW6432; - }); - - afterEach(function () { - delete process.env.AXWAY_TEST_PLATFORM; - delete process.env.AXWAY_TEST_ARCH; - this.PROCESSOR_ARCHITEW6432 && (process.env.PROCESSOR_ARCHITEW6432 = this.PROCESSOR_ARCHITEW6432); - }); - - it('should detect the system architecture', () => { - const a = util.arch(); - expect(a).to.be.oneOf([ 'x86', 'x64' ]); - }); - - it('should cache the architecture', () => { - process.env.AXWAY_TEST_ARCH = 'x64'; - expect(util.arch(true)).to.equal('x64'); - - process.env.AXWAY_TEST_ARCH = 'ia32'; - expect(util.arch()).to.equal('x64'); - - if (process.platform === 'linux') { - // on linux it actually subprocesses getconf to get the arch, so it's not easy to - // force the arch to x86 - expect(util.arch(true)).to.be.oneOf([ 'x86', 'x64' ]); - } else { - expect(util.arch(true)).to.equal('x86'); - } - }); - - it('should correct ia32 for 64-bit systems (Windows)', () => { - process.env.AXWAY_TEST_PLATFORM = 'win32'; - process.env.AXWAY_TEST_ARCH = 'ia32'; - process.env.PROCESSOR_ARCHITEW6432 = 'AMD64'; - - expect(util.arch(true)).to.equal('x64'); - }); - - (process.platform === 'win32' ? it.skip : it)('should correct ia32 for 64-bit systems (Linux)', () => { - process.env.AXWAY_TEST_PLATFORM = 'linux'; - process.env.AXWAY_TEST_ARCH = 'ia32'; - - expect(util.arch(true)).to.equal('x64'); - }); - }); - - describe('arrayify()', () => { - it('should convert a string to an array', () => { - expect(util.arrayify('foo')).to.deep.equal([ 'foo' ]); - }); - - it('should convert a number to an array', () => { - expect(util.arrayify(123)).to.deep.equal([ 123 ]); - }); - - it('should convert a set to an array', () => { - expect(util.arrayify(new Set([ 'a', 'b' ]))).to.deep.equal([ 'a', 'b' ]); - }); - - it('should return the original array', () => { - expect(util.arrayify([ 'foo', 'bar' ])).to.deep.equal([ 'foo', 'bar' ]); - }); - - it('should return empty array', () => { - expect(util.arrayify('', true)).to.deep.equal([]); - }); - - it('should remove falsey items', () => { - expect(util.arrayify([ 'a', '', 'b', null, 'c', undefined, 'd', true, false, 0, NaN, 1 ], true)).to.deep.equal([ 'a', 'b', 'c', 'd', true, 0, 1 ]); - }); - }); - - describe('assertNodeEngineVersion()', () => { - afterEach(() => { - delete process.env.AXWAY_TEST_NODE_VERSION; - }); - - it('should error if pkgJson is not a file or object', () => { - expect(() => { - util.assertNodeEngineVersion(); - }).to.throw(TypeError, 'Expected pkgJson to be an object or string to a package.json file'); - expect(() => { - util.assertNodeEngineVersion(null); - }).to.throw(TypeError, 'Expected pkgJson to be an object or string to a package.json file'); - expect(() => { - util.assertNodeEngineVersion([ 'a' ]); - }).to.throw(TypeError, 'Expected pkgJson to be an object or string to a package.json file'); - expect(() => { - util.assertNodeEngineVersion(123); - }).to.throw(TypeError, 'Expected pkgJson to be an object or string to a package.json file'); - }); - - it('should error if package.json file does not exist', () => { - expect(() => { - util.assertNodeEngineVersion('foo'); - }).to.throw(Error, 'File does not exist: foo'); - }); - - it('should load package.json', () => { - expect(util.assertNodeEngineVersion(path.join(__dirname, 'fixtures', 'empty-package.json'))).to.be.true; - }); - - it('should error with bad package.json', () => { - expect(() => { - util.assertNodeEngineVersion(path.join(__dirname, 'fixtures', 'bad-package.json')); - }).to.throw(Error, /^Unable to parse package.json: /); - }); - - it('should succeed without engines definition', () => { - expect(util.assertNodeEngineVersion({})).to.be.true; - }); - - it('should success if node version is valid', () => { - process.env.AXWAY_TEST_NODE_VERSION = 'v6.9.4'; - expect(util.assertNodeEngineVersion({ engines: { node: '6.9.4' } })).to.be.true; - expect(util.assertNodeEngineVersion({ engines: { node: 'v6.9.4' } })).to.be.true; - expect(util.assertNodeEngineVersion(path.join(__dirname, 'fixtures', 'good-package.json'))).to.be.true; - }); - - it('should fail if node version is not valid', () => { - process.env.AXWAY_TEST_NODE_VERSION = 'v6.9.4'; - expect(() => { - util.assertNodeEngineVersion({ engines: { node: '>=6.9' } }); - }).to.throw(Error, 'Invalid Node engine version in package.json: >=6.9'); - expect(() => { - util.assertNodeEngineVersion({ engines: { node: '6.9.3' } }); - }).to.throw(Error, 'Requires Node.js \'6.9.3\', but the current version is \'v6.9.4\''); - expect(() => { - util.assertNodeEngineVersion({ engines: { node: '7.0.0' } }); - }).to.throw(Error, 'Requires Node.js \'7.0.0\', but the current version is \'v6.9.4\''); - }); - }); - - describe('cache()', () => { - it('should error if namespace is not a string', async () => { - try { - await util.cache(); - } catch (e) { - expect(e).to.be.instanceof(TypeError); - expect(e.message).to.equal('Expected name to be a non-empty string'); - return; - } - - throw new Error('Expected rejection'); - }); - - it('should error if callback is not a function', async () => { - try { - await util.cache('foo', 'bar'); - } catch (e) { - expect(e).to.be.instanceof(TypeError); - expect(e.message).to.equal('Expected callback to be a function'); - return; - } - - throw new Error('Expected rejection'); - }); - - it('should cache a value', async () => { - let counter = 0; - const obj = { foo: 'bar' }; - const obj2 = { baz: 'pow' }; - - const value = await util.cache('foo', () => { - counter++; - return obj; - }); - expect(counter).to.equal(1); - expect(value).to.be.an('object'); - expect(value).to.deep.equal(obj); - - const value2 = await util.cache('foo', () => { - counter++; - return obj2; - }); - expect(counter).to.equal(1); - expect(value2).to.be.an('object'); - expect(value2).to.deep.equal(obj); - - const value3 = await util.cache('foo', true, () => { - counter++; - return obj2; - }); - expect(counter).to.equal(2); - expect(value3).to.be.an('object'); - expect(value3).to.deep.equal(obj2); - }); - - it('should queue multiple calls', async () => { - let counter = 0; - const obj = { foo: 'bar' }; - const obj2 = { baz: 'pow' }; - - const results = await Promise.all([ - util.cache('foo', true, async () => { - await util.sleep(250); - counter++; - return obj; - }), - util.cache('foo', true, async () => { - counter++; - return obj2; - }) - ]); - - expect(counter).to.equal(1); - expect(results).to.deep.equal([ obj, obj ]); - }); - - it('should catch errors', async () => { - try { - await util.cache('foo', true, () => { - throw new Error('oh snap'); - }); - } catch (e) { - expect(e).to.be.instanceof(Error); - expect(e.message).to.equal('oh snap'); - return; - } - - throw new Error('Expected rejection'); - }); - }); - - describe('cacheSync()', () => { - it('should error if namespace is not a string', () => { - expect(() => { - util.cacheSync(); - }).to.throw(TypeError, 'Expected name to be a non-empty string'); - }); - - it('should error if callback is not a function', () => { - expect(() => { - util.cacheSync('foo2', 'bar'); - }).to.throw(TypeError, 'Expected callback to be a function'); - }); - - it('should cache a value', () => { - let counter = 0; - const obj = { foo: 'bar' }; - const obj2 = { baz: 'pow' }; - - const value = util.cacheSync('foo2', () => { - counter++; - return obj; - }); - expect(counter).to.equal(1); - expect(value).to.be.an('object'); - expect(value).to.deep.equal(obj); - - const value2 = util.cacheSync('foo2', () => { - counter++; - return obj2; - }); - expect(counter).to.equal(1); - expect(value2).to.be.an('object'); - expect(value2).to.deep.equal(obj); - - const value3 = util.cacheSync('foo2', true, () => { - counter++; - return obj2; - }); - expect(counter).to.equal(2); - expect(value3).to.be.an('object'); - expect(value3).to.deep.equal(obj2); - }); - - it('should passthrough errors', () => { - expect(() => { - util.cacheSync('foo3', true, () => { - throw new Error('oh snap'); - }); - }).to.throw(Error, 'oh snap'); - }); - }); - - describe('debounce()', () => { - it('should debounce multiple calls using default timeout', function (done) { - this.slow(2000); - - let count = 0; - const fn = util.debounce(() => { - count++; - }); - - fn(); - fn(); - fn(); - - setTimeout(() => { - try { - expect(count).to.equal(0); - - fn(); - - setTimeout(() => { - try { - expect(count).to.equal(1); - done(); - } catch (e) { - done(e); - } - }, 500); - } catch (e) { - done(e); - } - }, 0); - }); - - it('should debounce multiple calls using 250ms timeout', function (done) { - this.slow(2000); - - let count = 0; - const fn = util.debounce(() => { - count++; - }, 250); - - fn(); - fn(); - fn(); - - setTimeout(() => { - try { - expect(count).to.equal(0); - - fn(); - - setTimeout(() => { - try { - expect(count).to.equal(1); - done(); - } catch (e) { - done(e); - } - }, 500); - } catch (e) { - done(e); - } - }, 0); - }); - - it('should resolve a promise when bouncing has stopped', async function () { - this.slow(2000); - - let count = 0; - const fn = util.debounce(() => { - count++; - }); - - return Promise - .all([ - fn(), - fn(), - fn(), - fn(), - fn(), - fn(), - fn() - ]) - .then(() => { - expect(count).to.equal(1); - }); - }); - - it('should cancel a pending debounce', function (done) { - this.slow(5000); - this.timeout(5000); - - let count = 0; - const fn = util.debounce(() => { - count++; - }, 1000); - - fn(); - - setTimeout(() => { - fn.cancel(); - setTimeout(() => { - try { - expect(count).to.equal(0); - done(); - } catch (e) { - done(e); - } - }, 1000); - }, 500); - }); - }); - - describe('decodeOctalUTF8()', () => { - it('decodes non-octal string', () => { - expect(util.decodeOctalUTF8('titanium rocks')).to.equal('titanium rocks'); - }); - - it('decodes octal string', () => { - expect(util.decodeOctalUTF8('testing \\303\\274 and \\351\\252\\236')).to.equal('testing ü and 骞'); - }); - - it('try to decode incomplete octal string', () => { - expect(util.decodeOctalUTF8('testing \\')).to.equal('testing \0'); - }); - }); - - describe('formatNumber()', () => { - it('should format a small integer', () => { - expect(util.formatNumber(12)).to.equal('12'); - }); - - it('should format a big integer', () => { - expect(util.formatNumber(1234567890)).to.equal('1,234,567,890'); - }); - - it('should format a small float', () => { - expect(util.formatNumber(1.2)).to.equal('1.2'); - }); - - it('should format a big float', () => { - expect(util.formatNumber(1234567890.123)).to.equal('1,234,567,890.123'); - }); - }); - - describe('getActiveHandles()', () => { - it('should return the active handles', done => { - const handles = util.getActiveHandles(); - expect(handles).to.be.an.instanceof(Object); - done(); - }); - }); - - describe('inherits()', () => { - it('should detect when a class extends another class', () => { - class Foo {} - class Bar extends Foo {} - expect(util.inherits(Bar, Foo)).to.be.true; - }); - - it('should detect when a class does not extend another class', () => { - class Foo {} - class Bar extends Foo {} - class Wiz {} - expect(util.inherits(Bar, Wiz)).to.be.false; - }); - - it('should detect when a class deeply extends another class', () => { - class Foo {} - class Bar extends Foo {} - class Baz extends Bar {} - expect(util.inherits(Baz, Foo)).to.be.true; - }); - - it('should detect when a class extends null', () => { - class Foo extends null {} - expect(util.inherits(Foo, null)).to.be.true; - }); - - it('should fail if subject is not a function', () => { - expect(() => { - util.inherits(); - }).to.throw(TypeError, 'Expected subject to be a function object'); - - expect(() => { - util.inherits(null); - }).to.throw(TypeError, 'Expected subject to be a function object'); - - expect(() => { - util.inherits({}); - }).to.throw(TypeError, 'Expected subject to be a function object'); - }); - - it('should fail if base class is not a function', () => { - expect(() => { - util.inherits(function () {}); - }).to.throw(TypeError, 'Expected base class to be a function object'); - - expect(() => { - util.inherits(function () {}, ''); - }).to.throw(TypeError, 'Expected base class to be a function object'); - - expect(() => { - util.inherits(function () {}, {}); - }).to.throw(TypeError, 'Expected base class to be a function object'); - }); - }); - - describe('makeSerializable()', () => { - it('should pass through non-objects', () => { - expect(util.makeSerializable()).to.equal(undefined); - expect(util.makeSerializable(undefined)).to.equal(undefined); - expect(util.makeSerializable(null)).to.equal(null); - expect(util.makeSerializable(123)).to.equal(123); - expect(util.makeSerializable('foo')).to.equal('foo'); - expect(util.makeSerializable(true)).to.equal(true); - expect(util.makeSerializable(false)).to.equal(false); - const dt = new Date(); - expect(util.makeSerializable(dt)).to.equal(dt); - }); - - it('should handle NaN', () => { - expect(util.makeSerializable(NaN)).to.equal(null); - }); - - it('should remove non-serializable values', () => { - expect(util.makeSerializable({ - a: () => {}, - b: Symbol() - })).to.deep.equal({ - a: undefined, - b: undefined - }); - }); - - it('should remove circular references', () => { - const obj = {}; - obj.a = obj; - obj.b = [ obj ]; - expect(util.makeSerializable(obj)).to.deep.equal({ - a: undefined, - b: [ undefined ] - }); - - const a = { foo: 'bar' }; - const b = { baz: 'wiz', a }; - a.b = b; - expect(util.makeSerializable({ a, b })).to.deep.equal({ - a: { foo: 'bar', b: { baz: 'wiz', a: undefined } }, - b: { baz: 'wiz', a: { foo: 'bar', b: undefined } } - }); - }); - - it('should not remove non-ciruclar references', () => { - const obj = {}; - const meta = { msg: 'hi' }; - obj.a = meta; - obj.b = meta; - expect(util.makeSerializable(obj)).to.deep.equal({ - a: { msg: 'hi' }, - b: { msg: 'hi' } - }); - }); - }); - - describe('mergeDeep()', () => { - it('should merge two objects together', () => { - const obj = util.mergeDeep({ a: 1 }, { b: 2 }); - expect(obj).to.deep.equal({ a: 1, b: 2 }); - }); - - it('should create a dest object', () => { - const obj = util.mergeDeep(null, { b: 2 }); - expect(obj).to.deep.equal({ b: 2 }); - }); - - it('should return original dest object if source not an object', () => { - const orig = { b: 2 }; - const obj = util.mergeDeep(orig); - expect(obj).to.equal(orig); - - const obj2 = util.mergeDeep(orig, 'foo'); - expect(obj2).to.equal(orig); - }); - - it('should merge deeply nested properties', () => { - const fn = () => {}; - - const obj = util.mergeDeep( - { - a: 1, - d: null, - g: [], - h: [ 'a' ], - i: { j: {} } - }, - { - a: 2, - b: 3, - c: [ 'x', 'y', 'z' ], - d: { fn: fn }, - e: undefined, - f: null, - g: { foo: 'bar' }, - h: [ 'b', 'c' ], - i: { j: { k: 'l' } } - } - ); - - expect(obj).to.deep.equal({ - a: 2, - b: 3, - c: [ 'x', 'y', 'z' ], - d: { fn: fn }, - f: null, - g: { foo: 'bar' }, - h: [ 'a', 'b', 'c' ], - i: { j: { k: 'l' } } - }); - }); - }); - - describe('mutex()', () => { - it('should error if name is not a string', async () => { - try { - await util.mutex(); - } catch (err) { - expect(err).to.be.an.instanceof(TypeError); - expect(err.message).to.equal('Expected name to be a non-empty string'); - return; - } - - throw new Error('Expected rejection'); - }); - - it('should error if callback is not a function', async () => { - try { - await util.mutex('foo', 'bar'); - } catch (err) { - expect(err).to.be.an.instanceof(TypeError); - expect(err.message).to.equal('Expected callback to be a function'); - return; - } - - throw new Error('Expected rejection'); - }); - - it('should queue up multiple calls', async () => { - let count = 0; - - const fn = () => { - return util.mutex('foo', () => { - return ++count; - }); - }; - - const results = await Promise.all([ fn(), fn(), fn() ]); - expect(count).to.equal(3); - expect(results).to.have.lengthOf(3); - expect(results[1]).to.not.equal(results[0]); - expect(results[2]).to.not.equal(results[0]); - }); - - it('should queue up multiple async calls', async () => { - let count = 0; - - const fn = () => { - return util.mutex('foo', () => { - return new Promise(resolve => setTimeout(() => { - resolve(++count); - }, 100)); - }); - }; - - const results = await Promise.all([ fn(), fn(), fn() ]); - expect(count).to.equal(3); - expect(results).to.have.lengthOf(3); - expect(results[1]).to.equal(results[0] + 1); - expect(results[2]).to.equal(results[0] + 2); - }); - - it('should catch errors', async () => { - try { - await util.mutex('foo', () => { - throw new Error('oh snap'); - }); - } catch (err) { - expect(err).to.be.instanceof(Error); - expect(err.message).to.equal('oh snap'); - return; - } - - throw new Error('Expected error to be caught'); - }); - }); - - describe('osInfo()', () => { - it('should get the os info', () => { - const info = util.osInfo(); - expect(info).to.have.keys('name', 'version'); - }); - }); - - describe('randomBytes()', () => { - it('should return 0 random bytes', () => { - const r = util.randomBytes(0); - expect(r).to.be.a('string'); - expect(r).to.have.lengthOf(0); - }); - - it('should return 1 random byte', () => { - const r = util.randomBytes(1); - expect(r).to.be.a('string'); - expect(r).to.have.lengthOf(2); - }); - - it('should return 2 random bytes', () => { - const r = util.randomBytes(2); - expect(r).to.be.a('string'); - expect(r).to.have.lengthOf(4); - }); - - it('should return 20 random bytes', () => { - const r = util.randomBytes(20); - expect(r).to.be.a('string'); - expect(r).to.have.lengthOf(40); - }); - }); - - describe('redact()', () => { - it('should error if options are invalid', () => { - expect(() => { - util.redact({}, 'foo'); - }).to.throw(TypeError, 'Expected options to be an object'); - - expect(() => { - util.redact({}, 123); - }).to.throw(TypeError, 'Expected options to be an object'); - }); - - it('should error if props is invalid', () => { - expect(() => { - util.redact({}, { props: 'foo' }); - }).to.throw(TypeError, 'Expected props to be a set or array of strings'); - - expect(() => { - util.redact({}, { props: 123 }); - }).to.throw(TypeError, 'Expected props to be a set or array of strings'); - - expect(() => { - util.redact({}, { props: [ 123 ] }); - }).to.throw(TypeError, 'Expected props to be a set or array of strings'); - - expect(() => { - util.redact({}, { props: [ {} ] }); - }).to.throw(TypeError, 'Expected props to be a set or array of strings'); - - expect(() => { - util.redact({}, { props: new Set([ 123 ]) }); - }).to.throw(TypeError, 'Expected props to be a set or array of strings'); - - expect(() => { - util.redact({}, { props: new Set([ {} ]) }); - }).to.throw(TypeError, 'Expected props to be a set or array of strings'); - }); - - it('should error if replacements is invalid', () => { - expect(() => { - util.redact({}, { replacements: 'foo' }); - }).to.throw(TypeError, 'Expected replacements to be an array of replace arguments'); - - expect(() => { - util.redact({}, { replacements: [ 123 ] }); - }).to.throw(TypeError, 'Expected replacements to be an array of replace arguments'); - }); - - it('should redact undefined value', () => { - expect(util.redact()).to.equal(undefined); - }); - - it('should redact null value', () => { - expect(util.redact(null)).to.equal(null); - }); - - it('should redact a string by trigger word', () => { - expect(util.redact('my password is 123456')).to.equal(''); - }); - - it('should passthrough non-string and non-object based values', () => { - expect(util.redact(true)).to.equal(true); - expect(util.redact(false)).to.equal(false); - - expect(util.redact(123)).to.equal(123); - - expect(isNaN(util.redact(NaN))).to.equal(true); - - const fn = () => {}; - expect(util.redact(fn)).to.equal(fn); - }); - - it('should redact a property (mutable)', () => { - const obj = { - good: 'hi', - bad: 'go away', - superbad: 'whoo' - }; - expect(util.redact(obj, { props: [ 'bad', /^super/ ] })).to.deep.equal({ - good: 'hi', - bad: '', - superbad: '' - }); - expect(obj.good).to.equal('hi'); - expect(obj.bad).to.equal(''); - expect(obj.superbad).to.equal(''); - }); - - it('should redact a property (immutable)', () => { - const obj = { - good: 'hi', - bad: 'go away', - superbad: 'whoo' - }; - expect(util.redact(obj, { clone: true, props: [ 'bad', /^super/ ] })).to.deep.equal({ - good: 'hi', - bad: '', - superbad: '' - }); - expect(obj.good).to.equal('hi'); - expect(obj.bad).to.equal('go away'); - expect(obj.superbad).to.equal('whoo'); - }); - - it('should redact part of a string', () => { - expect(util.redact(`${process.env.HOME}/foo/bar`)).to.equal('/foo/bar'); - expect(util.redact(`Hello! My name is ${process.platform === 'win32' ? process.env.USERNAME : process.env.USER}`)).to.equal('Hello! My name is '); - }); - - it('should replace a sensitive data in a string', () => { - expect(util.redact('Your username is chris!', { - replacements: [ - [ 'chris', '*****' ] - ] - })).to.equal('Your username is *****!'); - - expect(util.redact('Account name: foo@bar.com')).to.equal('Account name: '); - - expect(util.redact('Call me at 1-800-555-1212', { - replacements: [ - [ /\d-\d{3}-\d{3}-\d{4}/ ] - ] - })).to.equal('Call me at '); - - const s = 'TODO:\n1. Draw winner\n2. Email foo@bar.com\n3. Ship prize'; - expect(util.redact(s)).to.equal('TODO:\n1. Draw winner\n2. Email \n3. Ship prize'); - }); - - it('should redact an array of items', () => { - const name = process.env.USERNAME || process.env.USER; - const arr = util.redact([ - { user: name, password: '123456', email: 'foo@bar.com' }, - `Welcome ${name.substring(0, 1).toUpperCase()}${name.substring(1).toLowerCase()}!`, - 123, - [ `${process.env.HOME}/foo/bar` ] - ]); - - expect(arr).to.deep.equal([ - { user: '', password: '', email: '' }, - 'Welcome !', - 123, - [ '/foo/bar' ] - ]); - }); - }); - - describe('sha1()', () => { - it('should hash a buffer', () => { - expect(util.sha1(Buffer.from('foo'))).to.equal('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'); - }); - - it('should hash a string', () => { - expect(util.sha1('foo')).to.equal('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'); - }); - - it('should hash a number', () => { - expect(util.sha1(123)).to.equal('40bd001563085fc35165329ea1ff5c5ecbdbbeef'); - }); - - it('should hash an object', () => { - expect(util.sha1({ foo: 'bar' })).to.equal('a5e744d0164540d33b1d7ea616c28f2fa97e754a'); - }); - }); - - describe('sleep', () => { - it('should wait 1 second', async function () { - this.slow(3000); - this.timeout(3000); - - const start = Date.now(); - await util.sleep(1000); - expect(Date.now() - start).to.be.at.least(1000); - }); - - it('should error if ms is not a number', async () => { - try { - await util.sleep('foo'); - } catch (err) { - expect(err).to.be.instanceof(TypeError); - expect(err.message).to.equal('Expected timeout milliseconds to be a number'); - return; - } - - throw new Error('Expected type error'); - }); - - it('should error if ms is less than zero', async () => { - try { - await util.sleep(-666); - } catch (err) { - expect(err).to.be.instanceof(RangeError); - expect(err.message).to.equal('Expected timeout milliseconds to be greater than or equal to zero'); - return; - } - - throw new Error('Expected range error'); - }); - }); - - describe('tailgate()', () => { - it('should error if name is not a string', async () => { - try { - await util.tailgate(); - } catch (err) { - expect(err).to.be.an.instanceof(TypeError); - expect(err.message).to.equal('Expected name to be a non-empty string'); - return; - } - - throw new Error('Expected rejection'); - }); - - it('should error if callback is not a function', async () => { - try { - await util.tailgate('foo', 'bar'); - } catch (err) { - expect(err).to.be.an.instanceof(TypeError); - expect(err.message).to.equal('Expected callback to be a function'); - return; - } - - throw new Error('Expected rejection'); - }); - - it('should queue up multiple calls', async () => { - let count = 0; - const fn = () => util.tailgate('foo', () => ++count); - const results = await Promise.all([ fn(), fn(), fn() ]); - - expect(count).to.equal(3); - expect(results).to.have.lengthOf(3); - expect(results[1]).to.equal(results[0] + 1); - expect(results[2]).to.equal(results[0] + 2); - }); - - it('should queue up multiple async calls', async () => { - let count = 0; - const fn = () => util.tailgate('foo', () => new Promise(resolve => resolve(++count))); - const results = await Promise.all([ fn(), fn(), fn() ]); - - expect(count).to.equal(1); - expect(results).to.have.lengthOf(3); - expect(results[1]).to.equal(results[0]); - expect(results[2]).to.equal(results[0]); - }); - - it('should catch errors', async () => { - try { - await util.tailgate('foo', () => { - throw new Error('oh snap'); - }); - } catch (err) { - expect(err).to.be.instanceof(Error); - expect(err.message).to.equal('oh snap'); - return; - } - - throw new Error('Expected error to be caught'); - }); - }); - - describe('trackTimers()', () => { - it('should track there were no timers', () => { - const timers = []; - try { - const stop = util.trackTimers(); - const activeTimers = stop(); - expect(activeTimers).to.have.lengthOf(timers.length); - } finally { - timers.forEach(clearTimeout); - } - }); - - it('should track a single setTimeout()', () => { - const timers = []; - try { - const stop = util.trackTimers(); - timers.push(setTimeout(() => {}, 1e7)); - const activeTimers = stop(); - expect(activeTimers).to.have.lengthOf(timers.length); - } finally { - timers.forEach(a => clearTimeout(a)); - } - }); - - it('should track a multiple setTimeout()\'s', () => { - const timers = []; - try { - const stop = util.trackTimers(); - timers.push(setTimeout(() => {}, 1e7)); - const activeTimers = stop(); - expect(activeTimers).to.have.lengthOf(timers.length); - } finally { - timers.forEach(clearTimeout); - } - }); - }); - - describe('unique()', () => { - it('should return an empty array if input is not an array', () => { - let r = util.unique(); - expect(r).to.be.an('array'); - expect(r).to.have.lengthOf(0); - - r = util.unique('foo'); - expect(r).to.be.an('array'); - expect(r).to.have.lengthOf(0); - - r = util.unique([]); - expect(r).to.be.an('array'); - expect(r).to.have.lengthOf(0); - }); - - it('should handle a string and undefined', () => { - const r = util.unique([ 'foo', undefined ]); - expect(r).to.be.an('array'); - expect(r).to.deep.equal([ 'foo' ]); - }); - - it('should handle an empty string', () => { - const r = util.unique([ 'foo', '', 'bar', '' ]); - expect(r).to.be.an('array'); - expect(r).to.deep.equal([ 'foo', '', 'bar' ]); - }); - - it('should remove duplicates, null, and undefined elements', () => { - const r = util.unique([ 'a', 1, 'b', 'c', 2, 'a', undefined, 'd', 3, 'b', null, 'b', 1, 3 ]); - expect(r).to.be.an('array'); - expect(r).to.deep.equal([ 'a', 1, 'b', 'c', 2, 'd', 3 ]); - }); - }); -}); diff --git a/packages/amplify-utils/test/test-util.ts b/packages/amplify-utils/test/test-util.ts new file mode 100644 index 00000000..c98977d9 --- /dev/null +++ b/packages/amplify-utils/test/test-util.ts @@ -0,0 +1,288 @@ +import { expect } from 'chai'; +import * as util from '../src/index.js'; + +describe('util', () => { + + describe('arch()', () => { + beforeEach(function () { + this.PROCESSOR_ARCHITEW6432 = process.env.PROCESSOR_ARCHITEW6432; + }); + + afterEach(function () { + delete process.env.AXWAY_TEST_PLATFORM; + delete process.env.AXWAY_TEST_ARCH; + this.PROCESSOR_ARCHITEW6432 && (process.env.PROCESSOR_ARCHITEW6432 = this.PROCESSOR_ARCHITEW6432); + }); + + it('should detect the system architecture', () => { + const a = util.arch(); + expect(a).to.be.oneOf([ 'x86', 'x64' ]); + }); + + it('should cache the architecture', () => { + process.env.AXWAY_TEST_ARCH = 'x64'; + expect(util.arch(true)).to.equal('x64'); + + process.env.AXWAY_TEST_ARCH = 'ia32'; + expect(util.arch()).to.equal('x64'); + + if (process.platform === 'linux') { + // on linux it actually subprocesses getconf to get the arch, so it's not easy to + // force the arch to x86 + expect(util.arch(true)).to.be.oneOf([ 'x86', 'x64' ]); + } else { + expect(util.arch(true)).to.equal('x86'); + } + }); + + it('should correct ia32 for 64-bit systems (Windows)', () => { + process.env.AXWAY_TEST_PLATFORM = 'win32'; + process.env.AXWAY_TEST_ARCH = 'ia32'; + process.env.PROCESSOR_ARCHITEW6432 = 'AMD64'; + + expect(util.arch(true)).to.equal('x64'); + }); + + (process.platform === 'win32' ? it.skip : it)('should correct ia32 for 64-bit systems (Linux)', () => { + process.env.AXWAY_TEST_PLATFORM = 'linux'; + process.env.AXWAY_TEST_ARCH = 'ia32'; + + expect(util.arch(true)).to.equal('x64'); + }); + }); + + describe('mergeDeep()', () => { + it('should merge two objects together', () => { + const obj = util.mergeDeep({ a: 1 }, { b: 2 }); + expect(obj).to.deep.equal({ a: 1, b: 2 }); + }); + + it('should create a dest object', () => { + const obj = util.mergeDeep(null as any, { b: 2 }); + expect(obj).to.deep.equal({ b: 2 }); + }); + + it('should return original dest object if source not an object', () => { + const orig = { b: 2 }; + const obj = util.mergeDeep(orig, undefined as any); + expect(obj).to.equal(orig); + + const obj2 = util.mergeDeep(orig, 'foo' as any); + expect(obj2).to.equal(orig); + }); + + it('should merge deeply nested properties', () => { + const fn = () => {}; + + const obj = util.mergeDeep( + { + a: 1, + d: null, + g: [], + h: [ 'a' ], + i: { j: {} } + }, + { + a: 2, + b: 3, + c: [ 'x', 'y', 'z' ], + d: { fn: fn }, + e: undefined, + f: null, + g: { foo: 'bar' }, + h: [ 'b', 'c' ], + i: { j: { k: 'l' } } + } + ); + + expect(obj).to.deep.equal({ + a: 2, + b: 3, + c: [ 'x', 'y', 'z' ], + d: { fn: fn }, + f: null, + g: { foo: 'bar' }, + h: [ 'a', 'b', 'c' ], + i: { j: { k: 'l' } } + }); + }); + }); + + describe('osInfo()', () => { + it('should get the os info', () => { + const info = util.osInfo(); + expect(info).to.have.keys('name', 'version'); + }); + }); + + describe('randomBytes()', () => { + it('should return 0 random bytes', () => { + const r = util.randomBytes(0); + expect(r).to.be.a('string'); + expect(r).to.have.lengthOf(0); + }); + + it('should return 1 random byte', () => { + const r = util.randomBytes(1); + expect(r).to.be.a('string'); + expect(r).to.have.lengthOf(2); + }); + + it('should return 2 random bytes', () => { + const r = util.randomBytes(2); + expect(r).to.be.a('string'); + expect(r).to.have.lengthOf(4); + }); + + it('should return 20 random bytes', () => { + const r = util.randomBytes(20); + expect(r).to.be.a('string'); + expect(r).to.have.lengthOf(40); + }); + }); + + describe('redact()', () => { + it('should error if options are invalid', () => { + expect(() => { + util.redact({}, 'foo' as any); + }).to.throw(TypeError, 'Expected options to be an object'); + + expect(() => { + util.redact({}, 123 as any); + }).to.throw(TypeError, 'Expected options to be an object'); + }); + + it('should error if props is invalid', () => { + expect(() => { + util.redact({}, { props: 'foo' } as any); + }).to.throw(TypeError, 'Expected props to be a set or array of strings'); + + expect(() => { + util.redact({}, { props: 123 } as any); + }).to.throw(TypeError, 'Expected props to be a set or array of strings'); + + expect(() => { + util.redact({}, { props: [ 123 ] } as any); + }).to.throw(TypeError, 'Expected props to be a set or array of strings'); + + expect(() => { + util.redact({}, { props: [ {} ] } as any); + }).to.throw(TypeError, 'Expected props to be a set or array of strings'); + + expect(() => { + util.redact({}, { props: new Set([ 123 ]) } as any); + }).to.throw(TypeError, 'Expected props to be a set or array of strings'); + + expect(() => { + util.redact({}, { props: new Set([ {} ]) } as any); + }).to.throw(TypeError, 'Expected props to be a set or array of strings'); + }); + + it('should error if replacements is invalid', () => { + expect(() => { + util.redact({}, { replacements: 'foo' } as any); + }).to.throw(TypeError, 'Expected replacements to be an array of replace arguments'); + + expect(() => { + util.redact({}, { replacements: [ 123 ] } as any); + }).to.throw(TypeError, 'Expected replacements to be an array of replace arguments'); + }); + + it('should redact undefined value', () => { + expect(util.redact(undefined)).to.equal(undefined); + }); + + it('should redact null value', () => { + expect(util.redact(null)).to.equal(null); + }); + + it('should redact a string by trigger word', () => { + expect(util.redact('my password is 123456')).to.equal(''); + }); + + it('should passthrough non-string and non-object based values', () => { + expect(util.redact(true)).to.equal(true); + expect(util.redact(false)).to.equal(false); + + expect(util.redact(123)).to.equal(123); + + expect(isNaN(util.redact(NaN))).to.equal(true); + + const fn = () => {}; + expect(util.redact(fn)).to.equal(fn); + }); + + it('should redact a property (mutable)', () => { + const obj = { + good: 'hi', + bad: 'go away', + superbad: 'whoo' + }; + expect(util.redact(obj, { props: [ 'bad', /^super/ ] })).to.deep.equal({ + good: 'hi', + bad: '', + superbad: '' + }); + expect(obj.good).to.equal('hi'); + expect(obj.bad).to.equal(''); + expect(obj.superbad).to.equal(''); + }); + + it('should redact a property (immutable)', () => { + const obj = { + good: 'hi', + bad: 'go away', + superbad: 'whoo' + }; + expect(util.redact(obj, { clone: true, props: [ 'bad', /^super/ ] })).to.deep.equal({ + good: 'hi', + bad: '', + superbad: '' + }); + expect(obj.good).to.equal('hi'); + expect(obj.bad).to.equal('go away'); + expect(obj.superbad).to.equal('whoo'); + }); + + it('should redact part of a string', () => { + expect(util.redact(`${process.env.HOME}/foo/bar`)).to.equal('/foo/bar'); + expect(util.redact(`Hello! My name is ${process.platform === 'win32' ? process.env.USERNAME : process.env.USER}`)).to.equal('Hello! My name is '); + }); + + it('should replace a sensitive data in a string', () => { + expect(util.redact('Your username is chris!', { + replacements: [ + [ 'chris', '*****' ] + ] + } as any)).to.equal('Your username is *****!'); + + expect(util.redact('Account name: foo@bar.com')).to.equal('Account name: '); + + expect(util.redact('Call me at 1-800-555-1212', { + replacements: [ + [ /\d-\d{3}-\d{3}-\d{4}/ ] + ] + } as any)).to.equal('Call me at '); + + const s = 'TODO:\n1. Draw winner\n2. Email foo@bar.com\n3. Ship prize'; + expect(util.redact(s)).to.equal('TODO:\n1. Draw winner\n2. Email \n3. Ship prize'); + }); + + it('should redact an array of items', () => { + const name = process.env.USERNAME || process.env.USER || ''; + const arr = util.redact([ + { user: name, password: '123456', email: 'foo@bar.com' }, + `Welcome ${name.substring(0, 1).toUpperCase()}${name.substring(1).toLowerCase()}!`, + 123, + [ `${process.env.HOME}/foo/bar` ] + ]); + + expect(arr).to.deep.equal([ + { user: '', password: '', email: '' }, + 'Welcome !', + 123, + [ '/foo/bar' ] + ]); + }); + }); +}); diff --git a/packages/amplify-utils/test/tsconfig.json b/packages/amplify-utils/test/tsconfig.json new file mode 100644 index 00000000..40f5a110 --- /dev/null +++ b/packages/amplify-utils/test/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": ".." + }, + "include": [ "./**/*.ts" ] +} \ No newline at end of file diff --git a/packages/amplify-utils/tsconfig.json b/packages/amplify-utils/tsconfig.json new file mode 100644 index 00000000..26e29219 --- /dev/null +++ b/packages/amplify-utils/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/axway-cli-auth/.gitignore b/packages/axway-cli-auth/.gitignore deleted file mode 100644 index b3a1d215..00000000 --- a/packages/axway-cli-auth/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -._* -.DS_Store* -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log -yarn-error.log diff --git a/packages/axway-cli-auth/CHANGELOG.md b/packages/axway-cli-auth/CHANGELOG.md index 383efb83..275b50a5 100644 --- a/packages/axway-cli-auth/CHANGELOG.md +++ b/packages/axway-cli-auth/CHANGELOG.md @@ -1,3 +1,8 @@ +# v4.0.0 + +- BREAKING CHANGE: Dropped support for Node.js 12 and older. +- chore: Updated dependencies. + # v3.3.7 (Jul 7, 2022) - chore: Updated dependencies. diff --git a/packages/axway-cli-auth/gulpfile.js b/packages/axway-cli-auth/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/axway-cli-auth/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/axway-cli-auth/package.json b/packages/axway-cli-auth/package.json index fd2b22ac..599fc860 100644 --- a/packages/axway-cli-auth/package.json +++ b/packages/axway-cli-auth/package.json @@ -5,6 +5,7 @@ "access": "public" }, "description": "Authenticate machines with the Axway Amplify platform", + "type": "module", "author": "Axway, Inc. ", "maintainers": [ "Chris Barber ", @@ -16,30 +17,28 @@ "amplify" ], "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1" }, "dependencies": { "@axway/amplify-cli-utils": "^5.0.11", "@axway/amplify-utils": "^1.0.9", - "cli-kit": "^1.16.0", + "cli-kit": "^2.0.2", "enquirer": "^2.3.6", - "pretty-ms": "^7.0.1", - "snooplogg": "^3.0.2", - "source-map-support": "^0.5.21", + "pretty-ms": "^8.0.0", + "snooplogg": "^5.0.0", "uuid": "^8.3.2" }, - "devDependencies": { - "@axway/gulp-tasks": "^4.1.4" - }, "homepage": "https://github.com/appcelerator/amplify-tooling#readme", "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/axway-cli-auth", "engines": { - "node": ">=12.13.0" + "node": ">=14.15.0" }, "cli-kit": { "exports": { @@ -55,6 +54,5 @@ "main": "./dist/service-account/index.js" } } - }, - "gitHead": "9cc288d8ee067fb3444920aad11c53899455ad9c" + } } diff --git a/packages/axway-cli-auth/src/auth/index.js b/packages/axway-cli-auth/src/auth/index.ts similarity index 87% rename from packages/axway-cli-auth/src/auth/index.js rename to packages/axway-cli-auth/src/auth/index.ts index e1547134..fb539c43 100644 --- a/packages/axway-cli-auth/src/auth/index.js +++ b/packages/axway-cli-auth/src/auth/index.ts @@ -1,3 +1,9 @@ +import path from 'path'; +import { CLIHelpOptions } from 'cli-kit'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + export default { commands: [ `${__dirname}/list.js`, @@ -9,7 +15,7 @@ export default { ], desc: 'The Axway Auth CLI authenticates with the Axway Amplify Platform, manages access tokens, and retreives user information', help: { - header({ style }) { + header({ style }: CLIHelpOptions): string { return `The Axway CLI auth command allows you to authenticate with the Amplify platform under one or more accounts and switch between them. You can log in using your platform account as well as one or more service accounts at the same time. @@ -24,7 +30,7 @@ store type to “file”: ${style.highlight('axway config set auth.tokenStoreType file')}`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} Log into a platform account using a web browser: diff --git a/packages/axway-cli-auth/src/auth/list.js b/packages/axway-cli-auth/src/auth/list.ts similarity index 64% rename from packages/axway-cli-auth/src/auth/list.js rename to packages/axway-cli-auth/src/auth/list.ts index 8b72841d..96022202 100644 --- a/packages/axway-cli-auth/src/auth/list.js +++ b/packages/axway-cli-auth/src/auth/list.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'ls' ], desc: 'Lists all authenticated accounts', @@ -6,18 +11,18 @@ organization, and the current team.`, name: 'list', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs accounts as JSON' } }, - async action({ argv, console }) { - const { createTable, getAuthConfigEnvSpecifier, initSDK } = require('@axway/amplify-cli-utils'); - const { default: snooplogg } = require('snooplogg'); - - const { config, sdk } = initSDK({ - baseUrl: argv.baseUrl, - env: argv.env, - realm: argv.realm + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, getAuthConfigEnvSpecifier, initSDK } = await import('@axway/amplify-cli-utils'); + const { default: snooplogg } = await import('snooplogg'); + + const { config, sdk } = await initSDK({ + baseUrl: argv.baseUrl as string, + env: argv.env as string, + realm: argv.realm as string }); const authConfigEnvSpecifier = getAuthConfigEnvSpecifier(sdk.env.name); @@ -42,18 +47,18 @@ organization, and the current team.`, const { green } = snooplogg.styles; const check = process.platform === 'win32' ? '√' : '✔'; const now = Date.now(); - const pretty = require('pretty-ms'); + const { default: pretty } = await import('pretty-ms'); const table = createTable([ 'Account Name', 'Organization', 'Current Team', 'Region', 'Type', 'Expires' ]); for (const { default: def, auth, isPlatform, name, org, team } of accounts) { const { access, refresh } = auth.expires; table.push([ `${def ? green(`${check} ${name}`) : ` ${name}`}`, - !org || !org.name ? 'n/a' : org.id ? `${org.name} (${org.id})` : org.name, + !org || !org.name ? 'n/a' : org.org_id ? `${org.name} (${org.org_id})` : org.name, team ? `${team.name} (${team.guid})` : 'n/a', org?.region || 'US', isPlatform ? 'Platform' : 'Service', - pretty((refresh || access) - now, { secDecimalDigits: 0, msDecimalDigits: 0 }) + pretty((refresh || access) - now, { secondsDecimalDigits: 0, millisecondsDecimalDigits: 0 }) ]); } diff --git a/packages/axway-cli-auth/src/auth/login.js b/packages/axway-cli-auth/src/auth/login.ts similarity index 75% rename from packages/axway-cli-auth/src/auth/login.js rename to packages/axway-cli-auth/src/auth/login.ts index 76a6b412..c54968e4 100644 --- a/packages/axway-cli-auth/src/auth/login.js +++ b/packages/axway-cli-auth/src/auth/login.ts @@ -1,16 +1,29 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { + Account, + ManualLoginResult +} from '@axway/amplify-sdk'; +import { + CLIBannerCallback, + CLIHelpOptions +} from 'cli-kit'; + export default { autoHideBanner: false, - async banner(state) { + async banner(state: AxwayCLIState) { // this is a hack to conditionally render the banner based on the parsed args const { argv, cmd } = state; if (!argv.json && cmd.parent) { - const banner = cmd.parent.prop('banner'); + const banner: CLIBannerCallback = cmd.parent.prop('banner') as CLIBannerCallback; return typeof banner === 'function' ? await banner(state) : banner; } }, desc: 'Log in to the Axway Amplify Platform', help: { - header({ style }) { + header({ style }: CLIHelpOptions): string { return `Log in to the Axway Amplify Platform using your platform account as well as one or more service accounts at the same time. @@ -27,7 +40,7 @@ store type to “file”: Once authenticated, the account's current team is set to its configured default team to use for "axway" commands.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} Log into a platform account using a web browser: @@ -52,7 +65,7 @@ team to use for "axway" commands.`; { '--force': 'Re-authenticate even if the account is already authenticated', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs authenticated account as JSON' }, '--no-launch-browser': 'Display the authentication URL instead of opening it in the default web browser' @@ -66,11 +79,11 @@ team to use for "axway" commands.`; '-u, --username [email]': 'Your email address used to log into the Amplify Platform; requires --client-secret or --secret-file' } ], - async action({ argv, cli, console }) { - const { default: snooplogg } = require('snooplogg'); - const { getAuthConfigEnvSpecifier, initSDK, isHeadless } = require('@axway/amplify-cli-utils'); - const { renderAccountInfo } = require('../lib/info'); - const { prompt } = require('enquirer'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { default: snooplogg } = await import('snooplogg'); + const { getAuthConfigEnvSpecifier, initSDK, isHeadless } = await import('@axway/amplify-cli-utils'); + const { renderAccountInfo } = await import('../lib/info.js'); + const { prompt } = await import('enquirer'); // prompt for the username and password if (argv.username !== undefined) { @@ -85,7 +98,7 @@ team to use for "axway" commands.`; type: 'input', name: 'username', message: 'Username:', - validate(s) { + validate(s: string) { return s ? true : 'Please enter your username'; } }); @@ -96,7 +109,7 @@ team to use for "axway" commands.`; type: 'password', name: 'password', message: 'Password:', - validate(s) { + validate(s: string) { return s ? true : 'Please enter your password'; } }); @@ -113,16 +126,16 @@ team to use for "axway" commands.`; } } - const { config, sdk } = initSDK({ - baseUrl: argv.baseUrl, - clientId: argv.clientId, - clientSecret: argv.clientSecret, - env: argv.env, - realm: argv.realm, - secretFile: argv.secretFile, + const { config, sdk } = await initSDK({ + baseUrl: argv.baseUrl as string, + clientId: argv.clientId as string, + clientSecret: argv.clientSecret as string, + env: argv.env as string, + realm: argv.realm as string, + secretFile: argv.secretFile as string, serviceAccount: !!argv.clientSecret }); - let account; + let account!: Account; const authConfigEnvSpecifier = getAuthConfigEnvSpecifier(sdk.env.name); const { highlight, note } = snooplogg.styles; @@ -132,11 +145,11 @@ team to use for "axway" commands.`; // show the url and wait for the user to open it try { if (manual) { - account = await sdk.auth.login({ manual }); - const { cancel, promise, url } = account; + const result = await sdk.auth.login({ manual }) as ManualLoginResult; + const { cancel, promise, url } = result; if (promise) { - promise.catch(err => { + promise.catch((err: any) => { console.error(`${process.platform === 'win32' ? 'x' : '✖'} ${err.toString()}`); process.exit(1); }); @@ -144,11 +157,11 @@ team to use for "axway" commands.`; process.on('SIGINT', () => cancel()); console.log(`Please open following link in your browser:\n\n ${highlight(url)}\n`); - account = await sdk.auth.loadSession(await promise); + account = (await sdk.auth.loadSession(await promise)) as Account; } } else { - account = await sdk.auth.login({ - force: argv.force, + account = (await sdk.auth.login({ + force: !!argv.force, onOpenBrowser() { if (isHeadless()) { throw new Error('Only authenticating with a service account is supported in headless environments'); @@ -156,26 +169,26 @@ team to use for "axway" commands.`; console.log('Launching web browser to login...'); } }, - password: argv.password, - username: argv.username - }); + password: argv.password as string, + username: argv.username as string + })) as Account; } - } catch (err) { + } catch (err: any) { if (err.code === 'EAUTHENTICATED') { - ({ account } = err); + const acct = err.account; if (argv.json) { - account.default = config.get(`${authConfigEnvSpecifier}.defaultAccount`) === account.name; - console.log(JSON.stringify(account, null, 2)); + acct.default = config.get(`${authConfigEnvSpecifier}.defaultAccount`) === acct.name; + console.log(JSON.stringify(acct, null, 2)); return; } - if (account.isPlatform && account.org?.name) { - console.log(`You are already logged into a ${highlight('platform')} account in organization ${highlight(account.org.name)} ${note(`(${account.org.guid})`)} as ${highlight(account.user.email || account.name)}.`); + if (acct.isPlatform && acct.org?.name) { + console.log(`You are already logged into a ${highlight('platform')} account in organization ${highlight(acct.org.name)} ${note(`(${acct.org.guid})`)} as ${highlight(acct.user.email || acct.name)}.`); } else { - console.log(`You are already logged into a ${highlight('service')} account as ${highlight(account.user.email || account.name)}.`); + console.log(`You are already logged into a ${highlight('service')} account as ${highlight(acct.user.email || acct.name)}.`); } - console.log(await renderAccountInfo(account, config, sdk)); + console.log(await renderAccountInfo(acct, config, sdk)); return; } diff --git a/packages/axway-cli-auth/src/auth/logout.js b/packages/axway-cli-auth/src/auth/logout.ts similarity index 69% rename from packages/axway-cli-auth/src/auth/logout.js rename to packages/axway-cli-auth/src/auth/logout.ts index c765f14f..9a609b02 100644 --- a/packages/axway-cli-auth/src/auth/logout.js +++ b/packages/axway-cli-auth/src/auth/logout.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ '!revoke' ], args: [ @@ -9,29 +14,24 @@ export default { desc: 'Log out all or specific accounts', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs revoked accounts as JSON' } }, - async action({ argv, cli, console }) { - const [ - { initSDK, isHeadless }, - { default: snooplogg } - ] = await Promise.all([ - import('@axway/amplify-cli-utils'), - import('snooplogg') - ]); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initSDK, isHeadless } = await import('@axway/amplify-cli-utils'); + const { default: snooplogg } = await import('snooplogg'); - if (!argv.accounts.length) { + if (!(argv.accounts as string[]).length) { argv.all = true; } const { highlight, warning } = snooplogg.styles; - const { sdk } = initSDK({ - baseUrl: argv.baseUrl, - env: argv.env, - realm: argv.realm + const { sdk } = await initSDK({ + baseUrl: argv.baseUrl as string, + env: argv.env as string, + realm: argv.realm as string }); const revoked = await sdk.auth.logout({ ...argv, diff --git a/packages/axway-cli-auth/src/auth/server-info.js b/packages/axway-cli-auth/src/auth/server-info.js deleted file mode 100644 index 5736cce5..00000000 --- a/packages/axway-cli-auth/src/auth/server-info.js +++ /dev/null @@ -1,15 +0,0 @@ -export default { - hidden: true, - name: 'server-info', - async action({ argv, console }) { - const { initSDK } = await import('@axway/amplify-cli-utils'); - const { sdk } = initSDK({ - baseUrl: argv.baseUrl, - env: argv.env, - realm: argv.realm - }); - - const info = await sdk.auth.serverInfo(); - console.log(JSON.stringify(info, null, 2)); - } -}; diff --git a/packages/axway-cli-auth/src/auth/server-info.ts b/packages/axway-cli-auth/src/auth/server-info.ts new file mode 100644 index 00000000..f46d8851 --- /dev/null +++ b/packages/axway-cli-auth/src/auth/server-info.ts @@ -0,0 +1,17 @@ +import { AxwayCLIState } from '@axway/amplify-cli-utils'; + +export default { + hidden: true, + name: 'server-info', + async action({ argv, console }: AxwayCLIState): Promise { + const { initSDK } = await import('@axway/amplify-cli-utils'); + const { sdk } = await initSDK({ + baseUrl: argv.baseUrl as string, + env: argv.env as string, + realm: argv.realm as string + }); + + const info = await sdk.auth.serverInfo(); + console.log(JSON.stringify(info, null, 2)); + } +}; diff --git a/packages/axway-cli-auth/src/auth/switch.js b/packages/axway-cli-auth/src/auth/switch.ts similarity index 75% rename from packages/axway-cli-auth/src/auth/switch.js rename to packages/axway-cli-auth/src/auth/switch.ts index 75eb2ad7..054ccfde 100644 --- a/packages/axway-cli-auth/src/auth/switch.js +++ b/packages/axway-cli-auth/src/auth/switch.ts @@ -1,3 +1,12 @@ +import { + Account, + Team +} from '@axway/amplify-sdk'; +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { desc: 'Select default account, organization, and team', help: `Once authenticated, the "switch" command allows you to change the default @@ -14,26 +23,26 @@ more than one of org or team.`, options: { '--account [name]': 'The account to switch to', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Disables prompting and outputs selected account and org as JSON' }, '--org [guid|id|name]': 'The platform organization to switch to', '--team [guid|name]': 'The team to use for the selected account' }, - async action({ argv, cli, console }) { - const { default: snooplogg } = require('snooplogg'); - const { getAuthConfigEnvSpecifier, initSDK, isHeadless } = require('@axway/amplify-cli-utils'); - const { renderAccountInfo } = require('../lib/info'); - const { prompt } = require('enquirer'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { default: snooplogg } = await import('snooplogg'); + const { getAuthConfigEnvSpecifier, initSDK, isHeadless } = await import('@axway/amplify-cli-utils'); + const { renderAccountInfo } = await import('../lib/info.js'); + const { prompt } = await import('enquirer'); const { highlight, note } = snooplogg.styles; - const { config, sdk } = initSDK({ - baseUrl: argv.baseUrl, - env: argv.env, - realm: argv.realm + const { config, sdk } = await initSDK({ + baseUrl: argv.baseUrl as string, + env: argv.env as string, + realm: argv.realm as string }); const authConfigEnvSpecifier = getAuthConfigEnvSpecifier(sdk.env.name); const accounts = await sdk.auth.list({ validate: true }); - let account; + let account: Account | undefined; if (!accounts.length) { throw new Error('No authenticated accounts found'); @@ -48,13 +57,7 @@ more than one of org or team.`, } if (argv.account) { - account = await sdk.auth.find(argv.account); - if (!account) { - const err = new Error(`Account "${argv.account}" not found`); - err.code = 'ERR_NOT_FOUND'; - err.details = `Authenticated accounts:\n${accounts.map(a => ` ${highlight(a.name)}`).join('\n')}`; - throw err; - } + account = await sdk.auth.find(argv.account as string); } else { // pick account from the list of of authenticated accounts let accountName = accounts[0]?.name; @@ -62,7 +65,7 @@ more than one of org or team.`, if (accounts.length > 1 && !argv.json) { // we have more than one authenticated account, so we must prompt for which account const defaultAccount = config.get(`${authConfigEnvSpecifier}.defaultAccount`); - const choices = accounts + const choices: any[] = accounts .map(acct => ({ value: acct.name })) .sort((a, b) => a.value.localeCompare(b.value)); const initial = choices.findIndex(a => a.value === defaultAccount); @@ -83,6 +86,13 @@ more than one of org or team.`, } } + if (!account) { + const err: any = new Error(`Account "${argv.account}" not found`); + err.code = 'ERR_NOT_FOUND'; + err.details = `Authenticated accounts:\n${accounts.map(a => ` ${highlight(a.name)}`).join('\n')}`; + throw err; + } + account.default = true; config.set(`${authConfigEnvSpecifier}.defaultAccount`, account.name); config.delete(`${authConfigEnvSpecifier}.defaultOrg.${account.hash}`); @@ -94,9 +104,9 @@ more than one of org or team.`, const o = account.org; if (org && org.toLowerCase() !== o.guid?.toLowerCase() - && org !== String(o.id) + && org !== String(o.org_id) && (!o.name || org.toLowerCase() !== o.name.toLowerCase())) { - throw new Error(`Specified organization "${org}" does not match the service account's organization (${o.guid || o.id})`); + throw new Error(`Specified organization "${org}" does not match the service account's organization (${o.guid || o.org_id})`); } } @@ -104,18 +114,18 @@ more than one of org or team.`, // determine the org const defaultOrg = account?.hash && config.get(`${authConfigEnvSpecifier}.defaultOrg.${account.hash}`); const selectedOrg = argv.org || defaultOrg; - const org = selectedOrg && account.orgs.find(o => o.guid === selectedOrg || String(o.id) === selectedOrg || o.name.toLowerCase() === selectedOrg.toLowerCase()); + const org = selectedOrg && account.orgs.find(o => o.guid === selectedOrg || String(o.org_id) === selectedOrg || o.name.toLowerCase() === selectedOrg.toLowerCase()); if (account.isPlatformTooling) { if (argv.org && !org) { // if there was an explicit --org or default org that wasn't found, then we error for tooling users as web doesn't care - const err = new Error(`Unable to find organization "${argv.org}"`); + const err: any = new Error(`Unable to find organization "${argv.org}"`); err.code = 'ERR_NOT_FOUND'; err.details = `Available organizations:\n${account.orgs.map(a => ` ${highlight(a.name)}`).join('\n')}`; throw err; } } else { - account = await sdk.auth.switchOrg(account, org?.id, { + account = await sdk.auth.switchOrg(account, org?.org_id, { onOpenBrowser() { if (isHeadless()) { throw new Error('Switching default account and organization requires a web browser and is unsupported in headless environments'); @@ -123,7 +133,7 @@ more than one of org or team.`, console.log('Launching web browser to switch organization...'); } } - }); + }) as Account; } } @@ -131,12 +141,15 @@ more than one of org or team.`, // determine the team const defaultTeam = account?.hash && config.get(`${authConfigEnvSpecifier}.defaultTeam.${account.hash}`); const selectedTeam = String(argv.team || defaultTeam || ''); - let team = selectedTeam && account.org.teams.find(t => t.guid.toLowerCase() === selectedTeam.toLowerCase() || t.name.toLowerCase() === selectedTeam.toLowerCase()); + let team: Team | undefined; + if (selectedTeam) { + team = account.org.teams.find(t => t.guid.toLowerCase() === selectedTeam.toLowerCase() || t.name.toLowerCase() === selectedTeam.toLowerCase()); + } if (!team) { if (argv.team) { // if there was an explicit --org that wasn't found, then we error for tooling users as web doesn't care - const err = `Unable to find team "${argv.team}"`; + const err: any = new Error(`Unable to find team "${argv.team}"`); err.code = 'ERR_NOT_FOUND'; err.details = `Available teams:\n${account.org.teams.map(t => ` ${highlight(t.name)} ${note(`(${t.guid})`)}`).join('\n')}`; throw err; @@ -149,7 +162,7 @@ more than one of org or team.`, throw new Error('Must specify --team when --json is set and the selected account has multiple teams'); } - const choices = account.org.teams + const choices: any[] = account.org.teams .map(team => { team.toString = () => team.name; return { @@ -160,11 +173,10 @@ more than one of org or team.`, }) .sort((a, b) => a.message.localeCompare(b.message)); const initial = choices.findIndex(team => team.guid === defaultTeam); - const { prompt } = require('enquirer'); team = (await prompt({ choices, - format: function () { + format: function (this: any) { // for some reason, enquirer doesn't print the selected value using the primary // (green) color for select prompts, so we just force it for all prompts return this.style(this.value); @@ -173,27 +185,21 @@ more than one of org or team.`, message: 'Select an team to use', name: 'team', styles: { - em(msg) { + em(this: any, msg: string): string { // stylize emphasised text with just the primary color, no underline return this.primary(msg); } }, type: 'select' - })).team; + } as any) as any).team as Team; console.log(); } } if (team) { - account.team = { - default: team.default, - guid: team.guid, - name: team.name, - roles: team.users?.find(u => u.guid === account.user.guid)?.roles || [], - tags: team.tags - }; - await sdk.authClient.updateAccount(account); + account.team = (await sdk.team.find(account, account.org, team.guid)).team; + await sdk.auth.client.updateAccount(account); } } diff --git a/packages/axway-cli-auth/src/auth/whoami.js b/packages/axway-cli-auth/src/auth/whoami.ts similarity index 71% rename from packages/axway-cli-auth/src/auth/whoami.js rename to packages/axway-cli-auth/src/auth/whoami.ts index 1a3326a9..894d095e 100644 --- a/packages/axway-cli-auth/src/auth/whoami.js +++ b/packages/axway-cli-auth/src/auth/whoami.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { args: [ { @@ -9,17 +14,17 @@ export default { help: 'Display the currently selected account, organizations, roles, and teams.', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs accounts as JSON' } }, - async action({ argv, console }) { - const { getAuthConfigEnvSpecifier, initSDK } = require('@axway/amplify-cli-utils'); - const { renderAccountInfo } = require('../lib/info'); - const { config, sdk } = initSDK({ - baseUrl: argv.baseUrl, - env: argv.env, - realm: argv.realm + async action({ argv, console }: AxwayCLIState): Promise { + const { getAuthConfigEnvSpecifier, initSDK } = await import('@axway/amplify-cli-utils'); + const { renderAccountInfo } = await import('../lib/info.js'); + const { config, sdk } = await initSDK({ + baseUrl: argv.baseUrl as string, + env: argv.env as string, + realm: argv.realm as string }); const authConfigEnvSpecifier = getAuthConfigEnvSpecifier(sdk.env.name); let accounts = await sdk.auth.list({ @@ -39,7 +44,7 @@ export default { if (argv.json) { console.log(JSON.stringify(accounts, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; if (accounts.length) { @@ -56,7 +61,7 @@ export default { console.log(await renderAccountInfo(account, config, sdk)); } else if (argv.accountName) { - console.log(`The account ${highlight(argv.accountName)} is not logged in.`); + console.log(`The account ${highlight(argv.accountName as string)} is not logged in.`); } else { console.log('You are not logged in.'); } diff --git a/packages/axway-cli-auth/src/lib/info.js b/packages/axway-cli-auth/src/lib/info.ts similarity index 81% rename from packages/axway-cli-auth/src/lib/info.js rename to packages/axway-cli-auth/src/lib/info.ts index 8f989ca8..87100c15 100644 --- a/packages/axway-cli-auth/src/lib/info.js +++ b/packages/axway-cli-auth/src/lib/info.ts @@ -1,5 +1,6 @@ import snooplogg from 'snooplogg'; -import { createTable } from '@axway/amplify-cli-utils'; +import { Config, createTable } from '@axway/amplify-cli-utils'; +import AmplifySDK, { Account } from '@axway/amplify-sdk'; const { green, highlight, note } = snooplogg.styles; const check = process.platform === 'win32' ? '√' : '✔'; @@ -10,17 +11,18 @@ const check = process.platform === 'win32' ? '√' : '✔'; * @param {Object} account - The account object. * @param {Config} config - The Amplify config object. * @param {AmplifySDK} sdk - The Amplify SDK instance. + * @returns {String} */ -export async function renderAccountInfo(account, config, sdk) { +export async function renderAccountInfo(account: Account, config: Config, sdk: AmplifySDK): Promise { let s = `The current region is set to ${highlight(config.get('region', account.org?.region || 'US'))}.`; if (account.orgs?.length) { const table = createTable([ 'Organization', 'GUID', 'ORG ID' ]); - for (const { default: def, guid, id, name } of account.orgs) { + for (const { default: def, guid, name, org_id } of account.orgs) { table.push([ def ? green(`${check} ${name}`) : ` ${name}`, guid, - id + org_id ]); } s += `\n\n${table.toString()}`; @@ -42,7 +44,7 @@ export async function renderAccountInfo(account, config, sdk) { if (account.team) { const teams = account.org.teams.sort((a, b) => { - return a.guid === account.guid ? 1 : a.name.localeCompare(b.guid); + return a.guid === account.team?.guid ? 1 : a.name.localeCompare(b.guid); }); const table = createTable([ account.org.name ? `"${account.org.name}" Teams` : 'Teams', 'GUID', 'Role' ]); for (let i = 0; i < teams.length; i++) { diff --git a/packages/axway-cli-auth/src/lib/keypair.js b/packages/axway-cli-auth/src/lib/keypair.ts similarity index 70% rename from packages/axway-cli-auth/src/lib/keypair.js rename to packages/axway-cli-auth/src/lib/keypair.ts index 07be4c61..8ffa6ab0 100644 --- a/packages/axway-cli-auth/src/lib/keypair.js +++ b/packages/axway-cli-auth/src/lib/keypair.ts @@ -2,6 +2,29 @@ import path from 'path'; import { existsSync, writeFileSync } from '@axway/amplify-utils'; import { initSDK } from '@axway/amplify-cli-utils'; import { prompt } from 'enquirer'; +import { CLIError } from 'cli-kit'; + +export interface GenerateKeypairOptions { + force?: boolean; + privateKey?: string; + publicKey?: string; + silent?: boolean; +} + +export interface KeyInfo { + cert?: string, + file: string, + label: string +} + +export interface Keypair { + privateKey?: KeyInfo, + publicKey?: KeyInfo +} + +export interface KeypairResult extends Keypair { + cert?: string +} /** * Generates a public/private keypair. It prompts for the output filenames and whether to overwrite @@ -16,16 +39,16 @@ import { prompt } from 'enquirer'; * files will assume the defaults. If the destination files exist, an error is thrown. * @returns {Promise} Resolves the generated `publicKey` and `privateKey`. */ -export async function generateKeypair(opts = {}) { +export async function generateKeypair(opts: GenerateKeypairOptions = {}): Promise { if (!opts || typeof opts !== 'object') { throw new TypeError('Expected options to be an object'); } const { force, publicKey, privateKey, silent } = opts; - const { sdk } = initSDK(); + const { sdk } = await initSDK(); const certs = await sdk.client.generateKeyPair(); - const files = { + const files: Keypair = { privateKey: await validate({ force, initial: 'private_key.pem', @@ -44,13 +67,17 @@ export async function generateKeypair(opts = {}) { }; return Object.keys(files).reduce((result, type) => { - if (files[type]) { - writeFileSync(files[type].file, certs[type]); - result[type] = files[type]; - result[type].cert = certs[type]; + const info: KeyInfo | undefined = files[type as keyof Keypair]; + if (info) { + writeFileSync(info.file, certs[type as keyof Keypair]); + result[type as keyof Keypair] = { + cert: certs[type as keyof Keypair], + file: info.file, + label: info.label + }; } return result; - }, {}); + }, {} as KeypairResult); } /** @@ -65,7 +92,13 @@ export async function generateKeypair(opts = {}) { * @param {String} opts.value - The output file path. * @returns {Promise} */ -async function validate({ force, initial, label, silent, value }) { +async function validate({ force, initial, label, silent, value }: { + force?: boolean, + initial: string, + label: string, + silent?: boolean, + value?: string +}): Promise { if (!value) { value = initial; @@ -82,11 +115,11 @@ async function validate({ force, initial, label, silent, value }) { } } - const file = path.resolve(value); + const file = path.resolve(value as string); if (existsSync(file) && !force) { if (silent) { - const err = new Error(`${label} file exists: ${value}`); + const err = new Error(`${label} file exists: ${value}`) as CLIError; err.showHelp = false; throw err; } @@ -94,7 +127,7 @@ async function validate({ force, initial, label, silent, value }) { message: `"${file}" already exists, overwrite?`, name: 'overwrite', type: 'confirm' - }); + }) as any; if (!overwrite) { return; } diff --git a/packages/axway-cli-auth/src/service-account/add-team.js b/packages/axway-cli-auth/src/service-account/add-team.ts similarity index 65% rename from packages/axway-cli-auth/src/service-account/add-team.js rename to packages/axway-cli-auth/src/service-account/add-team.ts index 61baedbe..1a029053 100644 --- a/packages/axway-cli-auth/src/service-account/add-team.js +++ b/packages/axway-cli-auth/src/service-account/add-team.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand } from 'cli-kit'; + export default { args: [ { @@ -20,48 +26,54 @@ export default { ], desc: 'Add a team to a service account', help: { - header() { + header(this: CLICommand): string { return `${this.desc}.`; } }, options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid' }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount( + argv.account as string | undefined, + argv.org as string | undefined, + argv.env as string | undefined + ); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to modify a service account in the "${org.name}" organization`); } // get the service account and team - const { client: existing } = await sdk.client.find(account, org, argv.clientId); - const { team } = await sdk.team.find(account, org, argv.teamGuid); + const { client: existing } = await sdk.client.find(account, org, argv.clientId as string); + const { team } = await sdk.team.find(account, org, argv.teamGuid as string); // add the team to the existing list of teams const teams = (existing.teams || []).map(({ guid, roles }) => ({ guid, roles })); teams.push({ guid: team.guid, - roles: [ argv.role ] + roles: [ argv.role as string ] }); // update the service account - const results = await sdk.client.update(account, org, { - client: existing, - teams - }); - results.account = account; + const results = { + ...(await sdk.client.update(account, org, { + client: existing, + teams + })), + account + }; if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); diff --git a/packages/axway-cli-auth/src/service-account/create.js b/packages/axway-cli-auth/src/service-account/create.ts similarity index 76% rename from packages/axway-cli-auth/src/service-account/create.js rename to packages/axway-cli-auth/src/service-account/create.ts index d9468bae..b212fa7b 100644 --- a/packages/axway-cli-auth/src/service-account/create.js +++ b/packages/axway-cli-auth/src/service-account/create.ts @@ -1,3 +1,11 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { + CLIHelpOptions +} from 'cli-kit'; + export default { aliases: [ '!add', '!new' ], desc: 'Create a service account', @@ -14,7 +22,7 @@ If the service account name is not specified, then the command will interactively prompt for all values. If prompting is not available, then all required options must be passed in at execution.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} Create a service account and prompt for name, type, etc: @@ -34,7 +42,7 @@ required options must be passed in at execution.`; '--account [name]': 'The platform account to use', '--desc [value]': 'The description of the service account', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs result as JSON' }, '--name [value]': 'Friendly name to use for display', @@ -47,19 +55,23 @@ required options must be passed in at execution.`; }, '--secret [key]': 'A custom client secret key' }, - async action({ argv, cli, console, help, terminal }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { existsSync, isFile } = require('@axway/amplify-utils'); - const { generateKeypair } = require('../lib/keypair'); - const { prompt } = require('enquirer'); - const { readFileSync } = require('fs'); - const uuid = require('uuid'); - const { default: snooplogg } = require('snooplogg'); - const { highlight, note } = snooplogg.styles; - - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - - if (!org.userRoles.includes('administrator')) { + async action({ argv, cli, console, help, terminal }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { existsSync, isFile } = await import('@axway/amplify-utils'); + const { generateKeypair } = await import('../lib/keypair'); + const { prompt } = await import('enquirer'); + const { readFileSync } = await import('fs'); + const { default: uuid } = await import('uuid'); + const { default: snooplogg } = await import('snooplogg'); + const { highlight, note } = snooplogg.styles; + + const { account, org, sdk } = await initPlatformAccount( + argv.account as string, + argv.org as string, + argv.env as string + ); + + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to create a service account in the "${org.name}" organization`); } @@ -74,9 +86,15 @@ required options must be passed in at execution.`; publicKey, role: roles, secret - } = argv; + } = argv as { + desc: string, + name: string, + publicKey: string, + role: string[], + secret: string + }; let prompted = false; - const doPrompt = opts => { + const doPrompt = (opts: any) => { prompted = true; return prompt(opts); }; @@ -93,10 +111,10 @@ required options must be passed in at execution.`; message: 'Display name', name: 'name', type: 'input', - validate(s) { + validate(s: string) { return s ? true : 'Please enter a service account name'; } - })); + }) as any); } if (!desc && !argv.name) { @@ -105,7 +123,11 @@ required options must be passed in at execution.`; message: 'Description', name: 'desc', type: 'input' - })); + }) as any); + } + + if (typeof secret === 'number') { + secret = String(secret); } if (!secret && !publicKey) { @@ -123,7 +145,7 @@ required options must be passed in at execution.`; message: 'Authentication method', name: 'type', type: 'select' - }); + }) as any; if (type === 'auto') { secret = uuid.v4(); @@ -132,16 +154,16 @@ required options must be passed in at execution.`; message: 'Secret key', name: 'secret', type: 'password', - validate(s) { + validate(s: string) { return s ? true : 'Please enter a client secret key'; } - })); + }) as any); } else if (type === 'publicKey') { ({ publicKey } = await doPrompt({ message: 'Public key file path', name: 'publicKey', type: 'input', - validate(s) { + validate(s: string) { if (!s) { return 'Please enter the path to the PEM formatted public key file'; } @@ -153,14 +175,13 @@ required options must be passed in at execution.`; } return true; } - })); + }) as any); } else if (type === 'generate') { const certs = await generateKeypair({ - console, - silent: argv.json || !terminal.stdout.isTTY + silent: !!argv.json || !terminal.stdout.isTTY }); - publicKey = certs.publicKey.file; + publicKey = certs.publicKey?.file as string; } } @@ -172,7 +193,7 @@ required options must be passed in at execution.`; message: 'Roles', name: 'roles', type: 'multiselect' - })); + }) as any); } // validate the public key @@ -190,15 +211,21 @@ required options must be passed in at execution.`; } } - const results = await sdk.client.create(account, org, { + const { client } = await sdk.client.create(account, org, { desc, name, publicKey, secret, roles }); - results.account = account.name; - results.client.secret = secret; + const results = { + client: { + ...client, + secret + }, + org, + account + }; if (argv.json) { console.log(JSON.stringify(results, null, 2)); @@ -207,7 +234,7 @@ required options must be passed in at execution.`; console.log(); } - const { client_id } = results.client; + const { client_id } = client; console.log('Successfully created service account\n'); if (secret) { diff --git a/packages/axway-cli-auth/src/service-account/generate-keypair.js b/packages/axway-cli-auth/src/service-account/generate-keypair.ts similarity index 69% rename from packages/axway-cli-auth/src/service-account/generate-keypair.js rename to packages/axway-cli-auth/src/service-account/generate-keypair.ts index 6b50aac0..6a73a2e2 100644 --- a/packages/axway-cli-auth/src/service-account/generate-keypair.js +++ b/packages/axway-cli-auth/src/service-account/generate-keypair.ts @@ -1,10 +1,16 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { desc: 'Create a pem formatted public/private key pair', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} Create a keypair and be prompted for the output filenames: @@ -26,27 +32,26 @@ export default { options: { '--yes': 'Automatic yes to overwrite existing output files and run non-interactively', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs result as JSON' }, '--private-key [path]': 'The file to output the private key to', '--public-key [path]': 'The file to output the public key to' }, - async action({ argv, console, terminal }) { - const { generateKeypair } = require('../lib/keypair'); + async action({ argv, console, terminal }: AxwayCLIState): Promise { + const { generateKeypair } = await import('../lib/keypair'); const certs = await generateKeypair({ - console, - force: argv.yes, - publicKey: argv.publicKey, - privateKey: argv.privateKey, - silent: argv.json || !terminal.stdout.isTTY + force: !!argv.yes, + publicKey: argv.publicKey as string, + privateKey: argv.privateKey as string, + silent: !!argv.json || !terminal.stdout.isTTY }); if (argv.json) { console.log(JSON.stringify(certs, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight } = snooplogg.styles; for (const { file, label } of Object.values(certs)) { console.log(`Wrote ${label.toLowerCase()}: ${highlight(file)}`); diff --git a/packages/axway-cli-auth/src/service-account/index.js b/packages/axway-cli-auth/src/service-account/index.ts similarity index 89% rename from packages/axway-cli-auth/src/service-account/index.js rename to packages/axway-cli-auth/src/service-account/index.ts index d329d2c6..9ecda0ce 100644 --- a/packages/axway-cli-auth/src/service-account/index.js +++ b/packages/axway-cli-auth/src/service-account/index.ts @@ -1,3 +1,9 @@ +import path from 'path'; +import { CLIHelpOptions } from 'cli-kit'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + export default { commands: [ `${__dirname}/add-team.js`, @@ -12,7 +18,7 @@ export default { ], desc: 'Create and manage service accounts', help: { - header({ style }) { + header({ style }: CLIHelpOptions): string { return `Create and manage service accounts, generate public/private keypairs, and assign teams. @@ -26,7 +32,7 @@ a SSH terminal, you must set the token store type to "file": ${style.highlight('axway config set auth.tokenStoreType file')}`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} List all service accounts: diff --git a/packages/axway-cli-auth/src/service-account/list.js b/packages/axway-cli-auth/src/service-account/list.ts similarity index 60% rename from packages/axway-cli-auth/src/service-account/list.js rename to packages/axway-cli-auth/src/service-account/list.ts index ab30dda0..4b107907 100644 --- a/packages/axway-cli-auth/src/service-account/list.js +++ b/packages/axway-cli-auth/src/service-account/list.ts @@ -1,22 +1,32 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand } from 'cli-kit'; + export default { aliases: [ 'ls' ], desc: 'List all service accounts', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; } }, options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs service accounts as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid' }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount( + argv.account as string, + argv.org as string, + argv.env as string + ); const { clients } = await sdk.client.list(account, org); if (argv.json) { @@ -28,7 +38,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); @@ -41,12 +51,12 @@ export default { const table = createTable([ 'Client ID', 'Name', 'Auth Method', 'Teams', 'Roles', 'Date Created' ]); - for (const { client_id, created, method, name, roles, teams } of clients) { + for (const { client_id, created, method, name, roles, team_count } of clients) { table.push([ highlight(client_id), name, method, - teams, + team_count, roles?.join(', ') || 'n/a', new Date(created).toLocaleDateString() ]); diff --git a/packages/axway-cli-auth/src/service-account/remove-team.js b/packages/axway-cli-auth/src/service-account/remove-team.ts similarity index 66% rename from packages/axway-cli-auth/src/service-account/remove-team.js rename to packages/axway-cli-auth/src/service-account/remove-team.ts index 5b3f4f95..de7c9dca 100644 --- a/packages/axway-cli-auth/src/service-account/remove-team.js +++ b/packages/axway-cli-auth/src/service-account/remove-team.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand } from 'cli-kit'; + export default { args: [ { @@ -15,29 +21,33 @@ export default { ], desc: 'Remove a team from a service account', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; } }, options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid' }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount( + argv.account as string, + argv.org as string, + argv.env as string + ); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to modify a service account in the "${org.name}" organization`); } // get the service account and team - const { client: existing } = await sdk.client.find(account, org, argv.clientId); - const { team } = await sdk.team.find(account, org, argv.teamGuid); + const { client: existing } = await sdk.client.find(account, org, argv.clientId as string); + const { team } = await sdk.team.find(account, org, argv.teamGuid as string); // add the team to the existing list of teams const teams = (existing.teams || []) @@ -45,16 +55,18 @@ export default { .filter(t => t.guid !== team.guid); // update the service account - const results = await sdk.client.update(account, org, { - client: existing, - teams - }); - results.account = account; + const results = { + ...(await sdk.client.update(account, org, { + client: existing, + teams + })), + account + }; if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); diff --git a/packages/axway-cli-auth/src/service-account/remove.js b/packages/axway-cli-auth/src/service-account/remove.ts similarity index 64% rename from packages/axway-cli-auth/src/service-account/remove.js rename to packages/axway-cli-auth/src/service-account/remove.ts index 9c946b2e..9b4f0810 100644 --- a/packages/axway-cli-auth/src/service-account/remove.js +++ b/packages/axway-cli-auth/src/service-account/remove.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand } from 'cli-kit'; + export default { aliases: [ 'rm' ], args: [ @@ -10,27 +16,31 @@ export default { ], desc: 'Remove a service account', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; } }, options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid' }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount( + argv.account as string, + argv.org as string, + argv.env as string + ); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to remove a service account in the "${org.name}" organization`); } - const { client } = await sdk.client.remove(account, org, argv.clientId); + const { client } = await sdk.client.remove(account, org, argv.clientId as string); const results = { account: account.name, org, @@ -40,7 +50,7 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); diff --git a/packages/axway-cli-auth/src/service-account/roles.js b/packages/axway-cli-auth/src/service-account/roles.ts similarity index 66% rename from packages/axway-cli-auth/src/service-account/roles.js rename to packages/axway-cli-auth/src/service-account/roles.ts index a2565946..6e2050e0 100644 --- a/packages/axway-cli-auth/src/service-account/roles.js +++ b/packages/axway-cli-auth/src/service-account/roles.ts @@ -1,21 +1,31 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand } from 'cli-kit'; + export default { desc: 'View available service account roles', help: { - header() { + header(this: CLICommand): string { return `${this.desc}.`; } }, options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs service accounts as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid; roles vary by org' }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount( + argv.account as string, + argv.org as string, + argv.env as string + ); const orgRoles = await sdk.role.list(account, { client: true, org }); const teamRoles = await sdk.role.list(account, { team: true, org }); @@ -29,7 +39,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); diff --git a/packages/axway-cli-auth/src/service-account/update.js b/packages/axway-cli-auth/src/service-account/update.ts similarity index 63% rename from packages/axway-cli-auth/src/service-account/update.js rename to packages/axway-cli-auth/src/service-account/update.ts index b280299d..bb441062 100644 --- a/packages/axway-cli-auth/src/service-account/update.js +++ b/packages/axway-cli-auth/src/service-account/update.ts @@ -1,3 +1,10 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { ClientUpdateParams } from '@axway/amplify-sdk'; +import { CLIHelpOptions } from 'cli-kit'; + export default { args: [ { @@ -17,7 +24,7 @@ call. You cannot change a service account's authentication method from client secret to public key and vice versa.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} Change a service account name, description, and role: @@ -34,7 +41,7 @@ to public key and vice versa.`; '--account [name]': 'The platform account to use', '--desc [value]': 'The description of the service account', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs service account as JSON' }, '--name [value]': 'Friendly name to use for display', @@ -47,38 +54,42 @@ to public key and vice versa.`; }, '--secret [key]': 'A custom client secret key' }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { existsSync, isFile } = require('@axway/amplify-utils'); - const { readFileSync } = require('fs'); - - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - - if (!org.userRoles.includes('administrator')) { + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { existsSync, isFile } = await import('@axway/amplify-utils'); + const { readFileSync } = await import('fs'); + + const { account, org, sdk } = await initPlatformAccount( + argv.account as string, + argv.org as string, + argv.env as string + ); + + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to update a service account in the "${org.name}" organization`); } - const data = { - client: argv.id + const data: ClientUpdateParams = { + client: argv.id as string }; if (argv.name !== undefined) { - data.name = argv.name; + data.name = argv.name as string; } if (argv.desc !== undefined) { - data.desc = argv.desc; + data.desc = argv.desc as string; } if (argv.publicKey !== undefined) { - if (!existsSync(argv.publicKey)) { + if (!existsSync(argv.publicKey as string)) { throw new Error(`Public key ${argv.publicKey} does not exist`); } - if (!isFile(argv.publicKey)) { + if (!isFile(argv.publicKey as string)) { throw new Error(`Public key ${argv.publicKey} is not a file`); } const publicKeyFile = argv.publicKey; - data.publicKey = readFileSync(publicKeyFile, 'utf-8'); + data.publicKey = readFileSync(publicKeyFile as string, 'utf-8'); if (!data.publicKey.startsWith('-----BEGIN PUBLIC KEY-----')) { throw new Error(`Public key ${publicKeyFile} is not a PEM formatted file`); } @@ -86,20 +97,25 @@ to public key and vice versa.`; if (argv.role !== undefined) { // filter out all falsey/empty roles or `true` - data.roles = argv.role.filter(r => r && r !== true); + // note that --role without an explicit value is set to `true` + data.roles = (argv.role as (string | boolean)[]).filter(r => r && r !== true) as string[]; } - if (argv.secret !== undefined) { - data.secret = argv.secret; + if (typeof argv.secret === 'number') { + data.secret = String(argv.secret); + } else if (argv.secret !== undefined) { + data.secret = argv.secret as string; } - const results = await sdk.client.update(account, org, data); - results.account = account.name; + const results = { + ...(await sdk.client.update(account, org, data)), + account + }; if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}\n`); diff --git a/packages/axway-cli-auth/src/service-account/view.js b/packages/axway-cli-auth/src/service-account/view.ts similarity index 70% rename from packages/axway-cli-auth/src/service-account/view.js rename to packages/axway-cli-auth/src/service-account/view.ts index cbcf7578..5a3ec099 100644 --- a/packages/axway-cli-auth/src/service-account/view.js +++ b/packages/axway-cli-auth/src/service-account/view.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand } from 'cli-kit'; + export default { args: [ { @@ -10,29 +16,33 @@ export default { aliases: [ 'v', '!info', '!show' ], desc: 'View service account details', help: { - header() { + header(this: CLICommand): string { return `${this.desc}.`; } }, options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs service account as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid' }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const result = await sdk.client.find(account, org, argv.id); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount( + argv.account as string, + argv.org as string, + argv.env as string + ); + const result = await sdk.client.find(account, org, argv.id as string); if (argv.json) { console.log(JSON.stringify(result, null, 2)); return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; const { client } = result; @@ -64,16 +74,13 @@ export default { console.log('\nTEAMS'); if (client.teams.length) { - const table = createTable([ ' Name', 'Role', 'Description', 'Team GUID', 'User', 'Apps', 'Date Created' ]); - for (const { apps, created, desc, guid, name, roles, users } of client.teams) { + const table = createTable([ ' Name', 'Role', 'Description', 'Team GUID' ]); + for (const { desc, guid, name, roles } of client.teams) { table.push([ ` ${name}`, roles.join(', '), desc || '', - guid, - users?.length || 0, - apps?.length || 0, - new Date(created).toLocaleDateString() + guid ]); } console.log(table.toString()); diff --git a/packages/axway-cli-auth/tsconfig.json b/packages/axway-cli-auth/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/axway-cli-auth/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/axway-cli-oum/.eslintrc b/packages/axway-cli-oum/.eslintrc deleted file mode 100644 index f8a1c582..00000000 --- a/packages/axway-cli-oum/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-confusing-arrow": [ "off" ] - } -} diff --git a/packages/axway-cli-oum/.gitignore b/packages/axway-cli-oum/.gitignore deleted file mode 100644 index b3a1d215..00000000 --- a/packages/axway-cli-oum/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -._* -.DS_Store* -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log -yarn-error.log diff --git a/packages/axway-cli-oum/CHANGELOG.md b/packages/axway-cli-oum/CHANGELOG.md index 382d2420..35aac696 100644 --- a/packages/axway-cli-oum/CHANGELOG.md +++ b/packages/axway-cli-oum/CHANGELOG.md @@ -1,3 +1,8 @@ +# v3.0.0 + +- BREAKING CHANGE: Dropped support for Node.js 12 and older. +- chore: Updated dependencies. + # v2.0.11 (Jul 7, 2022) - chore: Updated dependencies. diff --git a/packages/axway-cli-oum/gulpfile.js b/packages/axway-cli-oum/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/axway-cli-oum/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/axway-cli-oum/package.json b/packages/axway-cli-oum/package.json index d0e40b9e..59e15892 100644 --- a/packages/axway-cli-oum/package.json +++ b/packages/axway-cli-oum/package.json @@ -5,6 +5,7 @@ "access": "public" }, "description": "Axway Amplify platform organization and user management CLI", + "type": "module", "author": "Axway, Inc. ", "maintainers": [ "Chris Barber " @@ -15,27 +16,25 @@ "amplify" ], "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1" }, "dependencies": { - "@axway/amplify-cli-utils": "^5.0.11", - "cli-kit": "^1.16.0", + "@axway/amplify-cli-utils": "^5.0.10", + "cli-kit": "^2.0.2", "open": "^8.4.0", - "snooplogg": "^3.0.2", - "source-map-support": "^0.5.21" - }, - "devDependencies": { - "@axway/gulp-tasks": "^4.1.4" + "snooplogg": "^5.0.0" }, "homepage": "https://github.com/appcelerator/amplify-tooling#readme", "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/axway-cli-oum", "engines": { - "node": ">=12.13.0" + "node": ">=14.15.0" }, "cli-kit": { "exports": { @@ -52,6 +51,5 @@ "main": "./dist/user/index.js" } } - }, - "gitHead": "9cc288d8ee067fb3444920aad11c53899455ad9c" + } } diff --git a/packages/axway-cli-oum/src/lib/activity.js b/packages/axway-cli-oum/src/lib/activity.ts similarity index 59% rename from packages/axway-cli-oum/src/lib/activity.js rename to packages/axway-cli-oum/src/lib/activity.ts index ff124af7..92489bda 100644 --- a/packages/axway-cli-oum/src/lib/activity.js +++ b/packages/axway-cli-oum/src/lib/activity.ts @@ -1,32 +1,58 @@ +import { Account, ActivityChange, ActivityEvent, OrgRef } from '@axway/amplify-sdk'; + +interface ExActivityChange extends ActivityChange { + [key: string]: boolean | number | string | string[] | undefined; +} + +export interface RenderActivityOptions { + account: Account, + console: Console, + events: ActivityEvent[], + from: Date, + json: boolean, + org?: OrgRef, + to: Date +} + /** * Renders org and user activity results. * * @param {Object} params - Various parameters. * @param {Object} params.account - The account the activity is for. * @param {Object} params.console - The console instance to write the output to. + * @param {Array.} params.events - The list of activity events. + * @param {Date} params.from - The date range starting date. * @param {Boolean} [params.json] - When `true`, outputs the results as JSON. - * @param {Array.} params.results - The list of activity events. + * @param {Object} [params.org] The organization info, if applicable. + * @param {Date} params.to - The date range ending date. * @returns {Promise} */ -export async function renderActivity({ account, console, json, results }) { +export async function renderActivity({ account, console, events, from, json, org, to }: RenderActivityOptions) { if (json) { - console.log(JSON.stringify(results, null, 2)); + console.log(JSON.stringify({ + account, + org, + from, + to, + events + }, null, 2)); return; } - const { createTable } = require('@axway/amplify-cli-utils'); - const { default: snooplogg } = require('snooplogg'); + const { createTable } = await import('@axway/amplify-cli-utils'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; - let { from, to, events } = results; - const formatDate = d => { - const dt = d ? new Date(d) : new Date(); + const formatDate = (dt: Date | number): string => { + if (!(dt instanceof Date)) { + dt = new Date(dt); + } return `${dt.getUTCMonth() + 1}/${dt.getUTCDate()}/${dt.getUTCFullYear()}`; }; console.log(`Account: ${highlight(account.name)}`); - if (results.org) { - console.log(`Organization: ${highlight(results.org.name)} ${note(`(${results.org.guid})`)}`); + if (org) { + console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}`); } console.log(`Date Range: ${highlight(formatDate(from))} - ${highlight(formatDate(to))}\n`); @@ -39,8 +65,9 @@ export async function renderActivity({ account, console, json, results }) { for (const event of events) { let changes = ''; if (event.data && Array.isArray(event.data.changes)) { - const t = str => str.toLowerCase().replace(/(?:^|\s|-)\S/g, c => c.toUpperCase()); - changes = event.data.changes.map((c, i, arr) => { + const t = (str: string): string => str.toLowerCase().replace(/(?:^|\s|-)\S/g, c => c.toUpperCase()); + changes = event.data.changes.map((change, i, arr) => { + const c: ExActivityChange = { ...change }; let unit; if (c.k.startsWith('entitlements.')) { @@ -53,14 +80,14 @@ export async function renderActivity({ account, console, json, results }) { for (const prop of [ 'o', 'v' ]) { if (Object.prototype.hasOwnProperty.call(c, prop)) { - const d = new Date(c[prop]); - if (!isNaN(d)) { + const d = new Date(c[prop] as string); + if (!isNaN(d.valueOf())) { c[prop] = d.toLocaleDateString(); continue; } if (Array.isArray(c[prop])) { - c[prop] = c[prop].join(', '); + c[prop] = (c[prop] as string[]).join(', '); } if (unit) { diff --git a/packages/axway-cli-oum/src/lib/util.js b/packages/axway-cli-oum/src/lib/util.ts similarity index 82% rename from packages/axway-cli-oum/src/lib/util.js rename to packages/axway-cli-oum/src/lib/util.ts index e7c64d58..10930389 100644 --- a/packages/axway-cli-oum/src/lib/util.js +++ b/packages/axway-cli-oum/src/lib/util.ts @@ -4,7 +4,7 @@ * @param {Date|Number} dt - The date to format. * @returns {String} */ -export function formatDate(dt) { +export function formatDate(dt: Date | number): string { if (!(dt instanceof Date)) { dt = new Date(dt); } diff --git a/packages/axway-cli-oum/src/org/activity.js b/packages/axway-cli-oum/src/org/activity.ts similarity index 63% rename from packages/axway-cli-oum/src/org/activity.js rename to packages/axway-cli-oum/src/org/activity.ts index 3c5c95ce..281d5041 100644 --- a/packages/axway-cli-oum/src/org/activity.js +++ b/packages/axway-cli-oum/src/org/activity.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { args: [ { @@ -7,10 +13,10 @@ export default { ], desc: 'Display organization activity report', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Example:')} You must be authenticated into an Amplify Platform account to view or manage @@ -33,7 +39,7 @@ export default { redact: false }, '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the org activity as JSON' }, '--month [mm|yyyy-mm]': { @@ -45,20 +51,16 @@ export default { redact: false } }, - async action({ argv, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { renderActivity } = require('../lib/activity'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { renderActivity } = await import('../lib/activity.js'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); await renderActivity({ account, console, - json: argv.json, - results: { - account: account.name, - org, - ...(await sdk.org.activity(account, org, argv)) - } + json: !!argv.json, + ...(await sdk.org.activity(account, org, argv)) }); } }; diff --git a/packages/axway-cli-oum/src/org/idp.js b/packages/axway-cli-oum/src/org/idp.ts similarity index 58% rename from packages/axway-cli-oum/src/org/idp.js rename to packages/axway-cli-oum/src/org/idp.ts index 7a5ae821..ae21e716 100644 --- a/packages/axway-cli-oum/src/org/idp.js +++ b/packages/axway-cli-oum/src/org/idp.ts @@ -1,3 +1,5 @@ +import { AxwayCLIState } from '@axway/amplify-cli-utils'; + export default { args: [ { @@ -9,14 +11,14 @@ export default { options: { '--account [name]': 'The account to use' }, - async action({ argv, console }) { - const { initPlatformAccount, isHeadless } = require('@axway/amplify-cli-utils'); - const { default: snooplogg } = require('snooplogg'); + async action({ argv, console }: AxwayCLIState): Promise { + const { initPlatformAccount, isHeadless } = await import('@axway/amplify-cli-utils'); + const { default: snooplogg } = await import('snooplogg'); const { highlight } = snooplogg.styles; - const { org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const open = require('open'); + const { org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { default: open } = await import('open'); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error('You do not have administrative access to configure this organization\'s identity provider'); } @@ -28,7 +30,7 @@ export default { throw new Error('Managing identity provider settings requires a web browser and is unsupported in headless environments'); } - const url = `${sdk.platformUrl}#/org/${org.id}/settings/idp`; + const url = `${sdk.platformUrl}#/org/${org.org_id}/settings/idp`; console.log(`Opening web browser to ${highlight(url)}`); await open(url); } diff --git a/packages/axway-cli-oum/src/org/index.js b/packages/axway-cli-oum/src/org/index.ts similarity index 88% rename from packages/axway-cli-oum/src/org/index.js rename to packages/axway-cli-oum/src/org/index.ts index 6d762443..4487135f 100644 --- a/packages/axway-cli-oum/src/org/index.js +++ b/packages/axway-cli-oum/src/org/index.ts @@ -1,3 +1,9 @@ +import path from 'path'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + export default { commands: [ `${__dirname}/activity.js`, @@ -10,10 +16,10 @@ export default { ], desc: 'Manage Amplify Platform organizations', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('General Organization Examples:')} You must be authenticated into an Amplify Platform account to view or manage diff --git a/packages/axway-cli-oum/src/org/list.js b/packages/axway-cli-oum/src/org/list.ts similarity index 62% rename from packages/axway-cli-oum/src/org/list.js rename to packages/axway-cli-oum/src/org/list.ts index bab713b1..e9af1e22 100644 --- a/packages/axway-cli-oum/src/org/list.js +++ b/packages/axway-cli-oum/src/org/list.ts @@ -1,16 +1,21 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'ls' ], desc: 'List organizations', options: { '--account [name]': 'The account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the organizations as JSON' } }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, null, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, undefined, argv.env as string); const orgs = await sdk.org.list(account, org); if (argv.json) { @@ -21,7 +26,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { green, highlight } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}\n`); @@ -33,17 +38,13 @@ export default { const table = createTable([ 'Organization', 'GUID', 'ORG ID' ]); const check = process.platform === 'win32' ? '√' : '✔'; - for (const { default: def, guid, id, name } of orgs) { + for (const { default: def, guid, org_id, name } of orgs) { table.push([ def ? green(`${check} ${name}`) : ` ${name}`, guid, - id + org_id ]); } console.log(table.toString()); - }, - - myOtherFunction() { - console.log('hi from my other function!'); } }; diff --git a/packages/axway-cli-oum/src/org/rename.js b/packages/axway-cli-oum/src/org/rename.ts similarity index 61% rename from packages/axway-cli-oum/src/org/rename.js rename to packages/axway-cli-oum/src/org/rename.ts index bfe740ad..6bc54c04 100644 --- a/packages/axway-cli-oum/src/org/rename.js +++ b/packages/axway-cli-oum/src/org/rename.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { args: [ { @@ -15,21 +20,21 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { default: snooplogg } = require('snooplogg'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { default: snooplogg } = await import('snooplogg'); const { highlight } = snooplogg.styles; - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error('You do not have administrative access to rename the organization'); } - const result = await sdk.org.rename(account, org, argv.name); + const result = await sdk.org.rename(account, org, argv.name as string); if (argv.json) { console.log(JSON.stringify({ diff --git a/packages/axway-cli-oum/src/org/usage.js b/packages/axway-cli-oum/src/org/usage.js deleted file mode 100644 index ae42cb56..00000000 --- a/packages/axway-cli-oum/src/org/usage.js +++ /dev/null @@ -1,203 +0,0 @@ -/* eslint-disable no-loop-func */ - -export default { - args: [ - { - name: 'org', - desc: 'The organization name, id, or guid; defaults to the current org' - } - ], - desc: 'Display organization usage report', - help: { - header() { - return `${this.desc}.`; - }, - footer({ style }) { - return `${style.heading('Example:')} - - You must be authenticated into an Amplify Platform account to view or manage - organizations. Run ${style.highlight('"axway auth login"')} to authenticate. - - Display organization usage for the past 14 days: - ${style.highlight('axway org usage ')} - - Display organization usage for a specific date range: - ${style.highlight('axway org usage --from 2021-04-01 --to 2021-04-30')} - - Display organization usage for the current month: - ${style.highlight('axway org usage --month')}`; - } - }, - options: { - '--account [name]': 'The platform account to use', - '--from [yyyy-mm-dd]': { - desc: 'The start date', - redact: false - }, - '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, - desc: 'Outputs the usage as JSON' - }, - '--month [mm|yyyy-mm]': { - desc: 'A month date range; overrides --to and --from', - redact: false - }, - '--to [yyyy-mm-dd]': { - desc: 'The end date', - redact: false - } - }, - async action({ argv, console }) { - const { formatDate } = require('../lib/util'); - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { bundle, from, to, usage } = await sdk.org.usage(account, org, argv); - const orgEnvs = await sdk.org.environments(account); - const maxEntitlement = 9999999999999; - const { format } = new Intl.NumberFormat(); - let bundleValuePadding = 0; - let saasPercentPadding = 0; - let saasValuePadding = 0; - - // pre-determine the bundle metric environments - if (bundle) { - for (const metric of Object.values(bundle.metrics)) { - metric.envs = Object.entries(metric.envs).map(([ guid, stats ]) => { - bundleValuePadding = Math.max(bundleValuePadding, String(format(stats.value)).length); - return { - ...stats, - guid, - name: orgEnvs.find(e => e.guid === guid)?.name || guid - }; - }); - } - } - - // pre-determine the saas metric environments - for (const data of Object.values(usage)) { - for (const info of Object.values(data)) { - // info.quota = maxEntitlement; - info.unlimited = info.quota === maxEntitlement; - info.formatted = `${format(info.value)} of ${info.unlimited ? 'Unlimited' : format(info.quota)}`; - - if (typeof info.percent === 'number') { - saasPercentPadding = Math.max(saasPercentPadding, String(info.percent).length); - } - saasValuePadding = Math.max(saasValuePadding, info.formatted.length); - - info.envs = Object.entries(info.envs || {}).map(([ name, stats ]) => { - stats.formatted = format(stats.value); - stats.percent = stats.quota && Math.floor(Math.min(stats.value / stats.quota * 100, 100)); - - saasPercentPadding = Math.max(saasPercentPadding, String(stats.percent).length); - saasValuePadding = Math.max(saasValuePadding, stats.formatted.length); - - return { name, ...stats }; - }); - } - } - - const results = { - account: account.name, - org, - from, - to, - bundle, - usage - }; - - if (argv.json) { - console.log(JSON.stringify(results, null, 2)); - return; - } - - const { default: snooplogg } = require('snooplogg'); - const { bold, gray, green, highlight, note, red, yellow } = snooplogg.styles; - - console.log(`Account: ${highlight(account.name)}`); - console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}`); - console.log(`Date Range: ${highlight(formatDate(from))} and ${highlight(formatDate(to))}`); - - const renderBar = (percent, width) => { - const used = Math.ceil(width * Math.min(percent, 100) / 100); - const color = percent > 85 ? red : percent > 65 ? yellow : green; - return `${color('\u25A0'.repeat(used))}${gray('⠂'.repeat(width - used))} ${renderPercent(percent)}`; - }; - - const renderPercent = percent => { - let label = `${percent}%`.padStart(saasPercentPadding + 1); - return (percent > 85 ? red(label) : percent > 65 ? yellow(label) : label); - }; - - // API Management Platform Usage - if (bundle) { - console.log(`\n${bold(bundle.name)} - ${highlight(bundle.edition)}`); - console.log( - ` ${highlight(`${format(bundle.value)} / ${format(bundle.quota)}`)} ${bundle.units}` - + ` ${renderBar(bundle.percent, 40)}` - ); - - const table = createTable(); - for (const [ name, metric ] of Object.entries(bundle.metrics)) { - table.push([ - ` ${bold(metric.name || name)}`, - '', - { content: `${highlight(format(metric.value))} ${bundle.units}`, hAlign: 'right' } - ]); - - const ratio = bundle.ratios[name]; - - // render the envs - for (let i = 0, len = metric.envs.length; i < len; i++) { - const env = metric.envs[i]; - table.push([ - ` ${i + 1 === len ? '└─' : '├─'} ${env.name} ${env.production ? gray('Production') : ''}`, - `${highlight(format(env.value).padStart(bundleValuePadding))} Transactions${env.tokens && ratio !== 1 ? highlight(` x ${(ratio / 100).toFixed(1)}`) : ''}`, - env.tokens ? { content: `${highlight(format(env.tokens))} ${bundle.units}`, hAlign: 'right' } : '' - ]); - } - } - if (table.length) { - console.log(); - console.log(table.toString()); - } - } - - // Project usage - const table = createTable(); - for (const [ label, data ] of Object.entries(usage)) { - const metrics = Object.values(data); - if (!metrics.length) { - continue; - } - - table.push([ `\n${bold(label)}` ]); - - // print the usage - for (const { envs, formatted, name, percent, unit, unlimited } of metrics) { - table.push([ - ` ${bold(name)}`, - `${highlight(formatted.padStart(saasValuePadding))} ${unit}`, - unlimited || typeof percent !== 'number' ? '' : `${renderBar(percent, 20)}` - ]); - - // render the envs - for (let i = 0, len = envs.length; i < len; i++) { - const { formatted, name, production } = envs[i]; - if (name !== 'default') { - table.push([ - ` ${i + 1 === len ? '└─' : '├─'} ${name} ${production ? gray('Production') : ''}`, - `${highlight(formatted.padStart(saasValuePadding))} ${unit}`, - '' - ]); - } - } - } - } - if (table.length) { - console.log(table.toString()); - } else if (!bundle) { - console.log('\nNo usage data'); - } - } -}; diff --git a/packages/axway-cli-oum/src/org/usage.ts b/packages/axway-cli-oum/src/org/usage.ts new file mode 100644 index 00000000..79c1a2e8 --- /dev/null +++ b/packages/axway-cli-oum/src/org/usage.ts @@ -0,0 +1,284 @@ +/* eslint-disable no-loop-func */ + +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { UsageBundleMetric } from '@axway/amplify-sdk'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + +interface BundleEnvironment { + guid: string, + name: string, + production: boolean, + quota: number, + tokens: number, + value: number +} + +interface BundleMetric { + envs: BundleEnvironment[], + name: string, + tokens: number, + unit: string, + value: number +} + +interface BundleMetrics { + [name: string]: BundleMetric +} + +interface ProductMetric { + [name: string]: SubproductMetric +} + +interface ProductEnvironment { + name: string +} + +interface SubproductMetric { + envs: ProductEnvironment[], + formatted: string, + unlimited: boolean +} + +interface GovernanceMetrics { + [name: string]: ProductMetric +} + +interface ProductMeta { + name: string, + governance: GovernanceMetrics +} + +interface UsageMetrics { + [product: string]: ProductMeta +} + +export default { + args: [ + { + name: 'org', + desc: 'The organization name, id, or guid; defaults to the current org' + } + ], + desc: 'Display organization usage report', + help: { + header(this: CLICommand) { + return `${this.desc}.`; + }, + footer({ style }: CLIHelpOptions): string { + return `${style.heading('Example:')} + + You must be authenticated into an Amplify Platform account to view or manage + organizations. Run ${style.highlight('"axway auth login"')} to authenticate. + + Display organization usage for the past 14 days: + ${style.highlight('axway org usage ')} + + Display organization usage for a specific date range: + ${style.highlight('axway org usage --from 2021-04-01 --to 2021-04-30')} + + Display organization usage for the current month: + ${style.highlight('axway org usage --month')}`; + } + }, + options: { + '--account [name]': 'The platform account to use', + '--from [yyyy-mm-dd]': { + desc: 'The start date', + redact: false + }, + '--json': { + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, + desc: 'Outputs the usage as JSON' + }, + '--month [mm|yyyy-mm]': { + desc: 'A month date range; overrides --to and --from', + redact: false + }, + '--to [yyyy-mm-dd]': { + desc: 'The end date', + redact: false + } + }, + async action({ argv, console }: AxwayCLIState): Promise { + // const { formatDate } = await import('../lib/util.js'); + // const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + // let { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + // const { bundle, from, to, usage } = await sdk.org.usage(account, org, { + // from: argv.from as string, + // month: argv.month as string | boolean, + // to: argv.to as string + // }); + // const orgEnvs = await sdk.org.environments(account); + // const maxEntitlement = 9999999999999; + // const { format } = new Intl.NumberFormat(); + // let bundleValuePadding = 0; + // let saasPercentPadding = 0; + // let saasValuePadding = 0; + // let bundleMetricsScrubbed: BundleMetrics | undefined; + // let usageMetricsScrubbed: UsageMetrics = {}; + + // // pre-determine the bundle metric environments + // if (bundle) { + // bundleMetricsScrubbed = {}; + // const metricEntries: [ string, UsageBundleMetric ][] = Object.entries(bundle.metrics as any); + // for (const [ name, metric ] of metricEntries) { + // bundleMetricsScrubbed[name] = { + // ...metric, + // envs: Object.entries(metric.envs).map(([ guid, stats ]) => { + // bundleValuePadding = Math.max(bundleValuePadding, String(format(stats.value)).length); + // return { + // ...stats, + // guid, + // name: orgEnvs.find(e => e.guid === guid)?.name || guid + // }; + // }) + // }; + // } + // } + + // // pre-determine the saas metric environments + // for (const [ product, usageMeta ] of Object.entries(usage)) { + // const governance: GovernanceMetrics = {}; + // for (const [ govName, govMetrics ] of Object.entries(usageMeta.governance)) { + // const metrics: ProductMetric = {}; + // for (const [ name, info ] of Object.entries(govMetrics)) { + // const formatted = `${format(info.value)} of ${info.unlimited ? 'Unlimited' : format(info.quota)}`; + + // if (typeof info.percent === 'number') { + // saasPercentPadding = Math.max(saasPercentPadding, String(info.percent).length); + // } + // saasValuePadding = Math.max(saasValuePadding, formatted.length); + + // metrics[name] = { + // envs: Object.entries(info.envs || {}).map(([ name, stats ]) => { + // const formatted = format(stats.value); + // const percent = stats.quota && Math.floor(Math.min(stats.value / stats.quota * 100, 100)); + + // saasPercentPadding = Math.max(saasPercentPadding, String(stats.percent).length); + // saasValuePadding = Math.max(saasValuePadding, stats.formatted.length); + + // return { ...stats, formatted, name, percent }; + // }), + // formatted, + // unlimited: info.quota === maxEntitlement + // }; + // } + // governance[govName] = metrics; + // } + + // usageMetricsScrubbed[product] = { + // name: usageMeta.name, + // governance + // }; + // } + + // const results = { + // account: account.name, + // org, + // from, + // to, + // bundle: { + // ...bundle, + // metrics: bundleMetricsScrubbed + // }, + // usage: usageMetricsScrubbed + // }; + + // if (argv.json) { + // console.log(JSON.stringify(results, null, 2)); + // return; + // } + + // const { default: snooplogg } = await import('snooplogg'); + // const { bold, gray, green, highlight, note, red, yellow } = snooplogg.styles; + + // console.log(`Account: ${highlight(account.name)}`); + // console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}`); + // console.log(`Date Range: ${highlight(formatDate(from))} and ${highlight(formatDate(to))}`); + + // const renderBar = (percent: number, width: number): string => { + // const used = Math.ceil(width * Math.min(percent, 100) / 100); + // const color = percent > 85 ? red : percent > 65 ? yellow : green; + // return `${color('\u25A0'.repeat(used))}${gray('⠂'.repeat(width - used))} ${renderPercent(percent)}`; + // }; + + // const renderPercent = (percent: number): string => { + // let label = `${percent}%`.padStart(saasPercentPadding + 1); + // return (percent > 85 ? red(label) : percent > 65 ? yellow(label) : label); + // }; + + // API Management Platform Usage + // if (bundle) { + // console.log(`\n${bold(bundle.name)} - ${highlight(bundle.edition)}`); + // console.log( + // ` ${highlight(`${format(bundle.value)} / ${format(bundle.quota)}`)} ${bundle.units}` + // + ` ${renderBar(bundle.percent, 40)}` + // ); + + // const table = createTable(); + // for (const [ name, metric ] of Object.entries(bundleScrubbed.metrics)) { + // table.push([ + // ` ${bold(metric.name || name)}`, + // '', + // { content: `${highlight(format(metric.value))} ${bundleScrubbed.units}`, hAlign: 'right' } + // ]); + + // const ratio = bundleScrubbed.ratios[name]; + + // // render the envs + // for (let i = 0, len = metric.envs.length; i < len; i++) { + // const env = metric.envs[i]; + // table.push([ + // ` ${i + 1 === len ? '└─' : '├─'} ${env.name} ${env.production ? gray('Production') : ''}`, + // `${highlight(format(env.value).padStart(bundleValuePadding))} Transactions${env.tokens && ratio !== 1 ? highlight(` x ${(ratio / 100).toFixed(1)}`) : ''}`, + // env.tokens ? { content: `${highlight(format(env.tokens))} ${bundleScrubbed.units}`, hAlign: 'right' } : '' + // ]); + // } + // } + // if (table.length) { + // console.log(); + // console.log(table.toString()); + // } + // } + + // Project usage + // const table = createTable(); + // for (const [ label, meta ] of Object.entries(usageScrubbed)) { + // const metrics = Object.values(meta); + // if (!metrics.length) { + // continue; + // } + + // table.push([ `\n${bold(label)}` ]); + + // // print the usage + // for (const { envs, formatted, name, percent, unit, unlimited } of metrics) { + // table.push([ + // ` ${bold(name)}`, + // `${highlight(formatted.padStart(saasValuePadding))} ${unit}`, + // unlimited || typeof percent !== 'number' ? '' : `${renderBar(percent, 20)}` + // ]); + + // // render the envs + // for (let i = 0, len = envs.length; i < len; i++) { + // const { formatted, name, production } = envs[i]; + // if (name !== 'default') { + // table.push([ + // ` ${i + 1 === len ? '└─' : '├─'} ${name} ${production ? gray('Production') : ''}`, + // `${highlight(formatted.padStart(saasValuePadding))} ${unit}`, + // '' + // ]); + // } + // } + // } + // } + // if (table.length) { + // console.log(table.toString()); + // } else if (!bundleScrubbed) { + // console.log('\nNo usage data'); + // } + } +}; diff --git a/packages/axway-cli-oum/src/org/user.js b/packages/axway-cli-oum/src/org/user.ts similarity index 87% rename from packages/axway-cli-oum/src/org/user.js rename to packages/axway-cli-oum/src/org/user.ts index 7aab9f2e..606e00a9 100644 --- a/packages/axway-cli-oum/src/org/user.js +++ b/packages/axway-cli-oum/src/org/user.ts @@ -1,12 +1,14 @@ +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { aliases: '!users', commands: `${__dirname}/user`, desc: 'Manage organization users', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} You may specify an organization by name, id, or guid. diff --git a/packages/axway-cli-oum/src/org/user/add.js b/packages/axway-cli-oum/src/org/user/add.ts similarity index 71% rename from packages/axway-cli-oum/src/org/user/add.js rename to packages/axway-cli-oum/src/org/user/add.ts index a72cdb6c..8afba120 100644 --- a/packages/axway-cli-oum/src/org/user/add.js +++ b/packages/axway-cli-oum/src/org/user/add.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { args: [ { @@ -13,10 +19,10 @@ export default { ], desc: 'Adds or invites a user to an organization', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} You may specify an organization by name, id, or guid. @@ -36,7 +42,7 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--role [role]': { @@ -46,13 +52,13 @@ export default { required: true } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { default: snooplogg } = require('snooplogg'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + let { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error('You do not have administrative access to add users to the organization'); } @@ -61,7 +67,7 @@ export default { console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}\n`); } - const { user } = await sdk.org.user.add(account, org, argv.email, argv.role); + const { user } = await sdk.org.userAdd(account, org, argv.email as string, argv.role as string[]); const results = { account: account.name, org, @@ -71,7 +77,7 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const name = `${results.user.firstname} ${results.user.lastname}`.trim(); + const name = `${results.user?.firstname} ${results.user?.lastname}`.trim(); console.log(`Successfully added ${highlight(name)} to ${highlight(org.name)}`); } diff --git a/packages/axway-cli-oum/src/org/user/list.js b/packages/axway-cli-oum/src/org/user/list.ts similarity index 63% rename from packages/axway-cli-oum/src/org/user/list.js rename to packages/axway-cli-oum/src/org/user/list.ts index 971f9d52..94b42e28 100644 --- a/packages/axway-cli-oum/src/org/user/list.js +++ b/packages/axway-cli-oum/src/org/user/list.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'ls' ], args: [ @@ -10,14 +15,14 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the list of users as JSON' } }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { users } = await sdk.org.user.list(account, org); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + let { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { users } = await sdk.org.userList(account, org); if (argv.json) { console.log(JSON.stringify({ @@ -28,7 +33,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); @@ -39,15 +44,14 @@ export default { return; } - const table = createTable([ 'Name', 'Type', 'Email', 'GUID', 'Teams', 'Roles' ]); + const table = createTable([ 'Name', 'Type', 'Email', 'GUID', 'Roles' ]); - for (const { client_id, email, guid, name, roles, teams } of users) { + for (const { client_id, email, guid, name, roles } of users) { table.push([ name, client_id ? 'Service' : 'User', email, guid, - teams, roles.length ? roles.join(', ') : note('n/a') ]); } diff --git a/packages/axway-cli-oum/src/org/user/remove.js b/packages/axway-cli-oum/src/org/user/remove.ts similarity index 67% rename from packages/axway-cli-oum/src/org/user/remove.js rename to packages/axway-cli-oum/src/org/user/remove.ts index 721da43d..f833d65a 100644 --- a/packages/axway-cli-oum/src/org/user/remove.js +++ b/packages/axway-cli-oum/src/org/user/remove.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'rm' ], args: [ @@ -16,14 +21,14 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { default: snooplogg } = require('snooplogg'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + let { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; if (!argv.json) { @@ -31,7 +36,7 @@ export default { console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}\n`); } - const { user } = await sdk.org.user.remove(account, org, argv.user); + const { user } = await sdk.org.userRemove(account, org, argv.user as string); const results = { account: account.name, org, diff --git a/packages/axway-cli-oum/src/org/user/roles.js b/packages/axway-cli-oum/src/org/user/roles.ts similarity index 73% rename from packages/axway-cli-oum/src/org/user/roles.js rename to packages/axway-cli-oum/src/org/user/roles.ts index beb34298..9de9c038 100644 --- a/packages/axway-cli-oum/src/org/user/roles.js +++ b/packages/axway-cli-oum/src/org/user/roles.ts @@ -1,16 +1,21 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { desc: 'View available organization user roles', options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs roles as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid; roles vary by org' }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + let { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); const roles = (await sdk.role.list(account, { org })); if (argv.json) { @@ -22,7 +27,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; const platformRoles = createTable([ ' Role', 'Description' ]); const serviceRoles = createTable([ ' Role', 'Description', 'Product' ]); diff --git a/packages/axway-cli-oum/src/org/user/update.js b/packages/axway-cli-oum/src/org/user/update.ts similarity index 59% rename from packages/axway-cli-oum/src/org/user/update.js rename to packages/axway-cli-oum/src/org/user/update.ts index d3328810..46743dbc 100644 --- a/packages/axway-cli-oum/src/org/user/update.js +++ b/packages/axway-cli-oum/src/org/user/update.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { args: [ { @@ -15,7 +20,7 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--role [role]': { @@ -24,13 +29,13 @@ export default { redact: false } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { default: snooplogg } = require('snooplogg'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + let { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error('You do not have administrative access to update an organization\'s user roles'); } @@ -39,7 +44,7 @@ export default { console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}\n`); } - const { roles, user } = await sdk.org.user.update(account, org, argv.user, argv.role); + const { roles, user } = await sdk.org.userUpdate(account, org, argv.user as string, argv.role as string[]); const results = { account: account.name, @@ -50,8 +55,8 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const name = `${user.firstname} ${user.lastname}`.trim(); - console.log(`Successfully updated role${roles === 1 ? '' : 's'} for ${highlight(name)}`); + const name = `${user?.firstname} ${user?.lastname}`.trim(); + console.log(`Successfully updated role${roles.length === 1 ? '' : 's'} for ${highlight(name)}`); } await cli.emitAction('axway:oum:org:user:update', results); diff --git a/packages/axway-cli-oum/src/org/view.js b/packages/axway-cli-oum/src/org/view.ts similarity index 77% rename from packages/axway-cli-oum/src/org/view.js rename to packages/axway-cli-oum/src/org/view.ts index ae6cdc19..5cb059e0 100644 --- a/packages/axway-cli-oum/src/org/view.js +++ b/packages/axway-cli-oum/src/org/view.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ '!info' ], args: [ @@ -10,13 +15,13 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs organization info as JSON' } }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); if (argv.json) { console.log(JSON.stringify({ @@ -26,16 +31,16 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { green, highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}\n`); console.log('ORGANIZATION'); console.log(` Name: ${highlight(org.name)}`); - console.log(` Org ID: ${highlight(org.id)}`); + console.log(` Org ID: ${highlight(org.org_id)}`); console.log(` Org GUID: ${highlight(org.guid)}`); - console.log(` Date Created: ${highlight(new Date(org.created).toLocaleString())}`); + console.log(` Date Created: ${highlight(org.created ? new Date(org.created).toLocaleString() : 'n/a')}`); console.log(` Active: ${highlight(org.active ? 'Yes' : 'No')}`); console.log(` Region: ${highlight(org.region === 'US' ? 'United States' : org.region)}`); console.log(` Users: ${highlight(`${org.userCount} user${org.userCount !== 1 ? 's' : ''}${org.seats ? ` / ${org.seats} seat${org.seats !== 1 ? 's' : ''}` : ''}`)}`); diff --git a/packages/axway-cli-oum/src/team/create.js b/packages/axway-cli-oum/src/team/create.ts similarity index 67% rename from packages/axway-cli-oum/src/team/create.js rename to packages/axway-cli-oum/src/team/create.ts index 738fdc4a..63e3ef6c 100644 --- a/packages/axway-cli-oum/src/team/create.js +++ b/packages/axway-cli-oum/src/team/create.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ '!add', '!new' ], args: [ @@ -18,7 +23,7 @@ export default { '--default': 'Set the team as the default team', '--desc [value]': 'The description of the team', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--tag [tag]': { @@ -27,18 +32,18 @@ export default { multiple: true } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to add a new team to the "${org.name}" organization`); } - const { team } = await sdk.team.create(account, org, argv.name, { - desc: argv.desc, - default: argv.default, - tags: argv.tag + const { team } = await sdk.team.create(account, org, argv.name as string, { + desc: argv.desc as string, + default: !!argv.default, + tags: argv.tag as string[] }); const results = { account: account.name, @@ -49,7 +54,7 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}\n`); diff --git a/packages/axway-cli-oum/src/team/index.js b/packages/axway-cli-oum/src/team/index.ts similarity index 88% rename from packages/axway-cli-oum/src/team/index.js rename to packages/axway-cli-oum/src/team/index.ts index 7c7750c0..482be319 100644 --- a/packages/axway-cli-oum/src/team/index.js +++ b/packages/axway-cli-oum/src/team/index.ts @@ -1,3 +1,9 @@ +import path from 'path'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + export default { commands: [ `${__dirname}/create.js`, @@ -9,10 +15,10 @@ export default { ], desc: 'Manage Amplify organization teams', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('General Team Examples:')} You must be authenticated into an Amplify Platform account to view or manage diff --git a/packages/axway-cli-oum/src/team/list.js b/packages/axway-cli-oum/src/team/list.ts similarity index 72% rename from packages/axway-cli-oum/src/team/list.js rename to packages/axway-cli-oum/src/team/list.ts index dd49bbc2..7b589fe0 100644 --- a/packages/axway-cli-oum/src/team/list.js +++ b/packages/axway-cli-oum/src/team/list.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'ls' ], args: [ @@ -10,13 +15,13 @@ export default { options: { '--account [name]': 'The account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the list of teams as JSON' } }, - async action({ argv, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); const { teams } = await sdk.team.list(account, org); if (argv.json) { @@ -28,7 +33,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { green, highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); @@ -39,7 +44,7 @@ export default { return; } - const { createTable } = require('@axway/amplify-cli-utils'); + const { createTable } = await import('@axway/amplify-cli-utils'); const table = createTable([ 'Name', 'Description', 'GUID', 'User', 'Apps', 'Date Created' ]); const check = process.platform === 'win32' ? '√' : '✔'; diff --git a/packages/axway-cli-oum/src/team/remove.js b/packages/axway-cli-oum/src/team/remove.ts similarity index 62% rename from packages/axway-cli-oum/src/team/remove.js rename to packages/axway-cli-oum/src/team/remove.ts index 02112eca..2aaaf371 100644 --- a/packages/axway-cli-oum/src/team/remove.js +++ b/packages/axway-cli-oum/src/team/remove.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'rm' ], args: [ @@ -16,19 +21,19 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to remove a team from the "${org.name}" organization`); } - const { team } = await sdk.team.remove(account, org, argv.team); + const { team } = await sdk.team.remove(account, org, argv.team as string); const results = { account: account.name, org, @@ -38,7 +43,7 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}\n`); diff --git a/packages/axway-cli-oum/src/team/update.js b/packages/axway-cli-oum/src/team/update.ts similarity index 66% rename from packages/axway-cli-oum/src/team/update.js rename to packages/axway-cli-oum/src/team/update.ts index 3c64ced4..bccfc434 100644 --- a/packages/axway-cli-oum/src/team/update.js +++ b/packages/axway-cli-oum/src/team/update.ts @@ -1,3 +1,18 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + +interface Labels { + default: string, + desc: string, + name: string, + tags: string +} + +type ChangeValue = boolean | string | undefined; + export default { aliases: [ '!up' ], args: [ @@ -14,10 +29,10 @@ export default { ], desc: 'Update team information', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Example:')} You must be authenticated into an Amplify Platform account to view or manage @@ -41,7 +56,7 @@ export default { '--default': 'Set the team as the default team', '--desc [value]': 'The description of the team', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--name [value]': 'The team name', @@ -51,19 +66,19 @@ export default { multiple: true } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to update a team in the "${org.name}" organization`); } - const { changes, team } = await sdk.team.update(account, org, argv.team, { - desc: argv.desc, - default: argv.default, - name: argv.name, - tags: argv.tag + const { changes, team } = await sdk.team.update(account, org, argv.team as string, { + desc: argv.desc as string, + default: !!argv.default, + name: argv.name as string, + tags: argv.tag as string[] }); const results = { account: account.name, @@ -75,15 +90,15 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; - const labels = { + const labels: Labels = { default: 'is default', desc: 'description', name: 'name', tags: 'tags' }; - const format = it => { + const format = (it: ChangeValue | ChangeValue[]): string => { return Array.isArray(it) ? `[${it.map(s => `"${s === undefined ? '' : s}"`).join(', ')}]` : `"${it === undefined ? '' : it}"`; }; @@ -92,7 +107,7 @@ export default { if (Object.keys(changes).length) { for (const [ key, { v, p } ] of Object.entries(changes)) { - console.log(`Updated ${highlight(labels[key])} from ${highlight(format(p))} to ${highlight(format(v))}`); + console.log(`Updated ${highlight(labels[key as keyof Labels])} from ${highlight(format(p))} to ${highlight(format(v))}`); } } else { console.log('No values were changed'); diff --git a/packages/axway-cli-oum/src/team/user.js b/packages/axway-cli-oum/src/team/user.ts similarity index 86% rename from packages/axway-cli-oum/src/team/user.js rename to packages/axway-cli-oum/src/team/user.ts index 6e57fef5..56ea392c 100644 --- a/packages/axway-cli-oum/src/team/user.js +++ b/packages/axway-cli-oum/src/team/user.ts @@ -1,12 +1,14 @@ +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { aliases: '!users', commands: `${__dirname}/user`, desc: 'Manage team users', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} You may specify an organization by name, id, or guid as well as the team by diff --git a/packages/axway-cli-oum/src/team/user/add.js b/packages/axway-cli-oum/src/team/user/add.ts similarity index 74% rename from packages/axway-cli-oum/src/team/user/add.js rename to packages/axway-cli-oum/src/team/user/add.ts index 33b2bae3..9717ebb0 100644 --- a/packages/axway-cli-oum/src/team/user/add.js +++ b/packages/axway-cli-oum/src/team/user/add.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { args: [ { @@ -18,10 +24,10 @@ export default { ], desc: 'Add a user to a team', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} You may specify an organization by name, id, or guid. @@ -40,7 +46,7 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--role ': { @@ -49,15 +55,15 @@ export default { redact: false } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to add a user to a team in the "${org.name}" organization`); } - const { team, user } = await sdk.team.user.add(account, org, argv.team, argv.user, argv.role); + const { team, user } = await sdk.team.userAdd(account, org, argv.team as string, argv.user as string, argv.role as string[]); const results = { account: account.name, @@ -69,7 +75,7 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); diff --git a/packages/axway-cli-oum/src/team/user/list.js b/packages/axway-cli-oum/src/team/user/list.ts similarity index 64% rename from packages/axway-cli-oum/src/team/user/list.js rename to packages/axway-cli-oum/src/team/user/list.ts index 7a5c5ba1..36db88e7 100644 --- a/packages/axway-cli-oum/src/team/user/list.js +++ b/packages/axway-cli-oum/src/team/user/list.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'ls' ], args: [ @@ -16,20 +21,20 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the list of users as JSON' } }, - async action({ argv, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { team } = await sdk.team.find(account, org, argv.team); + async action({ argv, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { team } = await sdk.team.find(account, org, argv.team as string); if (!team) { throw new Error(`Unable to find team "${argv.team}"`); } - const { users } = await sdk.team.user.list(account, org, team.guid); + const { users } = await sdk.team.userList(account, org, team.guid); if (argv.json) { console.log(JSON.stringify({ @@ -41,7 +46,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); @@ -53,16 +58,15 @@ export default { return; } - const { createTable } = require('@axway/amplify-cli-utils'); - const table = createTable([ 'Name', 'Type', 'Email', 'GUID', 'Teams', 'Roles' ]); + const { createTable } = await import('@axway/amplify-cli-utils'); + const table = createTable([ 'Name', 'Type', 'Email', 'GUID', 'Roles' ]); - for (const { email, guid, name, roles, teams, type } of users) { + for (const { email, guid, name, roles, type } of users) { table.push([ name, type === 'client' ? 'Service' : type === 'user' ? 'User' : type, email, guid, - teams, roles.length ? roles.join(', ') : note('n/a') ]); } diff --git a/packages/axway-cli-oum/src/team/user/remove.js b/packages/axway-cli-oum/src/team/user/remove.ts similarity index 70% rename from packages/axway-cli-oum/src/team/user/remove.js rename to packages/axway-cli-oum/src/team/user/remove.ts index b96e66d1..47bffdde 100644 --- a/packages/axway-cli-oum/src/team/user/remove.js +++ b/packages/axway-cli-oum/src/team/user/remove.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'rm' ], args: [ @@ -21,19 +26,19 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to remove a user from a team in the "${org.name}" organization`); } - const { team, user } = await sdk.team.user.remove(account, org, argv.team, argv.user); + const { team, user } = await sdk.team.userRemove(account, org, argv.team as string, argv.user as string); const results = { account: account.name, @@ -45,7 +50,7 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); diff --git a/packages/axway-cli-oum/src/team/user/roles.js b/packages/axway-cli-oum/src/team/user/roles.ts similarity index 67% rename from packages/axway-cli-oum/src/team/user/roles.js rename to packages/axway-cli-oum/src/team/user/roles.ts index 6bb67778..0e9342e9 100644 --- a/packages/axway-cli-oum/src/team/user/roles.js +++ b/packages/axway-cli-oum/src/team/user/roles.ts @@ -1,16 +1,21 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { desc: 'View available team user roles', options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs roles as JSON' }, '--org [name|id|guid]': 'The organization name, id, or guid; roles vary by org' }, - async action({ argv, console }) { - const { createTable, initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable, initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); const roles = (await sdk.role.list(account, { default: true, org, team: true })); if (argv.json) { @@ -22,7 +27,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; const table = createTable([ ' Role', 'Description' ]); diff --git a/packages/axway-cli-oum/src/team/user/update.js b/packages/axway-cli-oum/src/team/user/update.ts similarity index 61% rename from packages/axway-cli-oum/src/team/user/update.js rename to packages/axway-cli-oum/src/team/user/update.ts index 5cff4800..402bcaec 100644 --- a/packages/axway-cli-oum/src/team/user/update.js +++ b/packages/axway-cli-oum/src/team/user/update.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { args: [ { @@ -20,7 +25,7 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--role [role]': { @@ -29,18 +34,18 @@ export default { redact: false } }, - async action({ argv, cli, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); - if (!org.userRoles.includes('administrator')) { + if (!org.userRoles?.includes('administrator')) { throw new Error(`You do not have administrative access to update a user's team roles in the "${org.name}" organization`); } - const { team, user } = await sdk.team.user.update(account, org, argv.team, argv.user, argv.role); + const { team, user } = await sdk.team.userUpdate(account, org, argv.team as string, argv.user as string, argv.role as string[]); const results = { - account: account.name, + account, org, team, user @@ -49,12 +54,12 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); console.log(`Organization: ${highlight(org.name)} ${note(`(${org.guid})`)}\n`); - console.log(`Successfully updated user role${results.roles === 1 ? '' : 's'}`); + console.log(`Successfully updated user role${user.roles.length === 1 ? '' : 's'}`); } await cli.emitAction('axway:oum:team:user:update', results); diff --git a/packages/axway-cli-oum/src/team/view.js b/packages/axway-cli-oum/src/team/view.ts similarity index 63% rename from packages/axway-cli-oum/src/team/view.js rename to packages/axway-cli-oum/src/team/view.ts index ac8d185c..cf71ae06 100644 --- a/packages/axway-cli-oum/src/team/view.js +++ b/packages/axway-cli-oum/src/team/view.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ '!info' ], args: [ @@ -16,14 +21,14 @@ export default { options: { '--account [name]': 'The platform account to use', '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the team info as JSON' } }, - async action({ argv, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - let { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { team } = await sdk.team.find(account, org, argv.team); + async action({ argv, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { team } = await sdk.team.find(account, org, argv.team as string); if (argv.json) { console.log(JSON.stringify({ @@ -34,7 +39,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight, note } = snooplogg.styles; console.log(`Account: ${highlight(account.name)}`); @@ -43,7 +48,7 @@ export default { console.log(`Name: ${highlight(team.name)}`); console.log(`Description: ${team.desc ? highlight(team.desc) : note('n/a')}`); console.log(`Team GUID: ${highlight(team.guid)}`); - console.log(`Date Created: ${highlight(new Date(team.created).toLocaleString())}`); + console.log(`Date Created: ${team.created ? highlight(new Date(team.created).toLocaleString()) : note('n/a')}`); console.log(`Is Default: ${highlight(team.default ? 'Yes' : 'No')}`); console.log(`Users: ${highlight(team.users.length)}`); console.log(`Apps: ${highlight(team.apps.length)}`); diff --git a/packages/axway-cli-oum/src/user/activity.js b/packages/axway-cli-oum/src/user/activity.ts similarity index 64% rename from packages/axway-cli-oum/src/user/activity.js rename to packages/axway-cli-oum/src/user/activity.ts index 04ba7998..6057c4a0 100644 --- a/packages/axway-cli-oum/src/user/activity.js +++ b/packages/axway-cli-oum/src/user/activity.ts @@ -1,10 +1,16 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { desc: 'Display your activity', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Example:')} You must be authenticated into an Amplify Platform account to view or manage @@ -27,7 +33,7 @@ export default { redact: false }, '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the user activity as JSON' }, '--month [mm|yyyy-mm]': { @@ -39,19 +45,16 @@ export default { redact: false } }, - async action({ argv, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { renderActivity } = require('../lib/activity'); - const { account, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { renderActivity } = await import('../lib/activity.js'); + const { account, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); await renderActivity({ account, console, - json: argv.json, - results: { - account: account.name, - ...(await sdk.user.activity(account, argv)) - } + json: !!argv.json, + ...(await sdk.user.activity(account, argv)) }); } }; diff --git a/packages/axway-cli-oum/src/user/credentials.js b/packages/axway-cli-oum/src/user/credentials.js deleted file mode 100644 index 3a4eacd2..00000000 --- a/packages/axway-cli-oum/src/user/credentials.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - desc: 'Opens a web browser to the change your password page', - async action({ console }) { - const { initSDK, isHeadless } = require('@axway/amplify-cli-utils'); - const { default: snooplogg } = require('snooplogg'); - const { highlight } = snooplogg.styles; - const { sdk } = initSDK(); - const open = require('open'); - - if (isHeadless()) { - throw new Error('Changing your login credentials requires a web browser and is unsupported in headless environments'); - } - - const url = `${sdk.platformUrl}#/user/credentials`; - console.log(`Opening web browser to ${highlight(url)}`); - await open(url); - } -}; diff --git a/packages/axway-cli-oum/src/user/credentials.ts b/packages/axway-cli-oum/src/user/credentials.ts new file mode 100644 index 00000000..74e4ca27 --- /dev/null +++ b/packages/axway-cli-oum/src/user/credentials.ts @@ -0,0 +1,20 @@ +import { AxwayCLIState } from '@axway/amplify-cli-utils'; + +export default { + desc: 'Opens a web browser to the change your password page', + async action({ console }: AxwayCLIState): Promise { + const { initSDK, isHeadless } = await import('@axway/amplify-cli-utils'); + const { default: snooplogg } = await import('snooplogg'); + const { highlight } = snooplogg.styles; + const { sdk } = await initSDK(); + const { default: open } = await import('open'); + + if (isHeadless()) { + throw new Error('Changing your login credentials requires a web browser and is unsupported in headless environments'); + } + + const url = `${sdk.platformUrl}#/user/credentials`; + console.log(`Opening web browser to ${highlight(url)}`); + await open(url); + } +}; diff --git a/packages/axway-cli-oum/src/user/index.js b/packages/axway-cli-oum/src/user/index.ts similarity index 76% rename from packages/axway-cli-oum/src/user/index.js rename to packages/axway-cli-oum/src/user/index.ts index bf3a0c82..78a55b58 100644 --- a/packages/axway-cli-oum/src/user/index.js +++ b/packages/axway-cli-oum/src/user/index.ts @@ -1,3 +1,9 @@ +import path from 'path'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + export default { commands: [ `${__dirname}/activity.js`, @@ -7,10 +13,10 @@ export default { ], desc: 'Manage your user settings', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} You must be authenticated into an Amplify Platform account to view or update @@ -21,7 +27,6 @@ export default { Update your first name, last name, or phone number: ${style.highlight('axway user update --firstname --lastname ')} - ${style.highlight('axway user update --phone ')} View your recent activity report: ${style.highlight('axway user activity')} diff --git a/packages/axway-cli-oum/src/user/update.js b/packages/axway-cli-oum/src/user/update.ts similarity index 64% rename from packages/axway-cli-oum/src/user/update.js rename to packages/axway-cli-oum/src/user/update.ts index a7899102..f6f686db 100644 --- a/packages/axway-cli-oum/src/user/update.js +++ b/packages/axway-cli-oum/src/user/update.ts @@ -1,18 +1,21 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; + export default { aliases: [ '!up' ], desc: 'Change your information', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} Update your first and last name: - ${style.highlight('axway user update --firstname --lastname ')} - - Update your phone number: - ${style.highlight('axway user update --phone ')}`; + ${style.highlight('axway user update --firstname --lastname ')}`; } }, options: { @@ -22,23 +25,21 @@ export default { desc: 'Your first name' }, '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the result as JSON' }, '--lastname [value]': { aliases: '--last-name', desc: 'Your last name' - }, - '--phone [value]': 'Your phone number' + } }, - async action({ argv, cli, console, help }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account, org, sdk } = await initPlatformAccount(argv.account, argv.org, argv.env); + async action({ argv, cli, console, help }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account, org, sdk } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); const { changes, user } = await sdk.user.update(account, { - firstname: argv.firstname, - lastname: argv.lastname, - phone: argv.phone + firstname: argv.firstname as string, + lastname: argv.lastname as string }); const results = { account: account.name, @@ -50,12 +51,13 @@ export default { if (argv.json) { console.log(JSON.stringify(results, null, 2)); } else { - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { highlight } = snooplogg.styles; - const labels = { + const labels: { + [key: string]: string + } = { firstname: 'first name', - lastname: 'last name', - phone: 'phone number' + lastname: 'last name' }; if (Object.keys(changes).length) { diff --git a/packages/axway-cli-oum/src/user/view.js b/packages/axway-cli-oum/src/user/view.js deleted file mode 100644 index 524c147b..00000000 --- a/packages/axway-cli-oum/src/user/view.js +++ /dev/null @@ -1,31 +0,0 @@ -export default { - aliases: [ '!info' ], - desc: 'Display your user information', - options: { - '--account [name]': 'The platform account to use', - '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, - desc: 'Outputs the info as JSON' - } - }, - async action({ argv, console }) { - const { initPlatformAccount } = require('@axway/amplify-cli-utils'); - const { account } = await initPlatformAccount(argv.account, argv.org, argv.env); - const { user } = account; - - if (argv.json) { - console.log(JSON.stringify(user, null, 2)); - return; - } - - const { default: snooplogg } = require('snooplogg'); - const { highlight } = snooplogg.styles; - - console.log(`First Name: ${highlight(user.firstname)}`); - console.log(`Last Name: ${highlight(user.lastname)}`); - console.log(`Email: ${highlight(user.email)}`); - console.log(`Phone Number: ${highlight(user.phone)}`); - console.log(`Date Joined: ${highlight(new Date(user.dateJoined).toLocaleDateString())}`); - console.log(`GUID: ${highlight(user.guid)}`); - } -}; diff --git a/packages/axway-cli-oum/src/user/view.ts b/packages/axway-cli-oum/src/user/view.ts new file mode 100644 index 00000000..78a663ab --- /dev/null +++ b/packages/axway-cli-oum/src/user/view.ts @@ -0,0 +1,35 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + +export default { + aliases: [ '!info' ], + desc: 'Display your user information', + options: { + '--account [name]': 'The platform account to use', + '--json': { + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, + desc: 'Outputs the info as JSON' + } + }, + async action({ argv, console }: AxwayCLIState): Promise { + const { initPlatformAccount } = await import('@axway/amplify-cli-utils'); + const { account } = await initPlatformAccount(argv.account as string, argv.org as string, argv.env as string); + const { user } = account; + + if (argv.json) { + console.log(JSON.stringify(user, null, 2)); + return; + } + + const { default: snooplogg } = await import('snooplogg'); + const { highlight } = snooplogg.styles; + + console.log(`First Name: ${highlight(user.firstname)}`); + console.log(`Last Name: ${highlight(user.lastname)}`); + console.log(`Email: ${highlight(user.email)}`); + console.log(`Date Joined: ${highlight(user.dateJoined ? new Date(user.dateJoined).toLocaleDateString() : 'n/a')}`); + console.log(`GUID: ${highlight(user.guid)}`); + } +}; diff --git a/packages/axway-cli-oum/tsconfig.json b/packages/axway-cli-oum/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/axway-cli-oum/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/axway-cli-pm/.eslintrc b/packages/axway-cli-pm/.eslintrc deleted file mode 100644 index f5d53a3f..00000000 --- a/packages/axway-cli-pm/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "no-confusing-arrow": "off", - "no-ex-assign": "off" - } -} diff --git a/packages/axway-cli-pm/.gitignore b/packages/axway-cli-pm/.gitignore deleted file mode 100644 index b3a1d215..00000000 --- a/packages/axway-cli-pm/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -._* -.DS_Store* -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log -yarn-error.log diff --git a/packages/axway-cli-pm/CHANGELOG.md b/packages/axway-cli-pm/CHANGELOG.md index f5f82b87..65a2d340 100644 --- a/packages/axway-cli-pm/CHANGELOG.md +++ b/packages/axway-cli-pm/CHANGELOG.md @@ -1,3 +1,8 @@ +# v5.0.0 + +- BREAKING CHANGE: Dropped support for Node.js 12 and older. +- chore: Updated dependencies. + # v4.0.11 (Jun 7, 2022) - chore: Updated dependencies. diff --git a/packages/axway-cli-pm/gulpfile.js b/packages/axway-cli-pm/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/axway-cli-pm/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/axway-cli-pm/package.json b/packages/axway-cli-pm/package.json index 03c9eb62..1d61729e 100644 --- a/packages/axway-cli-pm/package.json +++ b/packages/axway-cli-pm/package.json @@ -5,6 +5,7 @@ "access": "public" }, "description": "Package manager for Axway products", + "type": "module", "author": "Axway, Inc. ", "maintainers": [ "Chris Barber " @@ -15,41 +16,38 @@ "amplify" ], "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1" }, "dependencies": { "@axway/amplify-cli-utils": "^5.0.11", "@axway/amplify-utils": "^1.0.9", - "cli-kit": "^1.16.0", + "cli-kit": "^2.0.2", "cross-spawn": "^7.0.3", "fs-extra": "^10.1.0", - "libnpmsearch": "^4.0.1", + "libnpmsearch": "^5.0.3", "listr2": "^4.0.5", - "npm-package-arg": "^9.0.2", - "ora": "^5.4.1", - "pacote": "^12.0.3", + "npm-package-arg": "^9.1.0", + "ora": "^6.1.2", + "pacote": "^13.6.1", "promise-limit": "^2.7.0", "semver": "^7.3.7", - "snooplogg": "^3.0.2", - "source-map-support": "^0.5.21", + "snooplogg": "^5.0.0", "which": "^2.0.2" }, - "devDependencies": { - "@axway/gulp-tasks": "^4.1.4" - }, "homepage": "https://github.com/appcelerator/amplify-tooling#readme", "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/amplify-cli-pm", "engines": { - "node": ">=12.13.0" + "node": ">=14.15.0" }, "cli-kit": { "main": "./dist/index.js", "name": "pm" - }, - "gitHead": "9cc288d8ee067fb3444920aad11c53899455ad9c" + } } diff --git a/packages/axway-cli-pm/src/commands/install.js b/packages/axway-cli-pm/src/commands/install.ts similarity index 68% rename from packages/axway-cli-pm/src/commands/install.js rename to packages/axway-cli-pm/src/commands/install.ts index c4d791d8..d8e19a17 100644 --- a/packages/axway-cli-pm/src/commands/install.js +++ b/packages/axway-cli-pm/src/commands/install.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { InstalledPackageDataDetailed } from '../types.js'; + export default { aliases: [ 'i' ], args: [ @@ -12,26 +18,29 @@ export default { desc: 'Install a package', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Output installed package as JSON' } }, skipExtensionUpdateCheck: true, - async action({ argv, cli, console, exitCode }) { - const { default: snooplogg } = require('snooplogg'); - const { Extension } = require('cli-kit'); - const { install } = require('../pm'); - const { loadConfig } = require('@axway/amplify-cli-utils'); - const { runListr } = require('../utils'); + async action({ argv, cli, console, exitCode }: AxwayCLIState): Promise { + const { default: snooplogg } = await import('snooplogg'); + const { Extension } = await import('cli-kit'); + const { install } = await import('../pm.js'); + const { loadConfig } = await import('@axway/amplify-cli-utils'); + const { runListr } = await import('../utils.js'); const { alert, highlight } = snooplogg.styles; const tasks = []; - const results = { + const results: { + installed: InstalledPackageDataDetailed[], + failures: { error: string, package: string }[] + } = { installed: [], failures: [] }; - const packages = (Array.isArray(argv.packages) ? argv.packages : [ argv.packages ]).filter(Boolean); + const packages: string[] = (Array.isArray(argv.packages) ? argv.packages : [ argv.packages as string ]).filter(Boolean); if (!packages.length) { throw new TypeError('Expected one or more package names'); } @@ -41,9 +50,9 @@ export default { for (const pkg of packages) { tasks.push({ title: `Fetching metadata ${highlight(pkg)}`, - async task(ctx, task) { + async task(ctx: any, task: any) { try { - await new Promise((resolve, reject) => { + await new Promise((resolve, reject) => { install(pkg) .on('download', ({ name, version }) => { task.title = `Downloading ${highlight(`${name}@${version}`)}`; @@ -61,7 +70,7 @@ export default { }) .on('error', reject); }); - } catch (err) { + } catch (err: any) { results.failures.push({ error: err.toString(), package: pkg @@ -76,12 +85,12 @@ export default { } try { - await runListr({ console, json: argv.json, tasks }); - } catch (err) { + await runListr({ console, json: !!argv.json, tasks }); + } catch (err: any) { // errors are stored in the results } - const cfg = loadConfig(); + const cfg = await loadConfig(); cfg.delete('update.notified'); cfg.save(); diff --git a/packages/axway-cli-pm/src/commands/list.js b/packages/axway-cli-pm/src/commands/list.ts similarity index 69% rename from packages/axway-cli-pm/src/commands/list.js rename to packages/axway-cli-pm/src/commands/list.ts index af1f4b7e..335944f1 100644 --- a/packages/axway-cli-pm/src/commands/list.js +++ b/packages/axway-cli-pm/src/commands/list.ts @@ -1,17 +1,22 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'ls' ], desc: 'List all installed packages', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs packages as JSON' } }, - async action({ argv, console }) { - const semver = require('semver'); - const { default: snooplogg } = require('snooplogg'); - const { createTable } = require('@axway/amplify-cli-utils'); - const { list, packagesDir } = require('../pm'); + async action({ argv, console }: AxwayCLIState): Promise { + const { default: semver } = await import('semver'); + const { default: snooplogg } = await import('snooplogg'); + const { createTable } = await import('@axway/amplify-cli-utils'); + const { list, packagesDir } = await import('../pm.js'); const installed = await list(); @@ -29,7 +34,7 @@ export default { } const table = createTable([ 'Name', 'Versions' ]); - const unmanaged = {}; + const unmanaged: { [key: string]: number } = {}; for (const pkg of installed) { const { version } = pkg; diff --git a/packages/axway-cli-pm/src/commands/purge.js b/packages/axway-cli-pm/src/commands/purge.ts similarity index 64% rename from packages/axway-cli-pm/src/commands/purge.js rename to packages/axway-cli-pm/src/commands/purge.ts index 2de53f49..f946603b 100644 --- a/packages/axway-cli-pm/src/commands/purge.js +++ b/packages/axway-cli-pm/src/commands/purge.ts @@ -1,3 +1,9 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { PackageData, PurgablePackageMap } from '../types'; + export default { args: [ { @@ -9,7 +15,7 @@ export default { desc: 'Removes all non-active, managed packages', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs the purged packages as JSON' }, '-y, --yes': { @@ -18,16 +24,18 @@ export default { } }, skipExtensionUpdateCheck: true, - async action({ argv, cli, console, terminal }) { - const { createTable, loadConfig } = require('@axway/amplify-cli-utils'); - const { default: snooplogg } = require('snooplogg'); - const { listPurgable, uninstallPackage } = require('../pm'); - const { runListr } = require('../utils'); + async action({ argv, cli, console, terminal }: AxwayCLIState): Promise { + const { createTable, loadConfig } = await import('@axway/amplify-cli-utils'); + const { default: snooplogg } = await import('snooplogg'); + const { listPurgable, uninstallPackage } = await import('../pm.js'); + const { runListr } = await import('../utils.js'); const { bold, highlight } = snooplogg.styles; const purgeTable = createTable(); - const purgable = await listPurgable(argv.package); - const removedPackages = {}; + const purgable: PurgablePackageMap = await listPurgable(argv.package as string); + const removedPackages: { + [name: string]: PackageData[] + } = {}; const tasks = []; // step 1: determine packages to remove @@ -35,7 +43,7 @@ export default { for (const pkg of versions) { tasks.push({ title: `Purging ${highlight(`${name}@${pkg.version}`)}`, - task: async (ctx, task) => { + task: async (ctx: any, task: any) => { await uninstallPackage(pkg.path); task.title = `Purged ${highlight(`${name}@${pkg.version}`)}`; } @@ -63,10 +71,10 @@ export default { console.log(`The following packages can be purged:\n\n${purgeTable.toString()}\n`); if (terminal.stdout.isTTY && !argv.yes && !argv.json) { - await new Promise(resolve => { + await new Promise(resolve => { terminal.once('keypress', str => { terminal.stderr.cursorTo(0); - terminal.stderr.clearLine(); + terminal.stderr.clearLine(0); if (str === 'y' || str === 'Y') { return resolve(); } @@ -78,14 +86,14 @@ export default { // step 3: run the tasks try { - await runListr({ console, json: argv.json, tasks }); - } catch (err) { + await runListr({ console, json: !!argv.json, tasks }); + } catch (err: any) { // errors are stored in the results } - const cfg = loadConfig(); + const cfg = await loadConfig(); cfg.delete('update.notified'); - cfg.save(); + await cfg.save(); if (argv.json) { console.log(JSON.stringify(removedPackages, null, 2)); diff --git a/packages/axway-cli-pm/src/commands/search.js b/packages/axway-cli-pm/src/commands/search.ts similarity index 70% rename from packages/axway-cli-pm/src/commands/search.js rename to packages/axway-cli-pm/src/commands/search.ts index edc6184f..b3bb60fd 100644 --- a/packages/axway-cli-pm/src/commands/search.js +++ b/packages/axway-cli-pm/src/commands/search.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 's', '!se' ], args: [ @@ -10,15 +15,15 @@ export default { desc: 'Searches registry for packages', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs packages as JSON' }, '--limit [count]': { desc: 'The maximum number of packages to return (default: 50)', redact: false }, '--type [type]': { desc: 'Type of package to search', redact: false } }, - async action({ argv, console }) { - const { createTable } = require('@axway/amplify-cli-utils'); - const { search } = require('../pm'); + async action({ argv, console }: AxwayCLIState): Promise { + const { createTable } = await import('@axway/amplify-cli-utils'); + const { search } = await import('../pm.js'); const results = await search(argv); diff --git a/packages/axway-cli-pm/src/commands/uninstall.js b/packages/axway-cli-pm/src/commands/uninstall.ts similarity index 69% rename from packages/axway-cli-pm/src/commands/uninstall.js rename to packages/axway-cli-pm/src/commands/uninstall.ts index 019a6c7c..1f02f85a 100644 --- a/packages/axway-cli-pm/src/commands/uninstall.js +++ b/packages/axway-cli-pm/src/commands/uninstall.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ '!un', '!unlink', '!r', 'rm', '!remove' ], args: [ @@ -12,37 +17,40 @@ export default { desc: 'Removes the specified package', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs removed packages as JSON' } }, skipExtensionUpdateCheck: true, - async action({ argv, cli, console }) { - const fs = require('fs-extra'); - const npa = require('npm-package-arg'); - const semver = require('semver'); - const { default: snooplogg } = require('snooplogg'); - const { dirname } = require('path'); - const { runListr } = require('../utils'); - const { loadConfig } = require('@axway/amplify-cli-utils'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { default: fs } = await import('fs-extra'); + const { default: npa } = await import('npm-package-arg'); + const { default: semver } = await import('semver'); + const { default: snooplogg } = await import('snooplogg'); + const { dirname } = await import('path'); + const { runListr } = await import('../utils.js'); + const { loadConfig } = await import('@axway/amplify-cli-utils'); const { find, packagesDir, uninstallPackage - } = require('../pm'); + } = await import('../pm.js'); const { highlight, note } = snooplogg.styles; - const { fetchSpec, name, type } = npa(argv.package); - const installed = find(name); + const { fetchSpec, name, type } = npa(argv.package as string) as any; + const installed = await find(name); if (!installed) { - const err = new Error(`Package "${name}" is not installed`); + const err: any = new Error(`Package "${name}" is not installed`); err.code = 'ENOTFOUND'; throw err; } const installedVersions = Object.keys(installed.versions); - const replacement = {}; + const replacement: { + path?: string, + version?: string + } = {}; const versions = []; if (type === 'range') { @@ -72,7 +80,7 @@ export default { } if (!versions.length) { - const err = new Error(`"${name}${fetchSpec === 'latest' ? '' : `@${fetchSpec}`}" is not installed`); + const err: any = new Error(`"${name}${fetchSpec === 'latest' ? '' : `@${fetchSpec}`}" is not installed`); err.code = 'ENOTFOUND'; throw err; } @@ -87,16 +95,18 @@ export default { newVersion = ver; } } - replacement.path = installed.versions[newVersion].path; - replacement.version = newVersion; + if (newVersion) { + replacement.path = installed.versions[newVersion].path; + replacement.version = newVersion; + } } // unregister extension const tasks = [ { title: `Unregistering ${highlight(name)} extension`, - task: () => { - const cfg = loadConfig(); + task: async () => { + const cfg = await loadConfig(); if (replacement.path) { cfg.set(`extensions.${name}`, replacement.path); } else { @@ -127,17 +137,17 @@ export default { // run the tasks if (tasks.length) { try { - await runListr({ console, json: argv.json, tasks }); + await runListr({ console, json: !!argv.json, tasks }); if (!argv.json && replacement.path) { console.log(`\n${highlight(`${name}@${replacement.version}`)} is now the active version`); } - } catch (err) { + } catch (err: any) { // squelch } } - const cfg = loadConfig(); + const cfg = await loadConfig(); cfg.delete('update.notified'); cfg.save(); diff --git a/packages/axway-cli-pm/src/commands/update.js b/packages/axway-cli-pm/src/commands/update.js deleted file mode 100644 index b18aa0dc..00000000 --- a/packages/axway-cli-pm/src/commands/update.js +++ /dev/null @@ -1,181 +0,0 @@ -export default { - aliases: [ 'up' ], - args: [ - { - name: 'package', - desc: 'The package name to update', - redact: false - } - ], - desc: 'Download updates for installed packages', - options: { - '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, - desc: 'Outputs updated packages as JSON' - }, - '-y, --yes': { - aliases: [ '--no-prompt' ], - desc: 'Automatic yes to prompts and run non-interactively' - } - }, - skipExtensionUpdateCheck: true, - async action({ argv, cli, console, exitCode, terminal }) { - const { default: snooplogg } = require('snooplogg'); - const { runListr } = require('../utils'); - const { createTable, hlVer, loadConfig } = require('@axway/amplify-cli-utils'); - const { find, install, list, listPurgable, view } = require('../pm'); - const ora = require('ora'); - const promiseLimit = require('promise-limit'); - const semver = require('semver'); - - const { alert, bold, highlight } = snooplogg.styles; - const results = { - alreadyActive: [], - selected: [], - installed: [], - failures: [] - }; - let packages = []; - - // get installed packages - if (argv.package) { - const pkg = await find(argv.package); - if (!pkg) { - throw new Error(`Package "${argv.package}" is not installed`); - } - packages.push(pkg); - } else { - packages = await list(); - } - - if (!packages.length) { - if (argv.json) { - console.log(JSON.stringify(results, null, 2)); - } else { - console.log('There are no packages to update.'); - } - return; - } - - // step 1: check for updates - const plimit = promiseLimit(10); - const spinner = ora({ stream: terminal.stderr }).start('Checking packages for updates'); - await Promise.all(packages.map(pkg => { - return plimit(async () => { - pkg.current = Object.keys(pkg.versions).sort(semver.rcompare)[0]; - pkg.latest = (await view(pkg.name)).version; - }); - })); - spinner.stop(); - - const updateTable = createTable(); - for (let i = 0; i < packages.length; i++) { - const pkg = packages[i]; - if (semver.gt(pkg.latest, pkg.version)) { - updateTable.push([ ` ${bold(pkg.name)}`, pkg.version, '→', hlVer(pkg.latest, pkg.version) ]); - } else { - results.alreadyActive.push(`${pkg.name}@${pkg.version}`); - packages.splice(i--, 1); - } - } - if (!packages.length) { - console.log('All packages are up-to-date'); - return; - } - - // step 2: confirm updates - console.log(`The following packages have updates available:\n\n${updateTable.toString()}\n`); - - if (terminal.stdout.isTTY && !argv.yes && !argv.json) { - await new Promise(resolve => { - terminal.once('keypress', str => { - terminal.stderr.cursorTo(0); - terminal.stderr.clearLine(); - if (str === 'y' || str === 'Y') { - return resolve(); - } - process.exit(0); - }); - terminal.stderr.write('Do you want to update? (y/N) '); - }); - } - - // step 3: create the tasks - const tasks = packages.map(pkg => { - const versionData = pkg.versions[pkg.latest]; - if (versionData) { - // select it - return { - title: `${highlight(`${pkg.name}@${pkg.latest}`)} is installed, setting it as active`, - async task(ctx, task) { - results.selected.push(`${pkg.name}@${pkg.latest}`); - loadConfig().set(`extensions.${pkg.name}`, versionData.path).save(); - task.title = `${highlight(`${pkg.name}@${pkg.latest}`)} set as active version`; - } - }; - } - - return { - title: `Downloading and installing ${highlight(`${pkg.name}@${pkg.latest}`)}`, - async task(ctx, task) { - try { - await new Promise((resolve, reject) => { - install(`${pkg.name}@${pkg.latest}`) - .on('download', ({ name, version }) => { - task.title = `Downloading ${highlight(`${name}@${version}`)}`; - }) - .on('install', ({ name, version }) => { - task.title = `Installing ${highlight(`${name}@${version}`)}`; - }) - .on('register', ({ name, version }) => { - task.title = `Registering ${highlight(`${name}@${version}`)}`; - }) - .on('end', info => { - task.title = `${highlight(`${info.name}@${info.version}`)} installed and set as active version`; - results.installed.push(info); - resolve(); - }) - .on('error', reject); - }); - } catch (err) { - results.failures.push({ - error: err.toString(), - package: pkg - }); - task.title = alert(err.toString()); - err.message = undefined; // prevent the error from rendering twice - exitCode(1); - throw err; - } - } - }; - }); - - // step 4: run the tasks - try { - await runListr({ console, json: argv.json, tasks }); - } catch (err) { - // errors are stored in the results - } - - const cfg = loadConfig(); - cfg.delete('update.notified'); - cfg.save(); - - if (argv.json) { - console.log(JSON.stringify(results, null, 2)); - } else { - // step 5: show packages that can be purged - const purgable = await listPurgable(argv.package); - if (Object.keys(purgable).length) { - const purgeTable = createTable(); - for (const [ name, versions ] of Object.entries(purgable)) { - purgeTable.push([ ` ${bold(name)}`, versions.map(v => v.version).sort(semver.rcompare).join(', ') ]); - } - console.log(`\nThe following package versions can be purged:\n\n${purgeTable.toString()}\n\nTo purge these unused packages, run: ${highlight('axway pm purge')}`); - } - } - - await cli.emitAction('axway:pm:update', results); - } -}; diff --git a/packages/axway-cli-pm/src/commands/update.ts b/packages/axway-cli-pm/src/commands/update.ts new file mode 100644 index 00000000..620a2364 --- /dev/null +++ b/packages/axway-cli-pm/src/commands/update.ts @@ -0,0 +1,208 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { PackageData } from '../types.js'; + +interface ExtendedPackageData extends PackageData { + current: string; + latest: string; +} + +export default { + aliases: [ 'up' ], + args: [ + { + name: 'package', + desc: 'The package name to update', + redact: false + } + ], + desc: 'Download updates for installed packages', + options: { + '--json': { + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, + desc: 'Outputs updated packages as JSON' + }, + '-y, --yes': { + aliases: [ '--no-prompt' ], + desc: 'Automatic yes to prompts and run non-interactively' + } + }, + skipExtensionUpdateCheck: true, + async action({ argv, cli, console, exitCode, terminal }: AxwayCLIState): Promise { + const { default: snooplogg } = await import('snooplogg'); + const { runListr } = await import('../utils.js'); + const { createTable, hlVer, loadConfig } = await import('@axway/amplify-cli-utils'); + const { find, install, list, listPurgable, view } = await import('../pm.js'); + const { default: ora } = await import('ora'); + const { default: promiseLimit } = await import('promise-limit'); + const { default: semver } = await import('semver'); + + const { alert, bold, highlight } = snooplogg.styles; + const results: { + alreadyActive: string[], + selected: string[], + installed: string[], + failures: { error: string, package: string }[] + } = { + alreadyActive: [], + selected: [], + installed: [], + failures: [] + }; + let packageDatas: PackageData[] = []; + + // get installed packages + if (argv.package) { + const pkg: PackageData | undefined = await find(argv.package as string); + if (!pkg) { + throw new Error(`Package "${argv.package}" is not installed`); + } + packageDatas.push(pkg); + } else { + packageDatas = await list(); + } + + if (!packageDatas.length) { + if (argv.json) { + console.log(JSON.stringify(results, null, 2)); + } else { + console.log('There are no packages to update.'); + } + return; + } + + // step 1: check for updates + const plimit = promiseLimit(10); + const spinner = ora({ stream: terminal.stderr }).start('Checking packages for updates'); + const packages: ExtendedPackageData[] = (await Promise.all(packageDatas.map(async (pkg): Promise => { + return await plimit(async () => { + let latest = null; + try { + latest = (await view(pkg.name)).version; + } catch (e) {} + return { + ...pkg, + current: Object.keys(pkg.versions).sort(semver.rcompare)[0], + latest + }; + }) as ExtendedPackageData; + }))).filter(p => p.latest); + spinner.stop(); + + const updateTable = createTable(); + for (let i = 0; i < packages.length; i++) { + const pkg = packages[i]; + if (semver.gt(pkg.latest as string, pkg.version as string)) { + updateTable.push([ ` ${bold(pkg.name)}`, pkg.version, '→', hlVer(pkg.latest as string, pkg.version as string) ]); + } else { + results.alreadyActive.push(`${pkg.name}@${pkg.version}`); + packages.splice(i--, 1); + } + } + if (!packages.length) { + console.log('All packages are up-to-date'); + return; + } + + // step 2: confirm updates + console.log(`The following packages have updates available:\n\n${updateTable.toString()}\n`); + + if (terminal.stdout.isTTY && !argv.yes && !argv.json) { + await new Promise(resolve => { + terminal.once('keypress', str => { + terminal.stderr.cursorTo(0); + terminal.stderr.clearLine(0); + if (str === 'y' || str === 'Y') { + return resolve(); + } + process.exit(0); + }); + terminal.stderr.write('Do you want to update? (y/N) '); + }); + } + + // step 3: create the tasks + const tasks: any[] = packages.reduce((list: any[], pkg: ExtendedPackageData): any[] => { + const versionData = pkg.versions[pkg.latest]; + if (versionData) { + // select it + list.push({ + title: `${highlight(`${pkg.name}@${pkg.latest}`)} is installed, setting it as active`, + async task(ctx: any, task: any) { + results.selected.push(`${pkg.name}@${pkg.latest}`); + const config = await loadConfig(); + await config.set(`extensions.${pkg.name}`, versionData.path); + await config.save(); + task.title = `${highlight(`${pkg.name}@${pkg.latest}`)} set as active version`; + } + }); + } else { + list.push({ + title: `Downloading and installing ${highlight(`${pkg.name}@${pkg.latest}`)}`, + async task(ctx: any, task: any) { + try { + await new Promise((resolve, reject) => { + install(`${pkg.name}@${pkg.latest}`) + .on('download', ({ name, version }) => { + task.title = `Downloading ${highlight(`${name}@${version}`)}`; + }) + .on('install', ({ name, version }) => { + task.title = `Installing ${highlight(`${name}@${version}`)}`; + }) + .on('register', ({ name, version }) => { + task.title = `Registering ${highlight(`${name}@${version}`)}`; + }) + .on('end', info => { + task.title = `${highlight(`${info.name}@${info.version}`)} installed and set as active version`; + results.installed.push(info); + resolve(); + }) + .on('error', reject); + }); + } catch (err: any) { + results.failures.push({ + error: err.toString(), + package: pkg.name + }); + task.title = alert(err.toString()); + err.message = undefined; // prevent the error from rendering twice + exitCode(1); + throw err; + } + } + }); + } + + return list; + }, [] as any[]); + + // step 4: run the tasks + try { + await runListr({ console, json: !!argv.json, tasks }); + } catch (err: any) { + // errors are stored in the results + } + + const cfg = await loadConfig(); + cfg.delete('update.notified'); + await cfg.save(); + + if (argv.json) { + console.log(JSON.stringify(results, null, 2)); + } else { + // step 5: show packages that can be purged + const purgable = await listPurgable(argv.package as string); + if (Object.keys(purgable).length) { + const purgeTable = createTable(); + for (const [ name, versions ] of Object.entries(purgable)) { + purgeTable.push([ ` ${bold(name)}`, versions.map(v => v.version).sort(semver.rcompare).join(', ') ]); + } + console.log(`\nThe following package versions can be purged:\n\n${purgeTable.toString()}\n\nTo purge these unused packages, run: ${highlight('axway pm purge')}`); + } + } + + await cli.emitAction('axway:pm:update', results); + } +}; diff --git a/packages/axway-cli-pm/src/commands/use.js b/packages/axway-cli-pm/src/commands/use.ts similarity index 62% rename from packages/axway-cli-pm/src/commands/use.js rename to packages/axway-cli-pm/src/commands/use.ts index 92e763e1..6d393f28 100644 --- a/packages/axway-cli-pm/src/commands/use.js +++ b/packages/axway-cli-pm/src/commands/use.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + /** * Examples: * amplify pm use @@ -19,23 +24,25 @@ export default { desc: 'Activates a specific package version', options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => ctx.jsonMode = !!value, desc: 'Outputs activated package as JSON' } }, - async action({ argv, cli, console }) { - const npa = require('npm-package-arg'); - const semver = require('semver'); - const { default: snooplogg } = require('snooplogg'); - const { find } = require('../pm'); - const { loadConfig } = require('@axway/amplify-cli-utils'); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { default: npa } = await import('npm-package-arg'); + const { default: semver } = await import('semver'); + const { default: snooplogg } = await import('snooplogg'); + const { find } = await import('../pm.js'); + const { loadConfig } = await import('@axway/amplify-cli-utils'); const { highlight } = snooplogg.styles; - let { fetchSpec, name, type } = npa(argv.package); - const installed = find(name); + const packageInfo = npa(argv.package as string); + const { name, type } = packageInfo; + let { fetchSpec } = packageInfo; + const installed = await find(name as string); if (!installed) { - const err = new Error(`Package "${name}" is not installed`); + const err: any = new Error(`Package "${name}" is not installed`); err.code = 'ENOTFOUND'; err.detail = `Please run ${highlight(`"axway pm install ${name}"`)} to install it`; throw err; @@ -63,7 +70,7 @@ export default { const info = installed.versions[version]; if (!info) { - const err = new Error(`Package "${name}@${version}" is not installed`); + const err: any = new Error(`Package "${name}@${version}" is not installed`); err.code = 'ENOTFOUND'; err.detail = `Please run ${highlight(`"axway pm install ${name}@${version}"`)} to install it`; throw err; @@ -75,9 +82,9 @@ export default { } else { msg = `Set ${highlight(`${name}@${version}`)} as action version`; installed.version = version; - loadConfig() - .set(`extensions.${name}`, info.path) - .save(); + const config = await loadConfig(); + await config.set(`extensions.${name}`, info.path); + await config.save(); } if (argv.json) { diff --git a/packages/axway-cli-pm/src/commands/view.js b/packages/axway-cli-pm/src/commands/view.ts similarity index 73% rename from packages/axway-cli-pm/src/commands/view.js rename to packages/axway-cli-pm/src/commands/view.ts index 9ef0c22c..2cc2d013 100644 --- a/packages/axway-cli-pm/src/commands/view.js +++ b/packages/axway-cli-pm/src/commands/view.ts @@ -1,3 +1,8 @@ +import { + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; + export default { aliases: [ 'v', '!info', '!show' ], args: [ @@ -11,7 +16,7 @@ export default { { name: 'filter', hint: 'field[.subfield]', - callback: ({ ctx, value }) => { + callback({ ctx, value }: AxwayCLIOptionCallbackState) { if (value) { ctx.banner = false; } @@ -23,8 +28,8 @@ export default { desc: 'Displays info for a specific package', options: { '--json': { - callback: ({ ctx, value }) => { - ctx.jsonMode = value; + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => { + ctx.jsonMode = !!value; if (value) { ctx.banner = false; } @@ -32,12 +37,12 @@ export default { desc: 'Outputs package info as JSON' } }, - async action({ argv, cli, console }) { - const { view } = require('../pm'); - let info = await view(argv.package); + async action({ argv, cli, console }: AxwayCLIState): Promise { + const { view } = await import('../pm.js'); + let info: any = await view(argv.package as string); if (argv.filter) { - for (const key of argv.filter.split('.')) { + for (const key of (argv.filter as string).split('.')) { if (typeof info !== 'object') { break; } @@ -51,7 +56,7 @@ export default { return; } - const { default: snooplogg } = require('snooplogg'); + const { default: snooplogg } = await import('snooplogg'); const { green, highlight } = snooplogg.styles; if (info) { @@ -61,10 +66,10 @@ export default { console.log(desc + '\n'); } - const { createTable } = require('@axway/amplify-cli-utils'); - const semver = require('semver'); - const createVersionTable = (label, versions) => { - const majors = {}; + const { createTable } = await import('@axway/amplify-cli-utils'); + const { default: semver } = await import('semver'); + const createVersionTable = (label: string, versions: string[]): string => { + const majors: { [type: string]: string[] } = {}; // sort versions into buckets by major version for (const ver of versions) { @@ -99,7 +104,7 @@ export default { console.log(createVersionTable('Available versions:', info.versions)); } - if (info.installed) { + if (info.installed?.length) { console.log(createVersionTable('Installed versions:', Object.keys(info.installed))); } else { console.log(`To install this package, run:\n\n ${highlight(`axway pm install ${info.name}`)}`); diff --git a/packages/axway-cli-pm/src/index.js b/packages/axway-cli-pm/src/index.ts similarity index 61% rename from packages/axway-cli-pm/src/index.js rename to packages/axway-cli-pm/src/index.ts index 6e9b4d34..0936e1e7 100644 --- a/packages/axway-cli-pm/src/index.js +++ b/packages/axway-cli-pm/src/index.ts @@ -1,11 +1,17 @@ +import path from 'path'; +import { CLICommand, CLIHelpOptions } from 'cli-kit'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + export default { commands: `${__dirname}/commands`, desc: 'Package manager for Axway products', help: { - header() { + header(this: CLICommand) { return `${this.desc}.`; }, - footer({ style }) { + footer({ style }: CLIHelpOptions): string { return `${style.heading('Examples:')} List all available packages: diff --git a/packages/axway-cli-pm/src/pm.js b/packages/axway-cli-pm/src/pm.ts similarity index 72% rename from packages/axway-cli-pm/src/pm.js rename to packages/axway-cli-pm/src/pm.ts index 1ffa32cf..191fe19d 100644 --- a/packages/axway-cli-pm/src/pm.js +++ b/packages/axway-cli-pm/src/pm.ts @@ -1,16 +1,25 @@ import fs from 'fs-extra'; import npa from 'npm-package-arg'; import npmsearch from 'libnpmsearch'; -import pacote from 'pacote'; +import pacote, { Options, PacoteOptions } from 'pacote'; import path from 'path'; import promiseLimit from 'promise-limit'; import semver from 'semver'; import snooplogg from 'snooplogg'; import spawn from 'cross-spawn'; import which from 'which'; -import { createNPMRequestArgs, createRequestOptions, loadConfig, locations } from '@axway/amplify-cli-utils'; +import { + ConfigExtensions, + InstalledPackageDataDetailed, + PackageData, + PackageDataDetailed, + PurgeablePackageData, + PurgablePackageMap +} from './types.js'; +import { createNPMRequestArgs, createRequestOptions, loadConfig, locations, request } from '@axway/amplify-cli-utils'; import { EventEmitter } from 'events'; import { isDir, isFile, mkdirpSync } from '@axway/amplify-utils'; +import { Readable } from 'stream'; const scopedPackageRegex = /^@[a-z0-9][\w-.]+\/?/; const { error, log } = snooplogg('pm'); @@ -28,7 +37,7 @@ export const packagesDir = path.join(locations.axwayHome, 'axway-cli', 'packages * @param {String} packageName - The name of the package to find. * @returns {Object} */ -export function find(packageName) { +export async function find(packageName: string): Promise { if (!packageName || typeof packageName !== 'string') { throw new TypeError('Expected package name to be a non-empty string'); } @@ -37,7 +46,7 @@ export function find(packageName) { return undefined; } - const extensions = loadConfig().get('extensions', {}); + const extensions: ConfigExtensions = (await loadConfig()).get('extensions', {}); packageName = packageName.toLowerCase(); @@ -73,40 +82,44 @@ export function find(packageName) { * @param {String} pkgName - The package and version to install. * @returns {EventEmitter} */ -export function install(pkgName) { +export function install(pkgName: string): EventEmitter { const emitter = new EventEmitter(); setImmediate(async () => { - let cfg = loadConfig(); + let cfg = await loadConfig(); let previousActivePackage; - let info; + let pkg: PackageDataDetailed; + let info: InstalledPackageDataDetailed; try { - info = await view(pkgName); + pkg = await view(pkgName); - let npm; + let npm: string; try { npm = await which('npm'); - } catch (e) { - const err = new Error('Unable to find the "npm" executable. Please ensure you have "npm" installed on your machine'); + } catch (e: any) { + const err: any = new Error('Unable to find the "npm" executable. Please ensure you have "npm" installed on your machine'); err.code = 'ENONPM'; throw err; } - previousActivePackage = cfg.get(`extensions.${info.name}`); + previousActivePackage = cfg.get(`extensions.${pkg.name}`); - info.path = path.join(packagesDir, info.name, info.version); + info = { + ...pkg, + path: path.join(packagesDir, pkg.name, pkg.version) + }; mkdirpSync(info.path); emitter.emit('download', info); - await pacote.extract(`${info.name}@${info.version}`, info.path, createRequestOptions()); + await pacote.extract(`${info.name}@${info.version}`, info.path, (await createRequestOptions()) as Options); emitter.emit('install', info); const args = [ 'install', '--production', - '--force', // needed for npm 7 - ...createNPMRequestArgs() + // '--force', // needed for npm 7, but prints an error other npm versions + ...(await createNPMRequestArgs()) ]; const opts = { cwd: info.path, @@ -118,12 +131,12 @@ export function install(pkgName) { log(`node ${highlight(process.version)} npm ${highlight(spawn.sync('npm', [ '-v' ], opts).stdout.toString().trim())}`); log(`Running PWD=${info.path} ${highlight(`${npm} ${args.join(' ')}`)}`); - await new Promise((resolve, reject) => { + await new Promise(async (resolve, reject) => { let stderr = ''; const child = spawn(npm, args, opts); - child.stdout.on('data', data => log(data.toString().trim())); - child.stderr.on('data', data => { + (child.stdout as Readable).on('data', (data: Buffer) => log(data.toString().trim())); + (child.stderr as Readable).on('data', (data: Buffer) => { const s = data.toString(); stderr += s; log(s.trim()); @@ -139,23 +152,23 @@ export function install(pkgName) { }); emitter.emit('register', info); - cfg = loadConfig(); - cfg.set(`extensions.${info.name}`, info.path); - cfg.save(); + cfg = await loadConfig(); + await cfg.set(`extensions.${info.name}`, info.path); + await cfg.save(); emitter.emit('end', info); - } catch (err) { - if (info) { + } catch (err: any) { + if (info!) { if (previousActivePackage === info.path) { // package was reinstalled, but failed and directory is in an unknown state - cfg = loadConfig(); + cfg = await loadConfig(); cfg.delete(`extensions.${info.name}`); - cfg.save(); + await cfg.save(); } else if (previousActivePackage) { // restore the previous value - cfg = loadConfig(); - cfg.set(`extensions.${info.name}`, previousActivePackage); - cfg.save(); + cfg = await loadConfig(); + await cfg.set(`extensions.${info.name}`, previousActivePackage); + await cfg.save(); } if (info.path) { @@ -175,13 +188,14 @@ export function install(pkgName) { * * @returns {Promise>} */ -export async function list() { +export async function list(): Promise { if (!isDir(packagesDir)) { return []; } - const extensions = loadConfig().get('extensions', {}); - const packages = []; + const cfg = await loadConfig(); + const extensions = cfg.get('extensions', {}); + const packages: PackageData[] = []; for (const name of fs.readdirSync(packagesDir)) { const pkgDir = path.join(packagesDir, name); @@ -218,8 +232,8 @@ export async function list() { * packages. * @returns {Object} */ -export async function listPurgable(pkgName) { - let packages = []; +export async function listPurgable(pkgName: string): Promise { + let packages: PackageData[] = []; if (pkgName) { const pkg = await find(pkgName); @@ -231,19 +245,19 @@ export async function listPurgable(pkgName) { packages = await list(); } - const purgable = {}; + const purgable: PurgablePackageMap = {}; for (const { name, version, versions } of packages) { for (const [ ver, versionData ] of Object.entries(versions)) { // if managed and not in use - if (versionData.managed && versionData.path.startsWith(packagesDir) && semver.neq(ver, version)) { + if (versionData.managed && versionData.path.startsWith(packagesDir) && version && semver.neq(ver, version)) { if (!purgable[name]) { purgable[name] = []; } purgable[name].push({ ...versionData, version: ver - }); + } as PurgeablePackageData); } } } @@ -259,8 +273,8 @@ export async function listPurgable(pkgName) { * @param {String} pkgDir - The path to the package. * @returns {Object} */ -function loadPackageData(name, extensions, pkgDir) { - const packageData = { +function loadPackageData(name: string, extensions: ConfigExtensions, pkgDir: string): PackageData { + const packageData: PackageData = { name, description: undefined, version: undefined, @@ -277,7 +291,7 @@ function loadPackageData(name, extensions, pkgDir) { path: versionDir, managed: true }; - } catch (e) { + } catch (e: any) { // squelch } } @@ -311,7 +325,7 @@ function loadPackageData(name, extensions, pkgDir) { * @param {String} dir - Path to the package to delete. * @returns {Promise} */ -export async function uninstallPackage(dir) { +export async function uninstallPackage(dir: string): Promise { try { const pkgJson = await fs.readJson(path.join(dir, 'package.json')); if (pkgJson.scripts.uninstall) { @@ -322,7 +336,7 @@ export async function uninstallPackage(dir) { error(stderr); } } - } catch (e) { + } catch (e: any) { // squelch } @@ -338,9 +352,13 @@ export async function uninstallPackage(dir) { * @param {String} [opts.type] - A package type to filter by. * @returns {Promse>} */ -export async function search({ keyword, limit, type } = {}) { +export async function search({ keyword, limit, type }: { + keyword?: string, + limit?: string | number, + type?: string +} = {}): Promise { const plimit = promiseLimit(10); - const requestOpts = createRequestOptions(); + const requestOpts = await createRequestOptions(); const keywords = [ 'amplify-package' ]; if (process.env.TEST) { keywords.push('amplify-test-package'); @@ -348,20 +366,20 @@ export async function search({ keyword, limit, type } = {}) { if (keyword) { keywords.push(keyword); } - const packages = await npmsearch(keywords, { + const packages: npmsearch.Result[] = await npmsearch(keywords, { ...requestOpts, - limit: Math.max(limit && parseInt(limit, 10) || 50, 1) - }); - const results = []; + limit: Math.max(limit && parseInt(limit as string, 10) || 50, 1) + } as npmsearch.Options); + const results: PackageDataDetailed[] = []; - await Promise.all(packages.map(({ name, version }) => { - return plimit(async () => { + await Promise.all(packages.map(async ({ name, version }): Promise => { + await plimit(async () => { try { - const pkg = await view(`${name}@${version}`, { requestOpts, type }); + const pkg: PackageDataDetailed = await view(`${name}@${version}`, { requestOpts, type }); if (pkg) { results.push(pkg); } - } catch (err) { + } catch (err: any) { // squelch } }); @@ -370,6 +388,11 @@ export async function search({ keyword, limit, type } = {}) { return results.sort((a, b) => a.name.localeCompare(b.name)); } +interface ViewOptions { + requestOpts?: request.RequestOptions; + type?: string; +} + /** * Fetches package information directly from npm and checks that it's a valid package. * @@ -378,15 +401,19 @@ export async function search({ keyword, limit, type } = {}) { * @param {Object} [opts.requestOpts] - HTTP request options. * @param {String} [opts.type] - The package type to filter by. */ -export async function view(pkgName, { requestOpts = createRequestOptions(), type } = {}) { +export async function view(pkgName: string, { requestOpts, type }: ViewOptions = {}): Promise { if (!pkgName || typeof pkgName !== 'string') { throw new TypeError('Expected package name to be a non-empty string'); } + if (!requestOpts) { + requestOpts = await createRequestOptions(); + } + const { name, fetchSpec } = npa(pkgName); let info; - if (!name) { + if (!name || !fetchSpec) { throw new Error(`Invalid package name "${pkgName}"`); } @@ -394,8 +421,8 @@ export async function view(pkgName, { requestOpts = createRequestOptions(), type info = await pacote.packument(name, { ...requestOpts, fullMetadata: true - }); - } catch (err) { + } as PacoteOptions); + } catch (err: any) { if (err.statusCode === 404) { throw new Error(`Package "${pkgName}" not found`); } @@ -403,7 +430,7 @@ export async function view(pkgName, { requestOpts = createRequestOptions(), type } const version = info['dist-tags']?.[fetchSpec] || fetchSpec; - const pkg = info.versions[version]; + const pkg = info.versions[version] as any; const maintainers = [ 'appcelerator', 'axway-npm' ]; if (!pkg @@ -411,16 +438,16 @@ export async function view(pkgName, { requestOpts = createRequestOptions(), type || (type && pkg.amplify.type !== type) || (pkg.keywords.includes('amplify-test-package') && !process.env.TEST) || !pkg.keywords.includes('amplify-package') - || !pkg.maintainers.some(m => maintainers.includes(m.name)) + || (Array.isArray(pkg.maintainers) && !pkg.maintainers.some((m: { name: string }) => maintainers.includes(m.name))) ) { throw new Error(`Package "${pkgName}" not found`); } - const installed = find(pkg.name); + const installed = await find(pkg.name); return { description: pkg.description, - installed: installed?.versions || false, + installed: installed && Object.keys(installed.versions).length > 0, name: pkg.name, type: pkg.amplify.type, version, diff --git a/packages/axway-cli-pm/src/types.ts b/packages/axway-cli-pm/src/types.ts new file mode 100644 index 00000000..6b00b14f --- /dev/null +++ b/packages/axway-cli-pm/src/types.ts @@ -0,0 +1,38 @@ +export interface ConfigExtensions { + [name: string]: string; // path +} + +export interface PackageData { + description?: string; + name: string; + version?: string; + versions: { + [ver: string]: { + managed: boolean; + path: string; + } + } +} + +export interface PackageDataDetailed { + description?: string; + installed?: boolean; + name: string; + type?: string; + version: string; + versions: string[]; +} + +export interface InstalledPackageDataDetailed extends PackageDataDetailed { + path: string; +} + +export interface PurgeablePackageData extends PackageData { + managed: boolean; + path: string; + version: string; +} + +export interface PurgablePackageMap { + [name: string]: PurgeablePackageData[] +} diff --git a/packages/axway-cli-pm/src/utils.js b/packages/axway-cli-pm/src/utils.ts similarity index 61% rename from packages/axway-cli-pm/src/utils.js rename to packages/axway-cli-pm/src/utils.ts index cdd37354..8604f46e 100644 --- a/packages/axway-cli-pm/src/utils.js +++ b/packages/axway-cli-pm/src/utils.ts @@ -1,17 +1,35 @@ -import { Listr } from 'listr2'; import { ansi } from 'cli-kit'; +import { + Listr, + ListrEvent, + ListrOptions, + ListrRenderer, + ListrTaskObject +} from 'listr2'; + +export interface AxwayRunListrOptions { + console: Console; + json: boolean; + tasks: any; +} + +export interface AxwayListrOptions extends ListrOptions { + console: Console; +} /** * Custom Listr renderer for non-TTY environments. */ -export class ListrTextRenderer { - constructor(tasks, options) { - this._tasks = tasks; - this._console = options?.console || console; - } +export class ListrTextRenderer implements ListrRenderer { + _console: Console; + _tasks: any; + static nonTTY = true; + static rendererOptions: never; + static rendererTaskOptions: never; - static get nonTTY() { - return true; + constructor(tasks: ListrTaskObject[], options: AxwayListrOptions) { + this._console = options?.console || console; + this._tasks = tasks; } render() { @@ -19,7 +37,7 @@ export class ListrTextRenderer { for (const task of this._tasks) { task.subscribe( - event => { + (event: ListrEvent) => { if (event.type === 'STATE') { const message = task.isPending() ? 'started' : task.state.toLowerCase(); this._console.log(`${task.title} [${message}]`); @@ -27,7 +45,7 @@ export class ListrTextRenderer { this._console.log(task.title); } }, - err => this._console.error(err) + (err: any) => this._console.error(err) ); } } @@ -46,12 +64,12 @@ export class ListrTextRenderer { * @param {Array.} params.tasks - A list of tasks to execute. * @returns {Promise} */ -export async function runListr({ console, json, tasks }) { +export async function runListr({ console, json, tasks }: AxwayRunListrOptions): Promise { await (new Listr(tasks, { concurrent: 10, console, dateFormat: false, exitOnError: false, renderer: json ? 'silent' : process.stdout.isTTY === true ? 'default' : ListrTextRenderer - })).run(); + } as AxwayListrOptions)).run(); } diff --git a/packages/axway-cli-pm/tsconfig.json b/packages/axway-cli-pm/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/axway-cli-pm/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/packages/axway-cli/.gitignore b/packages/axway-cli/.gitignore deleted file mode 100644 index b3a1d215..00000000 --- a/packages/axway-cli/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -._* -.DS_Store* -.nyc_output -/coverage -/dist -/docs -gulpfile.tmp.* -junit.xml -node_modules -npm-debug.log -yarn-error.log diff --git a/packages/axway-cli/CHANGELOG.md b/packages/axway-cli/CHANGELOG.md index 110d4e71..e82401a7 100644 --- a/packages/axway-cli/CHANGELOG.md +++ b/packages/axway-cli/CHANGELOG.md @@ -1,3 +1,8 @@ +# v4.0.0 + +- BREAKING CHANGE: Dropped support for Node.js 12 and older. +- chore: Updated dependencies. + # v3.2.7 (Jul 7, 2022) - chore: Updated dependencies. diff --git a/packages/axway-cli/bin/axway b/packages/axway-cli/bin/axway deleted file mode 100755 index d624235f..00000000 --- a/packages/axway-cli/bin/axway +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node -require('v8-compile-cache'); -require('../dist/main'); diff --git a/packages/axway-cli/bin/axway.js b/packages/axway-cli/bin/axway.js new file mode 100755 index 00000000..f32d3624 --- /dev/null +++ b/packages/axway-cli/bin/axway.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +import 'v8-compile-cache'; +import '../dist/main.js'; diff --git a/packages/axway-cli/gulpfile.js b/packages/axway-cli/gulpfile.js deleted file mode 100644 index 4f5fdc73..00000000 --- a/packages/axway-cli/gulpfile.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -require('@axway/gulp-tasks')({ - exports, - pkgJson: require('./package.json'), - template: 'standard', - babel: 'node12' -}); diff --git a/packages/axway-cli/package.json b/packages/axway-cli/package.json index e9520874..966f3952 100644 --- a/packages/axway-cli/package.json +++ b/packages/axway-cli/package.json @@ -5,6 +5,8 @@ "access": "public" }, "description": "A unified CLI for the Axway Amplify platform.", + "type": "module", + "exports": "./dist/index.js", "author": "Axway, Inc. ", "maintainers": [ "Chris Barber ", @@ -16,39 +18,35 @@ "amplify" ], "bin": { - "axway": "./bin/axway" + "axway": "./bin/axway.js" }, "preferGlobal": true, "scripts": { - "build": "gulp build", - "coverage": "gulp coverage", - "docs": "gulp docs", - "postinstall": "node scripts/postinstall.js || node -e true", - "prepare": "gulp build", - "test": "gulp test" + "build": "tsc", + "coverage": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1", + "lint": "concurrently -s all -m 1 npm:lint:src npm:lint:tsc", + "lint:src": "eslint src/**/*.ts", + "lint:tsc": "tsc -p tsconfig.json", + "prepublishOnly": "concurrently -s all -m 1 npm:lint:src npm:build", + "test": "echo \"Error: Axway CLI tests are in the monorepo top-level\" && exit 1" }, "dependencies": { "@axway/amplify-cli-utils": "^5.0.11", "@axway/amplify-utils": "^1.0.9", - "@axway/axway-cli-auth": "^3.3.7", - "@axway/axway-cli-oum": "^2.0.11", - "@axway/axway-cli-pm": "^4.0.11", - "boxen": "^5.1.2", - "check-kit": "^2.0.0", - "cli-kit": "^1.16.0", - "serialize-error": "^8.1.0", - "snooplogg": "^3.0.2", - "source-map-support": "^0.5.21", + "@axway/axway-cli-auth": "^3.3.6", + "@axway/axway-cli-oum": "^2.0.10", + "@axway/axway-cli-pm": "^4.0.10", + "boxen": "^7.0.0", + "check-kit": "^3.0.1", + "cli-kit": "^2.0.2", + "serialize-error": "^11.0.0", + "snooplogg": "^5.0.0", "v8-compile-cache": "^2.3.0" }, - "devDependencies": { - "@axway/gulp-tasks": "^4.1.4" - }, "homepage": "https://github.com/appcelerator/amplify-tooling#readme", "bugs": "https://github.com/appcelerator/amplify-tooling/issues", "repository": "https://github.com/appcelerator/amplify-tooling/tree/master/packages/axway-cli", "engines": { - "node": ">=12.13.0" - }, - "gitHead": "9cc288d8ee067fb3444920aad11c53899455ad9c" + "node": ">=14.15.0" + } } diff --git a/packages/axway-cli/src/commands/config.js b/packages/axway-cli/src/commands/config.ts similarity index 76% rename from packages/axway-cli/src/commands/config.js rename to packages/axway-cli/src/commands/config.ts index 285c9eee..0c1c9129 100644 --- a/packages/axway-cli/src/commands/config.js +++ b/packages/axway-cli/src/commands/config.ts @@ -1,46 +1,55 @@ +import { + AxwayCLIContext, + AxwayCLIOptionCallbackState, + AxwayCLIState +} from '@axway/amplify-cli-utils'; +import { + CLIHelpOptions +} from 'cli-kit'; + export default { aliases: [ '!conf' ], banner: false, commands: { '@ls, list': { desc: 'Display all config settings', - action: ctx => runConfig('get', ctx) + action: (ctx: AxwayCLIState) => runConfig('get', ctx) }, 'get [~key]': { desc: 'Display a specific config setting', - action: ctx => runConfig('get', ctx) + action: (ctx: AxwayCLIState) => runConfig('get', ctx) }, 'set <~key> ': { desc: 'Change a config setting', - action: ctx => runConfig('set', ctx) + action: (ctx: AxwayCLIState) => runConfig('set', ctx) }, '@rm, delete, !remove, !unset <~key>': { desc: 'Remove a config setting', - action: ctx => runConfig('delete', ctx) + action: (ctx: AxwayCLIState) => runConfig('delete', ctx) }, 'push <~key> ': { desc: 'Add a value to the end of a list', - action: ctx => runConfig('push', ctx) + action: (ctx: AxwayCLIState) => runConfig('push', ctx) }, 'pop <~key>': { desc: 'Remove the last value in a list', - action: ctx => runConfig('pop', ctx) + action: (ctx: AxwayCLIState) => runConfig('pop', ctx) }, 'shift <~key>': { desc: 'Remove the first value in a list', - action: ctx => runConfig('shift', ctx) + action: (ctx: AxwayCLIState) => runConfig('shift', ctx) }, 'unshift <~key> ': { desc: 'Add a value to the beginning of a list', - action: ctx => runConfig('unshift', ctx) + action: (ctx: AxwayCLIState) => runConfig('unshift', ctx) } }, desc: 'Manage configuration options', help: { - header() { + header(this: AxwayCLIContext): string { return `${this.desc}.`; }, - footer: ({ style }) => `${style.heading('Examples:')} + footer: ({ style }: CLIHelpOptions): string => `${style.heading('Examples:')} List all config settings: ${style.highlight('axway config ls')} @@ -95,18 +104,18 @@ ${style.heading('Settings:')} }, options: { '--json': { - callback: ({ ctx, value }) => ctx.jsonMode = value, + callback: ({ ctx, value }: AxwayCLIOptionCallbackState) => (ctx as AxwayCLIContext).jsonMode = !!value, desc: 'Outputs the config as JSON' } } }; -async function runConfig(action, { argv, cli, console, setExitCode }) { - const { loadConfig } = require('@axway/amplify-cli-utils'); - let { json, key, value } = argv; - const cfg = loadConfig(argv); +async function runConfig(action: string, { argv, cli, console, setExitCode }: AxwayCLIState): Promise { + const { loadConfig } = await import('@axway/amplify-cli-utils'); + const { json, key, value }: { json: boolean, key: string, value: any } = argv as any; + const cfg = await loadConfig(argv); const data = { action, key, value }; - const filter = key && key.split(/\.|\//).filter(Boolean).join('.') || undefined; + const filter: string | undefined = key && key.split(/\.|\//).filter(Boolean).join('.') || undefined; if (typeof data.value === 'string') { try { @@ -116,7 +125,7 @@ async function runConfig(action, { argv, cli, console, setExitCode }) { } } - const print = ({ code = 0, key = null, value }) => { + const print = ({ code = 0, key = null, value }: { code?: number, key?: null | string, value: any }) => { setExitCode(code); if (json) { @@ -167,7 +176,7 @@ async function runConfig(action, { argv, cli, console, setExitCode }) { switch (action) { case 'set': - cfg.set(key, data.value); + await cfg.set(key, data.value); break; case 'delete': @@ -175,19 +184,19 @@ async function runConfig(action, { argv, cli, console, setExitCode }) { break; case 'push': - cfg.push(key, data.value); + await cfg.push(key, data.value); break; case 'pop': - result = cfg.pop(key); + result = await cfg.pop(key); break; case 'shift': - result = cfg.shift(key); + result = await cfg.shift(key); break; case 'unshift': - cfg.unshift(key, data.value); + await cfg.unshift(key, data.value); break; } diff --git a/packages/axway-cli/src/commands/telemetry.js b/packages/axway-cli/src/commands/telemetry.ts similarity index 74% rename from packages/axway-cli/src/commands/telemetry.js rename to packages/axway-cli/src/commands/telemetry.ts index b45fd53b..f4165d15 100644 --- a/packages/axway-cli/src/commands/telemetry.js +++ b/packages/axway-cli/src/commands/telemetry.ts @@ -1,3 +1,6 @@ +import { AxwayCLIContext, AxwayCLIState } from '@axway/amplify-cli-utils'; +import { CLIHelpOptions } from 'cli-kit'; + export default { desc: 'Opt-in or out of telemetry to improve Axway products', extendedDesc: `The Axway CLI has a telemetry system that collects anonymous data which is used @@ -13,10 +16,10 @@ Axway does not collect your personal information, link your activity to your Axway account, capture environment variables, or unique machine identifiers such as the MAC address or serial number.`, help: { - header() { + header(this: AxwayCLIContext): string { return `${this.desc}.`; }, - footer({ style }) { + footer(this: AxwayCLIContext, { style }: CLIHelpOptions) { return `${this.extendedDesc} You may opt-out of telemetry by running ${style.highlight('axway telemetry --disable')} or setting @@ -27,12 +30,12 @@ the environment variable ${style.highlight('AXWAY_TELEMETRY_DISABLED')} to ${sty '--enable': 'Enables data collection', '--disable': 'Disabled data collection and deletes any pending telemetry data' }, - async action({ argv, console, terminal }) { - const { default: snooplogg } = require('snooplogg'); + async action({ argv, console, terminal }: AxwayCLIState): Promise { + const { default: snooplogg } = await import('snooplogg'); const { green, red } = snooplogg.styles; - const { loadConfig, telemetry } = require('@axway/amplify-cli-utils'); - const config = loadConfig(); - let enabled = telemetry.isEnabled(); + const { loadConfig, telemetry } = await import('@axway/amplify-cli-utils'); + const config = await loadConfig(); + let enabled = await telemetry.isEnabled(); if (argv.enable && !argv.disable) { enabled = true; @@ -47,11 +50,12 @@ the environment variable ${style.highlight('AXWAY_TELEMETRY_DISABLED')} to ${sty } if (terminal.stdout.isTTY) { - enabled = await new Promise(resolve => { - terminal.once('keypress', str => { + enabled = await new Promise(resolve => { + terminal.once('keypress', (str: string): void => { terminal.stderr.cursorTo(0); - terminal.stderr.clearLine(); - return resolve(str === 'y' || str === 'Y'); + terminal.stderr.clearLine(0); + resolve(str === 'y' || str === 'Y'); + return; }); terminal.stderr.write('Do you want to enable telemetry? (y/N) '); }); diff --git a/packages/axway-cli/src/main.js b/packages/axway-cli/src/main.ts similarity index 71% rename from packages/axway-cli/src/main.js rename to packages/axway-cli/src/main.ts index 8848aee7..21aaf0ec 100644 --- a/packages/axway-cli/src/main.js +++ b/packages/axway-cli/src/main.ts @@ -1,11 +1,16 @@ -/* istanbul ignore if */ -if (!Error.prepareStackTrace) { - require('source-map-support/register'); -} - -import check from 'check-kit'; -import CLI from 'cli-kit'; +import check, { + CheckKitOptions, + CheckKitResults +} from 'check-kit'; import { + CLI, + CLIContext, + CLINextIterator, + CLIParsedArgument, + CLIState +} from 'cli-kit'; +import { + AxwayCLIState, Config, createRequestOptions, createTable, @@ -15,32 +20,38 @@ import { locations, telemetry } from '@axway/amplify-cli-utils'; +import path from 'path'; import snooplogg from 'snooplogg'; import { dirname, join, parse, resolve } from 'path'; import { existsSync, readFileSync } from 'fs'; +import { fileURLToPath } from 'url'; import { redact } from '@axway/amplify-utils'; import { serializeError } from 'serialize-error'; -const { bold, cyan, gray, red, yellow } = snooplogg.styles; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const { bold, cyan, gray, red, yellow } = snooplogg.chalk; const { log, warn } = snooplogg('axway'); +type ConfigExtension = [ string, string ]; + (async () => { - const pkgJson = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'))); + const pkgJson = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8')); const { version } = pkgJson; process.env.AMPLIFY_CLI = version; process.env.AXWAY_CLI = version; - let cfg; + let cfg: Config; try { - cfg = loadConfig(); + cfg = await loadConfig(); } catch (err) { // config failed to load, reset to defaults warn(err); - cfg = new Config(); + cfg = await new Config().init(); } - const externalExtensions = Object.entries(cfg.get('extensions', {})); - const allExtensions = [ ...externalExtensions ]; + const externalExtensions: ConfigExtension[] = Object.entries(cfg.get('extensions', {})); + const allExtensions: ConfigExtension[] = [ ...externalExtensions ]; for (const name of [ '@axway/axway-cli-auth', '@axway/axway-cli-oum', '@axway/axway-cli-pm' ]) { let { dir, root } = parse(__dirname); while (dir !== root) { @@ -55,26 +66,23 @@ const { log, warn } = snooplogg('axway'); } const packagesDir = resolve(locations.axwayHome, 'axway-cli', 'packages'); - let checkWait; + let checkWait: Promise<(CheckKitResults | void)[]> | undefined; const cli = new CLI({ banner() { const env = process.env.AXWAY_ENV; const title = process.env.AXWAY_ENV_TITLE; - let str = `${cyan('AXWAY CLI')}, version ${version}${!env || env === 'prod' ? '' : ` ${yellow(title.toUpperCase())}`} + let str = `${cyan('AXWAY CLI')}, version ${version}${!env || env === 'prod' || !title ? '' : ` ${yellow(title.toUpperCase())}`} Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; - if (process.versions.node.split('.')[0] < 12) { + if (parseInt(process.versions.node.split('.')[0]) < 14) { str += '\n\n' + yellow(` ┃ ATTENTION! The Node.js version you are currently using (${process.version}) has been - ┃ deprecated and is unsupported in Axway CLI v3 and newer. Please upgrade + ┃ deprecated and is unsupported in Axway CLI v4 and newer. Please upgrade ┃ Node.js to the latest LTS release: https://nodejs.org/`); } const { arch } = process; - if (arch === 'ia32' || arch === 'x32') { - str += '\n\n' + yellow(` ┃ ATTENTION! Your current architecture "${arch}" has been deprecated and is unsupported - ┃ in Axway CLI v3 and newer.`); - } else if (arch !== 'x64' && arch !== 'arm64') { + if (arch !== 'x64' && arch !== 'arm64') { str += '\n\n' + yellow(` ┃ ATTENTION! Your current architecture "${arch}" is not supported.`); } return str; @@ -92,33 +100,51 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; version }); - cli.on('banner', ({ argv }) => { + cli.on('banner', async ({ argv }) => { if (cfg.get('update.check') === false || argv.json) { log('Skipping update check'); return; } - const opts = createRequestOptions({ - metaDir: resolve(locations.axwayHome, 'axway-cli', 'update'), - timeout: 4000 + const opts = await createRequestOptions({ + timeout: { request: 4000 } }, cfg); + const checkOpts: CheckKitOptions = { + caFile: opts.caFile, + certFile: opts.certFile, + keyFile: opts.keyFile, + proxy: opts.proxy, + strictSSL: opts.strictSSL, + timeout: opts.timeout, + metaDir: resolve(locations.axwayHome, 'axway-cli', 'update'), + pkg: pkgJson + }; + // store the check promise and let it continue asynchronously - checkWait = Promise.all([ + checkWait = Promise.all([ // check the Axway CLI for updates check({ - ...opts, - pkg: pkgJson + caFile: opts.caFile, + certFile: opts.certFile, + keyFile: opts.keyFile, + proxy: opts.proxy, + strictSSL: opts.strictSSL, + timeout: opts.timeout, + metaDir: resolve(locations.axwayHome, 'axway-cli', 'update'), + pkg: pkgJson }).catch(() => {}), - // check all CLI extensions for updates + // check all CLI extensions for updates ...(externalExtensions .map(ext => join(ext[1], 'package.json')) .filter(ext => ext.startsWith(packagesDir) && existsSync(ext)) - .map(pkg => check({ - ...opts, - pkg - }).catch(() => {}))) + .map(async (pkg): Promise => { + try { + return await check(Object.assign(checkOpts, { pkg })); + } catch (e: any) {} + }) + ) ]); }); @@ -129,10 +155,10 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; }); // local ref so we can include argv and the context chain in the crash report - let state; + let state: AxwayCLIState | undefined = undefined; // after the args have been parsed, determine the environment before the banner is rendered - cli.on('parse', async (state, next) => { + cli.on('parse', async (state: CLIState, next: CLINextIterator) => { const { result } = await next(); const env = environments.resolve(result.argv.env || cfg.get('env')); process.env.AXWAY_ENV = env.name; @@ -141,7 +167,7 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; // add the hook to record the telemetry event after the command finishes running cli.on('exec', async (_state, next) => { - state = _state; + state = _state as AxwayCLIState; state.startTime = Date.now(); // if the command is running, then don't wait for it to finish, just send the telemetry @@ -173,14 +199,19 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; exitCode: state?.exitCode() || 0, extensions: allExtensions .map(([ name, ext ]) => { - const info = { name }; + const info = { + err: undefined, + managed: false, + name, + version: undefined + }; try { - const json = JSON.parse(readFileSync(join(ext, 'package.json'))); + const json = JSON.parse(readFileSync(join(ext, 'package.json'), 'utf-8')); if (ext.startsWith(packagesDir)) { info.managed = true; } info.version = json.version; - } catch (err) { + } catch (err: any) { info.err = err.toString(); } return info; @@ -197,9 +228,9 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; // now that the command is done, wait for the check to finish and display it's message, // if there is one if (checkWait && cmd.prop('banner')) { - const results = (await checkWait).filter(p => p?.updateAvailable); + const results: CheckKitResults[] = (await checkWait).filter(p => p?.updateAvailable) as CheckKitResults[]; if (results.length) { - const boxen = require('boxen'); + const { default: boxen } = await import('boxen'); let msg = ''; let axway = ''; const exts = createTable(); @@ -210,7 +241,9 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; return; } - loadConfig().set('update.notified', Date.now()).save(); + const config = await loadConfig(); + await config.set('update.notified', Date.now()); + await config.save(); // remove axway package and treat it special for (let i = 0; i < results.length; i++) { @@ -242,18 +275,18 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; } } } - } catch (err) { + } catch (err: any) { const exitCode = err.exitCode || 1; // record the crash telemetry.addCrash({ message: 'Unknown error', ...serializeError(err), - argv: state ? scrubArgv(state.__argv) : undefined, - contexts: state ? state.contexts.map(ctx => ctx.name).reverse() : undefined, - duration: state ? Date.now() - state.startTime : undefined, - exitCode: state?.exitCode() || 0, - warnings: state?.warnings + argv: state ? scrubArgv((state as AxwayCLIState).__argv) : undefined, + contexts: state ? (state as AxwayCLIState).contexts.map((ctx: CLIContext) => ctx.name).reverse() : undefined, + duration: state ? Date.now() - (state as AxwayCLIState).startTime : undefined, + exitCode: state ? (state as AxwayCLIState).exitCode() : 0, + warnings: state ? (state as AxwayCLIState).warnings : undefined }); if (err.json) { @@ -286,7 +319,7 @@ Copyright (c) 2018-2022, Axway, Inc. All Rights Reserved.`; * @param {Array} argv - The parsed arguments. * @returns {Array} */ -function scrubArgv(argv) { +function scrubArgv(argv: CLIParsedArgument[]): string[] { const scrubbed = []; for (const { arg, input, option, type } of argv) { if (type === 'command' || type === 'extension' || (type === 'option' && option.isFlag)) { diff --git a/packages/axway-cli/tsconfig.json b/packages/axway-cli/tsconfig.json new file mode 100644 index 00000000..837bccaf --- /dev/null +++ b/packages/axway-cli/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ "./src/**/*.ts" ] +} \ No newline at end of file diff --git a/scripts/release-notes.js b/scripts/release-notes.js new file mode 100644 index 00000000..4a9670f5 --- /dev/null +++ b/scripts/release-notes.js @@ -0,0 +1,286 @@ +const fs = require('fs-extra'); +const https = require('https'); +const semver = require('semver'); +const tar = require('tar-stream'); +const zlib = require('zlib'); +const { cyan } = require('ansi-colors'); + +const packages = {}; +const re = /^@axway\//; +const tempDir = tmp.dirSync({ + mode: '755', + prefix: 'axway-cli-release-notes-', + unsafeCleanup: true +}).name; +const cacheDir = path.join(__dirname, '.npm-info'); + +await fs.remove(cacheDir); +await fs.mkdirs(cacheDir); + +const fetch = async name => { + const cacheFile = path.join(cacheDir, `${name}.json`); + await fs.mkdirs(path.dirname(cacheFile)); + let info; + + if (fs.existsSync(cacheFile)) { + log(`Fetching ${cyan(name)} from cache`); + const s = fs.readFileSync(cacheFile, 'utf8'); + info = s ? JSON.parse(s) : null; + } else { + log(`Fetching ${cyan(name)}`); + const { status, stdout, stderr } = spawnSync('npm', [ 'view', name, '--json' ]); + if (status) { + console.error('Failed to get package info:'); + console.error(stdout.toString()); + console.error(stderr.toString()); + process.exit(1); + } + const s = stdout.toString(); + fs.writeFileSync(cacheFile, s); + + info = s ? JSON.parse(s) : null; + } + + // if more than one is returned, get the latest + if (Array.isArray(info)) { + let pkg; + for (const i of info) { + if (!pkg || semver.gt(i.version, pkg.version)) { + pkg = i; + } + } + info = pkg; + } + + return info; +}; + +const getPackageInfo = async (name, ver) => { + const info = await fetch(`${name}@${ver}`); + if (!info || packages[name]) { + return info; + } + + ver = info.version; + + log(`Initializing new package ${name}`); + packages[name] = { latest: null, versions: {} }; + + log(` Versions: ${info.versions.join(', ')}`); + for (const version of info.versions) { + if (!packages[name].versions[version] && semver.valid(version) && semver.gt(version, '0.0.0')) { + const { prerelease } = semver.parse(version); + if (!prerelease || !prerelease.length) { + log(` Initializing pacakge ${name}@${version}`); + const verInfo = await fetch(`${name}@${version}`); + if (verInfo) { + packages[name].versions[version] = { changelog: null, ts: info.time[version], version }; + for (const type of [ 'dependencies', 'devDependencies' ]) { + if (verInfo[type]) { + for (const [ dep, range ] of Object.entries(verInfo[type])) { + if (re.test(dep)) { + await getPackageInfo(dep, range); + } + } + } + } + } + } + } + } + + return info; +}; + +const processChangelog = (name, changelog) => { + const changes = changelog.split('\n\n#').map((s, i) => `${i ? '#' : ''}${s}`.trim()); + for (const chunk of changes) { + const m = chunk.match(/^# v?([^\s\n]*)[^\n]*\n+(.+)$/s); + if (!m) { + continue; + } + + const { version } = semver.coerce(m[1]); + + if (packages[name].versions[m[1]]) { + packages[name].versions[m[1]].changelog = m[2]; + } else if (packages[name].versions[version]) { + packages[name].versions[version].changelog = m[2]; + } else { + log(red(`Package ${name} does not have a version ${m[1]}! (${Object.keys(packages[name].versions).join(', ')})`)); + } + } +}; + +try { + // Step 1: get all the `axway` releases and their `@axway/*` dependencies + const { versions } = await fetch('axway'); + for (const ver of versions) { + if (semver.valid(ver) && semver.gt(ver, '0.0.0')) { + const { prerelease } = semver.parse(ver); + if (!prerelease || !prerelease.length) { + await getPackageInfo('axway', ver); + } + } + } + + // Step 2: add in the local packages + const local = {}; + for (const subdir of fs.readdirSync(path.join(__dirname, 'packages'))) { + try { + const pkgJson = fs.readJsonSync(path.join(__dirname, 'packages', subdir, 'package.json')); + let { name, version } = pkgJson; + local[name] = pkgJson; + const changelogFile = path.join(__dirname, 'packages', subdir, 'CHANGELOG.md'); + const changelog = fs.existsSync(changelogFile) ? fs.readFileSync(changelogFile, 'utf8') : null; + let ts = null; + + const m = changelog && changelog.match(/^# v([^\s]+)/); + if (m && m[1] !== version) { + // set release timestamp to now unless package is axway, then make it 10 seconds older + ts = new Date(Date.now() + (name === 'axway' || name === '@axway/amplify-cli' ? 10000 : 0)); + pkgJson.version = version = m[1]; + } + + // TEMP: another v2 prerelease hack + version = semver.coerce(version).version; + if (name === '@axway/amplify-cli') { + name = 'axway'; + } + + if (!packages[name]) { + packages[name] = { latest: null, versions: {} }; + } + + if (!packages[name] || !packages[name].versions[version]) { + packages[name].local = true; + packages[name].versions[version] = { changelog: null, local: true, ts, version }; + } + + if (changelog) { + processChangelog(name, changelog); + } + } catch (e) {} + } + + // Step 3: for each non-local package, fetch the latest npm package and extract the changelog + for (const [ pkg, info ] of Object.entries(packages)) { + if (!packages[pkg].latest) { + packages[pkg].latest = Object.keys(info.versions).sort(semver.compare).pop(); + } + + if (info.local) { + continue; + } + + const changelogFile = path.join(cacheDir, `${pkg}@${info.latest}_CHANGELOG.md`); + if (fs.existsSync(changelogFile)) { + processChangelog(pkg, fs.readFileSync(changelogFile, 'utf8')); + } else { + const url = `https://registry.npmjs.org/${pkg}/-/${path.basename(pkg)}-${info.latest}.tgz`; + const file = path.join(tempDir, `${path.basename(pkg)}-${info.latest}.tgz`); + + await new Promise((resolve, reject) => { + const dest = fs.createWriteStream(file); + dest.on('finish', () => dest.close(resolve)); + log(`Downloading ${cyan(url)}`); + https.get(url, response => response.pipe(dest)) + .on('error', reject); + }); + + await new Promise((resolve, reject) => { + const gunzip = zlib.createGunzip(); + const extract = tar.extract(); + + extract.on('entry', (header, stream, next) => { + if (header.name !== 'package/CHANGELOG.md') { + stream.resume(); + return next(); + } + + let changelog = ''; + stream + .on('data', chunk => changelog += chunk) + .on('end', () => { + fs.writeFileSync(changelogFile, changelog, 'utf8'); + processChangelog(pkg, changelog); + next(); + }) + .on('error', reject) + .resume(); + }); + + extract.on('finish', resolve); + extract.on('error', reject); + + log(`Extract changelog from ${cyan(file)}`); + fs.createReadStream(file).pipe(gunzip).pipe(extract); + }); + } + } +} finally { + fs.removeSync(tempDir); +} + +const axwayCli = packages['axway']; +delete packages['axway']; +const pkgs = Object.keys(packages).sort(); + +// Step 4: loop over every `axway` release and generate the changelog +for (const ver of Object.keys(axwayCli.versions).sort(semver.compare)) { + const { raw } = semver.coerce(ver); + if (semver.lte(raw, '2.0.0')) { + continue; + } + const { major, minor, patch } = semver.parse(ver); + const cleanVersion = `${major}.${minor}.${patch}`; + const dest = path.join(__dirname, 'docs', 'Release Notes', `Axway CLI ${raw}.md`); + const { changelog, local, ts } = axwayCli.versions[ver]; + const dt = ts ? new Date(ts) : new Date(); + const rd = ts && dt.toDateString().split(' ').slice(1); + let s = `# Axway CLI ${raw}\n\n## ${local ? 'Unreleased' : `${rd[0]} ${rd[1]}, ${rd[2]}`}\n\n`; + + if (patch === 0) { + if (minor === 0) { + s += 'This is a major release with breaking changes, new features, bug fixes, and dependency updates.\n\n'; + } else { + s += 'This is a minor release with new features, bug fixes, and dependency updates.\n\n'; + } + } else { + s += 'This is a patch release with bug fixes and minor dependency updates.\n\n'; + } + s += `### Installation\n\n\`\`\`\nnpm i -g axway@${cleanVersion}\n\`\`\`\n\n` + if (changelog) { + s += '### axway\n\n'; + s += ` * **v${cleanVersion}**${ts ? ` - ${dt.toLocaleDateString()}` : ''}\n\n`; + s += `${changelog.split('\n').map(s => ` ${s}`).join('\n')}\n\n`; + } + + for (const pkg of pkgs) { + // the AMPLIFY CLI and Auth SDK are deprecated, so ignore them + if (pkg === '@axway/amplify-cli' || pkg === '@axway/amplify-auth-sdk') { + continue; + } + + const vers = Object.keys(packages[pkg].versions).filter(ver => { + const { ts } = packages[pkg].versions[ver]; + return !ts || new Date(ts) < dt; + }).sort(semver.rcompare); + + let vs = ''; + for (const v of vers) { + if (packages[pkg].versions[v].changelog) { + const pts = new Date(packages[pkg].versions[v].ts); + vs += ` * **v${v}** - ${pts.toLocaleDateString()}\n\n`; + vs += `${packages[pkg].versions[v].changelog.split('\n').map(s => ` ${s}`).join('\n')}\n\n`; + } + delete packages[pkg].versions[v]; + } + if (vs) { + s += `### ${pkg.replace(/@.+\//, '')}\n\n${vs}`; + } + } + + log(`Writing release notes ${cyan(dest)}`); + fs.outputFileSync(dest, s.trim()); +} \ No newline at end of file diff --git a/scripts/run-tests.js b/scripts/run-tests.js new file mode 100644 index 00000000..dcff2dd7 --- /dev/null +++ b/scripts/run-tests.js @@ -0,0 +1,145 @@ +import chalk from 'chalk'; +import fs from 'fs-extra'; +import path from 'path'; +import tmp from 'tmp'; +import { createRequire } from 'module'; +import { fileURLToPath } from 'url'; +import { findUpSync } from 'find-up'; +import { spawnSync } from 'child_process'; + +const { cyan } = chalk; +const root = path.dirname(fileURLToPath(new URL('.', import.meta.url))); +const all = process.argv.includes('--all'); +const cover = process.argv.includes('--coverage'); +const coverageDir = path.join(root, 'coverage'); + +let origHomeDir = process.env.HOME; +let tmpHomeDir = tmp.dirSync({ + mode: '755', + prefix: 'axway-cli-test-home-', + unsafeCleanup: true +}).name; + +if (all) { + process.env.AXWAY_TEST = '1'; // allow telemetry tests to run +} +process.env.NODE_ENV = 'test'; // disables the update check +// process.env.SNOOPLOGG = '*'; // uncomment to debug +process.env.SNOOPLOGG_MIN_BRIGHTNESS = '100'; +process.env.SPAWN_WRAP_SHIM_ROOT = origHomeDir; + +console.log(`Protecting home directory, overriding HOME with temp dir: ${cyan(tmpHomeDir)}`); +process.env.HOME = process.env.USERPROFILE = tmpHomeDir; +if (process.platform === 'win32') { + process.env.HOMEDRIVE = path.parse(tmpHomeDir).root.replace(/[\\/]/g, ''); + process.env.HOMEPATH = tmpHomeDir.replace(process.env.HOMEDRIVE, ''); +} + +try { + await fs.remove(path.join(root, '.nyc_output')); + await fs.remove(coverageDir); + + const args = []; + + // add c8 + if (cover) { + args.push( + path.resolve(resolveModule(root, 'c8'), 'bin', 'c8.js'), + '--cache', 'true', + '--exclude', 'test', + '--exclude', 'packages/*/test/**/*.js', // exclude tests + '--instrument', 'true', + '--source-map', 'true', + // supported reporters: + // https://github.com/istanbuljs/istanbuljs/tree/master/packages/istanbul-reports/lib + '--reporter=html', + '--reporter=json', + '--reporter=lcovonly', + '--reporter=text', + '--reporter=text-summary', + '--reporter=cobertura', + '--show-process-tree', + process.execPath // need to specify node here so that spawn-wrap works + ); + + process.env.FORCE_COLOR = 1; + process.env.AXWAY_COVERAGE = root; + } + + // add ts-mocha + const tsmocha = resolveModule(root, 'ts-mocha'); + if (!tsmocha) { + console.error(chalk.red('Unable to find ts-mocha!')); + process.exit(1); + } + args.push(path.join(tsmocha, 'bin', 'ts-mocha'), '-n', 'loader=ts-node/esm'); + + // add --inspect + if (process.argv.includes('--debug') || process.argv.includes('--inspect') || process.argv.includes('--inspect-brk')) { + args.push('--inspect-brk', '--timeout', '9999999'); + } else { + args.push('--timeout', 40000); + } + args.push('--slow', 15000); + + // add grep + let p = process.argv.indexOf('--grep'); + if (p !== -1 && p + 1 < process.argv.length) { + args.push('--grep', process.argv[p + 1]); + } + + // add suite + p = process.argv.indexOf('--suite'); + if (p !== -1 && p + 1 < process.argv.length) { + const suites = process.argv[p + 1].split(','); + args.push.apply(args, suites.map(s => `test/**/test-${s}.{js,ts}`)); + if (all) { + args.push.apply(args, suites.map(s => `packages/*/test/**/test-${s}.{js,ts}`)); + } + } else { + args.push('test/**/test-*.{js,ts}'); + if (all) { + args.push('packages/*/test/**/test-*.{js,ts}'); + } + } + + // run! + console.log(`Running: ${chalk.cyan(`${process.execPath} ${args.join(' ')}`)}`); + if (spawnSync(process.execPath, args, { cwd: root, stdio: 'inherit' }).status) { + console.error(chalk.red('At least one test failed :(')); + process.exit(1); + } +} finally { + // restore home directory so that we can delete the temp one + if (tmpHomeDir) { + console.log(`Removing temp home directory: ${cyan(tmpHomeDir)}`); + try { + fs.removeSync(tmpHomeDir); + } catch (err) { + console.log(`Failed to remove temp home directory: ${err.toString()}`); + } + } + + console.log(`Restoring home directory: ${cyan(origHomeDir)}`); + process.env.HOME = origHomeDir; + + if (cover && fs.existsSync(coverageDir)) { + fs.copySync(path.join(root, 'test', 'helpers', 'report-styles'), coverageDir); + } +} + +function resolveModule(root, name) { + let dir = path.join(root, name); + if (fs.existsSync(dir)) { + return dir; + } + + try { + const require = createRequire(import.meta.url); + const s = path.dirname(require.resolve(name)); + const t = path.dirname(findUpSync('package.json', { cwd: s })); + return t; + } catch (e) { + return null; + } +} diff --git a/test/auth/list/platform-service-accounts.mustache b/test/auth/list/platform-service-accounts.mustache index afeb4c16..5e8daaee 100644 --- a/test/auth/list/platform-service-accounts.mustache +++ b/test/auth/list/platform-service-accounts.mustache @@ -3,4 +3,4 @@ Copyright (c) 2018-{{year}}, Axway, Inc. All Rights Reserved.{{{nodeDeprecationW ACCOUNT NAME ORGANIZATION CURRENT TEAM REGION TYPE EXPIRES {{#green}}{{check}} test_client:foo@bar.com{{/green}} Foo org (100) A Team (60000) US Platform {{delta}} - test_client:service@bar.com n/a n/a US Service {{delta}} + test_client:service@bar.com Foo org (100) n/a US Service {{delta}} diff --git a/test/auth/list/service-bar-account.mustache b/test/auth/list/service-bar-account.mustache index dbea61f9..8377261b 100644 --- a/test/auth/list/service-bar-account.mustache +++ b/test/auth/list/service-bar-account.mustache @@ -1,5 +1,5 @@ {{#cyan}}AXWAY CLI{{/cyan}}, version {{version}} Copyright (c) 2018-{{year}}, Axway, Inc. All Rights Reserved.{{{nodeDeprecationWarning}}} -ACCOUNT NAME ORGANIZATION CURRENT TEAM REGION TYPE EXPIRES -{{#green}}{{check}} test_client:service@bar.com{{/green}} n/a n/a US Service {{delta}} +ACCOUNT NAME ORGANIZATION CURRENT TEAM REGION TYPE EXPIRES +{{#green}}{{check}} test_client:service@bar.com{{/green}} Foo org (100) n/a US Service {{delta}} diff --git a/test/auth/login/success-service-not-default.mustache b/test/auth/login/success-service-not-default.mustache index 300ee506..c633692d 100644 --- a/test/auth/login/success-service-not-default.mustache +++ b/test/auth/login/success-service-not-default.mustache @@ -4,5 +4,8 @@ Copyright (c) 2018-{{year}}, Axway, Inc. All Rights Reserved.{{{nodeDeprecationW You are logged into a {{#cyan}}service{{/cyan}} account as {{#cyan}}service@bar.com{{/cyan}}. The current region is set to {{#cyan}}US{{/cyan}}. +ORGANIZATION GUID ORG ID + Foo org 1000 100 + To make this account the default, run: {{#cyan}}axway config set auth.defaultAccount test_client:service@bar.com{{/cyan}} diff --git a/test/auth/login/success-service.mustache b/test/auth/login/success-service.mustache index 26dd0b67..e684042a 100644 --- a/test/auth/login/success-service.mustache +++ b/test/auth/login/success-service.mustache @@ -4,4 +4,7 @@ Copyright (c) 2018-{{year}}, Axway, Inc. All Rights Reserved.{{{nodeDeprecationW You are logged into a {{#cyan}}service{{/cyan}} account as {{#cyan}}service@bar.com{{/cyan}}. The current region is set to {{#cyan}}US{{/cyan}}. +ORGANIZATION GUID ORG ID + Foo org 1000 100 + This account has been set as the default. diff --git a/test/auth/logout/success.mustache b/test/auth/logout/success.mustache index a8bca2e5..dc288826 100644 --- a/test/auth/logout/success.mustache +++ b/test/auth/logout/success.mustache @@ -1,5 +1,6 @@ {{#cyan}}AXWAY CLI{{/cyan}}, version {{version}} Copyright (c) 2018-{{year}}, Axway, Inc. All Rights Reserved.{{{nodeDeprecationWarning}}} +Launching default web browser: {{#cyan}}{{url}}{{/cyan}} Revoked authenticated accounts: {{#cyan}}test_client:foo@bar.com{{/cyan}} diff --git a/test/auth/test-auth.js b/test/auth/test-auth.js index f202d71d..a334235a 100644 --- a/test/auth/test-auth.js +++ b/test/auth/test-auth.js @@ -1,6 +1,8 @@ import fs from 'fs-extra'; import got from 'got'; import path from 'path'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; import { initHomeDir, renderRegexFromFile, @@ -9,9 +11,10 @@ import { runAxwaySync, startServers, stopServers -} from '../helpers'; +} from '../helpers/index.js'; import { isHeadless } from '@axway/amplify-cli-utils'; +const __dirname = fileURLToPath(new URL('.', import.meta.url)); const itSkipHeadless = isHeadless() ? it.skip : it; describe('axway auth', () => { @@ -19,15 +22,15 @@ describe('axway auth', () => { after(resetHomeDir); it('should output the help screen with color', async () => { - const { status, stdout } = await runAxwaySync([ 'auth' ]); - expect(status).to.equal(2); + const { status, stdout, stderr } = await runAxwaySync([ 'auth' ]); expect(stdout).to.match(renderRegexFromFile('help/help-with-color')); + expect(status).to.equal(2); }); it('should output the help screen using --help flag', async () => { const { status, stdout } = await runAxwaySync([ 'auth', '--help' ]); - expect(status).to.equal(2); expect(stdout).to.match(renderRegexFromFile('help/help-with-color')); + expect(status).to.equal(2); }); }); @@ -36,20 +39,20 @@ describe('axway auth', () => { it('should list no authenticated accounts', async () => { const { status, stdout } = await runAxwaySync([ 'auth', 'list' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('list/no-accounts')); + expect(status).to.equal(0); }); it('should list no authenticated accounts as JSON', async () => { const { status, stdout } = await runAxwaySync([ 'auth', 'list', '--json' ]); - expect(status).to.equal(0); expect(JSON.parse(stdout)).to.deep.equal([]); + expect(status).to.equal(0); }); it('should display list help', async () => { const { status, stdout } = await runAxwaySync([ 'auth', 'list', '--help' ]); - expect(status).to.equal(2); expect(stdout).to.match(renderRegexFromFile('list/help')); + expect(status).to.equal(2); }); // NOTE: `list` tests with accounts are handled by `login` tests @@ -68,11 +71,11 @@ describe('axway auth', () => { SSH_TTY: '1' } }); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('login/headless')); + expect(status).to.equal(1); }); - itSkipHeadless('should log into platform account using PKCE, list account, and login again', async function () { + it('should log into platform account using PKCE, list account, and login again', async function () { initHomeDir('home-local'); this.servers = await startServers(); @@ -167,12 +170,12 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout, stderr } = await runAxwaySync([ 'auth', 'login', '--secret-file', 'does_not_exist' ]); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('login/secret-file-not-found')); + expect(status).to.equal(1); ({ status, stdout, stderr } = await runAxwaySync([ 'auth', 'login', '--secret-file', path.join(__dirname, 'login/bad-secret.pem') ])); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('login/invalid-secret-file')); + expect(status).to.equal(1); }); it('should log into service account using signed JWT', async function () { @@ -180,12 +183,12 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout } = await runAxwaySync([ 'auth', 'login', '--secret-file', path.join(__dirname, 'login/secret.pem') ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('login/success-service')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'list' ])); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('list/service-bar-account')); + expect(status).to.equal(0); }); it('should log into platform account using client secret, username and password', async function () { @@ -193,12 +196,12 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout } = await runAxwaySync([ 'auth', 'login', '--client-secret', 'shhhh', '--username', 'test1@domain.com', '--password', 'bar' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('login/success-headless')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'list' ])); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('list/service-bar-platform-account')); + expect(status).to.equal(0); }); it('should log into platform account using secret file, username and password', async function () { @@ -206,12 +209,12 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout } = await runAxwaySync([ 'auth', 'login', '--secret-file', path.join(__dirname, 'login/secret.pem'), '--username', 'test1@domain.com', '--password', 'bar' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('login/success-headless')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'list' ])); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('list/service-bar-platform-account')); + expect(status).to.equal(0); }); it('should error logging into platform account using username and password and no client secret or secret file', async function () { @@ -219,8 +222,8 @@ describe('axway auth', () => { this.servers = await startServers(); const { status, stderr } = await runAxwaySync([ 'auth', 'login', '--username', 'test1@domain.com', '--password', 'bar' ]); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('login/missing-client-secret')); + expect(status).to.equal(1); }); it('should error logging into platform account using invalid username and password credentials', async function () { @@ -231,12 +234,12 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stderr } = await runAxwaySync([ 'auth', 'login', '--client-secret', 'shhh', '--username', 'bad_user', '--password', 'bar' ]); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('login/bad-credentials')); + expect(status).to.equal(1); ({ status, stderr } = await runAxwaySync([ 'auth', 'login', '--client-secret', 'shhh', '--username', 'test1@domain.com', '--password', 'bad_password' ])); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('login/bad-credentials')) + expect(status).to.equal(1); }); itSkipHeadless('should log into both a platform and service account', async function () { @@ -268,15 +271,15 @@ describe('axway auth', () => { passiveOpen: true }); - expect(status).to.equal(1); expect(stdout).to.match(renderRegexFromFile('login/timeout-stdout')); expect(stderr).to.match(renderRegexFromFile('login/timeout-stderr')); + expect(status).to.equal(1); }); it('should display login help', async () => { const { status, stdout } = await runAxwaySync([ 'auth', 'login', '--help' ]); - expect(status).to.equal(2); expect(stdout).to.match(renderRegexFromFile('login/help')); + expect(status).to.equal(2); }); }); @@ -284,7 +287,7 @@ describe('axway auth', () => { afterEach(stopServers); afterEach(resetHomeDir); - itSkipHeadless('should logout of platform account', async function () { + it('should logout of platform account', async function () { initHomeDir('home-local'); this.servers = await startServers(); @@ -299,8 +302,8 @@ describe('axway auth', () => { expect(accounts[0].name).to.equal('test_client:foo@bar.com'); ({ status, stdout } = await runAxwaySync([ 'auth', 'logout' ])); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('logout/success')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'list', '--json' ])); accounts = JSON.parse(stdout); @@ -313,8 +316,8 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout } = await runAxwaySync([ 'auth', 'login' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('login/success')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'list', '--json' ])); let accounts = JSON.parse(stdout); @@ -341,20 +344,20 @@ describe('axway auth', () => { it('should error if no authenticated accounts', async () => { const { status, stderr } = await runAxwaySync([ 'auth', 'logout' ]); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('logout/no-accounts')); + expect(status).to.equal(1); }); it('should error if specified account is not found', async () => { const { status, stderr } = await runAxwaySync([ 'auth', 'logout', 'foo' ]); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('logout/not-found')); + expect(status).to.equal(1); }); it('should display logout help', async () => { const { status, stdout } = await runAxwaySync([ 'auth', 'logout', '--help' ]); - expect(status).to.equal(2); expect(stdout).to.match(renderRegexFromFile('logout/help')); + expect(status).to.equal(2); }); }); @@ -368,8 +371,8 @@ describe('axway auth', () => { it('should display switch help', async () => { const { status, stdout } = await runAxwaySync([ 'auth', 'switch', '--help' ]); - expect(status).to.equal(2); expect(stdout).to.match(renderRegexFromFile('switch/help')); + expect(status).to.equal(2); }); }); @@ -382,12 +385,12 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout } = await runAxwaySync([ 'auth', 'login' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('login/success')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'whoami' ])); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('whoami/foo-bar-account')); + expect(status).to.equal(0); }); it.skip('should log into service account and display whoami for all accounts', async function () { @@ -402,12 +405,12 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout } = await runAxwaySync([ 'auth', 'login' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('login/success')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'whoami', 'foo@bar.com' ])); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('whoami/foo-bar-account')); + expect(status).to.equal(0); }); itSkipHeadless('should login and display whoami and output result as JSON', async function () { @@ -415,8 +418,8 @@ describe('axway auth', () => { this.servers = await startServers(); let { status, stdout } = await runAxwaySync([ 'auth', 'login' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('login/success')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'auth', 'whoami', '--json' ])); expect(status).to.equal(0); @@ -431,8 +434,8 @@ describe('axway auth', () => { this.servers = await startServers(); const { status, stdout } = await runAxwaySync([ 'auth', 'whoami' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('whoami/not-logged-in')); + expect(status).to.equal(0); }); it('should login and display not logged into a specific account', async function () { @@ -440,14 +443,14 @@ describe('axway auth', () => { this.servers = await startServers(); const { status, stdout } = await runAxwaySync([ 'auth', 'whoami', 'foo@bar.com' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('whoami/not-logged-in-account')); + expect(status).to.equal(0); }); it('should display whoami help', async () => { const { status, stdout } = await runAxwaySync([ 'auth', 'whoami', '--help' ]); - expect(status).to.equal(2); expect(stdout).to.match(renderRegexFromFile('whoami/help')); + expect(status).to.equal(2); }); }); diff --git a/test/axway/help/32-bit-deprecation.mustache b/test/axway/help/32-bit-deprecation.mustache index 22a0ce9d..56a5d94b 100644 --- a/test/axway/help/32-bit-deprecation.mustache +++ b/test/axway/help/32-bit-deprecation.mustache @@ -1,8 +1,7 @@ {{#cyan}}AXWAY CLI{{/cyan}}, version {{version}} Copyright (c) 2018-{{year}}, Axway, Inc. All Rights Reserved.{{{nodeDeprecationWarning}}} -{{#yellow}} ┃ ATTENTION! Your current architecture "ia32" has been deprecated and is unsupported{{/yellow}} -{{#yellow}} ┃ in Axway CLI v3 and newer.{{/yellow}} +{{#yellow}} ┃ ATTENTION! Your current architecture "ia32" is not supported.{{/yellow}} The Axway CLI is a unified command line interface for the Axway Amplify Platform. diff --git a/test/axway/test-axway.js b/test/axway/test-axway.js index b2c68f64..e8b0eb9d 100644 --- a/test/axway/test-axway.js +++ b/test/axway/test-axway.js @@ -1,8 +1,9 @@ +import { expect } from 'chai'; import { renderRegexFromFile, resetHomeDir, runAxwaySync -} from '../helpers'; +} from '../helpers/index.js'; describe('axway', () => { describe('help', () => { @@ -10,14 +11,17 @@ describe('axway', () => { it('should output the help screen with color', async () => { const { status, stdout } = await runAxwaySync(); - expect(status).to.equal(2); expect(stdout.toString()).to.match(renderRegexFromFile('help/help-with-color')); + expect(status).to.equal(2); }); - it('should output the help screen without color', async () => { + it.skip('should output the help screen without color', async () => { const { status, stdout } = await runAxwaySync([ '--no-color' ]); - expect(status).to.equal(2); + console.log('-'.repeat(100)); + console.log(stdout); + console.log('-'.repeat(100)); expect(stdout.toString()).to.match(renderRegexFromFile('help/help-without-color')); + expect(status).to.equal(2); }); it('should output the help as JSON', async () => { @@ -56,13 +60,13 @@ describe('axway', () => { }); it('should show 32-bit deprecation warning', async () => { - const { status, stdout } = await runAxwaySync([], { shim: 'arch-shim-ia32' }); - expect(status).to.equal(2); + const { status, stdout } = await runAxwaySync([], { arch: 'ia32' }); expect(stdout.toString()).to.match(renderRegexFromFile('help/32-bit-deprecation')); + expect(status).to.equal(2); }); it('should show unsupported architecture warning', async () => { - const { status, stdout } = await runAxwaySync([], { shim: 'arch-shim-arm' }); + const { status, stdout } = await runAxwaySync([], { arch: 'arm' }); expect(status).to.equal(2); expect(stdout.toString()).to.match(renderRegexFromFile('help/unsupported-arch')); }); diff --git a/test/config/test-config.js b/test/config/test-config.js index e99d1580..7e03d1d4 100644 --- a/test/config/test-config.js +++ b/test/config/test-config.js @@ -1,9 +1,10 @@ +import { expect } from 'chai'; import { initHomeDir, renderRegexFromFile, resetHomeDir, runAxwaySync -} from '../helpers'; +} from '../helpers/index.js'; describe('axway config', () => { describe('help', () => { diff --git a/test/helpers/arch-shim-arm.js b/test/helpers/arch-shim-arm.js deleted file mode 100644 index e2fe97f4..00000000 --- a/test/helpers/arch-shim-arm.js +++ /dev/null @@ -1 +0,0 @@ -Object.defineProperty(process, 'arch', { value: 'arm' }); diff --git a/test/helpers/arch-shim-ia32.js b/test/helpers/arch-shim-ia32.js deleted file mode 100644 index 72751dc9..00000000 --- a/test/helpers/arch-shim-ia32.js +++ /dev/null @@ -1 +0,0 @@ -Object.defineProperty(process, 'arch', { value: 'ia32' }); diff --git a/test/helpers/arch-shim.js b/test/helpers/arch-shim.js new file mode 100644 index 00000000..60b0fe59 --- /dev/null +++ b/test/helpers/arch-shim.js @@ -0,0 +1,3 @@ +if (process.env.TEST_ARCH) { + Object.defineProperty(process, 'arch', { value: process.env.TEST_ARCH }); +} diff --git a/test/helpers/auth-routes.js b/test/helpers/auth-routes.js index 5d8968a1..4509f018 100644 --- a/test/helpers/auth-routes.js +++ b/test/helpers/auth-routes.js @@ -2,6 +2,9 @@ import fs from 'fs-extra'; import jws from 'jws'; import path from 'path'; import Router from '@koa/router'; +import { fileURLToPath } from 'url'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); export function createAuthRoutes(server, opts = {}) { const router = new Router(); @@ -25,13 +28,13 @@ export function createAuthRoutes(server, opts = {}) { state.accessToken = jws.sign({ header: { alg: 'HS256' }, - payload: { email }, + payload: { email, orgId: 100 }, secret: `access_secret` }); state.refreshToken = jws.sign({ header: { alg: 'HS256' }, - payload: { email }, + payload: { email, orgId: 100 }, secret: `refresh_secret` }); diff --git a/test/helpers/index.js b/test/helpers/index.js index c1cf581c..b1152a87 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -9,8 +9,9 @@ import path from 'path'; import Router from '@koa/router'; import session from 'koa-session'; import snooplogg from 'snooplogg'; -import { createAuthRoutes } from './auth-routes'; -import { createPlatformRoutes } from './platform-routes'; +import { createAuthRoutes } from './auth-routes.js'; +import { createPlatformRoutes } from './platform-routes.js'; +import { fileURLToPath } from 'url'; import { spawn } from 'child_process'; const logger = snooplogg.config({ @@ -21,7 +22,8 @@ const logger = snooplogg.config({ const { log } = logger; const { highlight } = snooplogg.styles; -const axwayBin = path.resolve(__dirname, `../../packages/axway-cli/${process.env.AXWAY_COVERAGE ? 'src' : 'dist'}/main.js`); +const __dirname = fileURLToPath(new URL('.', import.meta.url)); +const axwayBin = path.resolve(__dirname, `../../packages/axway-cli/dist/main.js`); export function initHomeDir(templateDir) { if (!fs.existsSync(templateDir) && !path.isAbsolute(templateDir)) { @@ -38,9 +40,10 @@ const defaultVars = { delta: '\\d+(\\.\\d+)?\\w( \\d+(\\.\\d+)?\\w)*\\s*', nodeDeprecationWarning: '(?:\n*\u001b\\[33m ┃ ATTENTION! The Node\\.js version you are currently using \\(v\\d+\\.\\d+\\.\\d+\\) has been\u001b\\[39m\n\u001b\\[33m ┃ deprecated and is unsupported in Axway CLI v3 and newer\\. Please upgrade\u001b\\[39m\n\u001b\\[33m ┃ Node\\.js to the latest LTS release: https://nodejs\\.org/\u001b\\[39m)?', nodeDeprecationWarningNoColor: '(?:\n* ┃ ATTENTION! The Node\\.js version you are currently using \\(v\\d+\\.\\d+\\.\\d+\\) has been\n ┃ deprecated and is unsupported in Axway CLI v3 and newer\\. Please upgrade\n ┃ Node\\.js to the latest LTS release: https://nodejs\\.org/)?', + nodeExperimentalWarning: '(?:\\(node:.+\\) ExperimentalWarning:.+\n\\(Use .+\\)\n)?', startRed: '(?:\u001b\\[31m)?', string: '[^\\s]+', - url: 'http[^\\s]+', + url: '(?:http[^\\s]+)', version: '(?:\\d+\\.\\d+\\.\\d+(?:-[^\\s]*)?\\s*)', versionList: '(?:\u001b\\[36m(?:\\d+\\.\\d+\\.\\d+(?:-[^\\s]*)?\\s*)*\\s*\u001b\\[39m\n+)+', versionWithColor: '(?:(?:\u001b\\[\\d\\dm)?\\d+(?:\\.(?:\u001b\\[\\d\\dm)?\\d+){2}(?:-[^\\s]*)?(?:\u001b\\[39m)?\\s*)', @@ -72,7 +75,7 @@ export function renderRegexFromFile(file, vars) { file += '.mustache'; } if (!fs.existsSync(file) && !path.isAbsolute(file)) { - file = path.resolve(path.dirname(callerPath()), file); + file = path.resolve(path.dirname(fileURLToPath(callerPath())), file); } return renderRegex(fs.readFileSync(file, 'utf8').trim(), vars); } @@ -98,7 +101,7 @@ function _runAxway(fn, args = [], opts = {}, cfg) { if (args.includes('--no-color') || args.includes('--no-colors')) { delete env.FORCE_COLOR; } - // delete env.SNOOPLOGG; + delete env.SNOOPLOGG; } if (cfg) { @@ -108,13 +111,13 @@ function _runAxway(fn, args = [], opts = {}, cfg) { args.unshift(axwayBin); if (opts.passiveOpen) { - args.unshift('--require', path.join(__dirname, 'open-shim-passive.js')); + args.unshift('--loader', path.join(__dirname, 'open-shim-passive.js')); } else { - args.unshift('--require', path.join(__dirname, 'open-shim.js')); + args.unshift('--loader', path.join(__dirname, 'open-shim.js')); } - if (opts.shim) { - args.unshift('--require', path.join(__dirname, `${opts.shim}.js`)); + if (opts.arch) { + env.TEST_ARCH = opts.arch; } log(`Executing: ${highlight(`${process.execPath} ${axwayBin} ${args.join(' ')}`)}`); diff --git a/test/helpers/open-shim-passive.js b/test/helpers/open-shim-passive.js index 07df7fe3..2f87b249 100644 --- a/test/helpers/open-shim-passive.js +++ b/test/helpers/open-shim-passive.js @@ -4,13 +4,17 @@ * fake the browser interaction. */ -const got = require('got'); -const Module = require('module'); +import './arch-shim.js'; -const origResolveFilename = Module._resolveFilename; -Module._resolveFilename = function (request, parent, isMain, options) { - return request === 'open' ? __filename : origResolveFilename(request, parent, isMain, options); -}; +export function resolve(specifier, context, defaultResolve) { + if (specifier === 'open') { + return { + url: import.meta.url + }; + } + return defaultResolve(specifier, context, defaultResolve); +} -// this is the passive version which will not simulate the browser being opened -module.exports = async () => {}; +export default async function shimmedPassiveOpen(url, opts) { + // do nothing +} diff --git a/test/helpers/open-shim.js b/test/helpers/open-shim.js index 578e6c6e..5b1ac8ad 100644 --- a/test/helpers/open-shim.js +++ b/test/helpers/open-shim.js @@ -4,27 +4,32 @@ * fake the browser interaction. */ -const got = require('got'); -const Module = require('module'); +import got from 'got'; +import './arch-shim.js'; -const origResolveFilename = Module._resolveFilename; -Module._resolveFilename = function (request, parent, isMain, options) { - return request === 'open' ? __filename : origResolveFilename(request, parent, isMain, options); -}; - -module.exports = async (url, opts) => { - const response = await got(url); - const parsedUrl = new URL(response.url); - let { hash, origin } = parsedUrl; - if (hash) { - hash = hash.replace(/^#/, ''); - if (!hash.startsWith('http')) { - hash = origin + hash; - } - const parsedHash = new URL(hash); - const redirect = parsedHash.searchParams.get('redirect'); - if (redirect) { - await got(redirect); - } +export function resolve(specifier, context, defaultResolve) { + if (specifier === 'open') { + return { + url: import.meta.url + }; } -}; + return defaultResolve(specifier, context, defaultResolve); +} + +export default async function shimmedOpen(url, opts) { + const response = await got(url); + const parsedUrl = new URL(response.url); + let { hash, origin } = parsedUrl; + if (hash) { + hash = hash.replace(/^#/, ''); + if (!hash.startsWith('http')) { + hash = origin + hash; + } + const parsedHash = new URL(hash); + const redirect = parsedHash.searchParams.get('redirect'); + if (redirect) { + await got(redirect); + } + } + } + \ No newline at end of file diff --git a/test/helpers/platform-routes.js b/test/helpers/platform-routes.js index fe9234ca..063ca7fb 100644 --- a/test/helpers/platform-routes.js +++ b/test/helpers/platform-routes.js @@ -2,8 +2,11 @@ import fs from 'fs'; import path from 'path'; import Router from '@koa/router'; import snooplogg from 'snooplogg'; +import { fileURLToPath } from 'url'; import { v4 as uuidv4 } from 'uuid'; +const __dirname = fileURLToPath(new URL('.', import.meta.url)); + const logger = snooplogg.config({ minBrightness: 80, maxBrightness: 210, diff --git a/test/helpers/report-styles/base.css b/test/helpers/report-styles/base.css new file mode 100644 index 00000000..9225f551 --- /dev/null +++ b/test/helpers/report-styles/base.css @@ -0,0 +1,227 @@ +body, html { + background-color: #272B33; + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#d5ddea; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#f9c858; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +div > span.strong { color: #ff9369; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #e5e5e5; +} + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + background: #3e4451; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { xborder-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { xborder: 1px solid #bbb; } +.coverage-summary td { xborder-right: 1px solid #bbb; } +.coverage-summary td:nth-child(1), +.coverage-summary td:nth-child(2) { background-color: #272B33;} +.coverage-summary td:last-child { xborder-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +.cbranch-no > span { color: #272B33; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#fc2e51 } +.low .chart { border:1px solid #fc2e51 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #fc2e51 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#c41e3b87 } +/* light red */ +.low { background-color: #fc2e51;} +.cline-no { background:#c41e3b87; } +/* light green */ +.high, .cline-yes { background:#25a45c; color: #333; } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:#25a45c } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; color: #333; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #22252c; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: #e5e5e5; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/test/helpers/report-styles/prettify.css b/test/helpers/report-styles/prettify.css new file mode 100644 index 00000000..354e0681 --- /dev/null +++ b/test/helpers/report-styles/prettify.css @@ -0,0 +1,19 @@ +/*! Color themes for Google Code Prettify | MIT License | github.com/jmblog/color-themes-for-google-code-prettify */ +.prettyprint{background:#2f3640;font-family:Menlo,Bitstream Vera Sans Mono,DejaVu Sans Mono,Monaco,Consolas,monospace;border:0!important} +.pln{color:#e6e9ed} +ol.linenums{margin-top:0;margin-bottom:0;color:#656d78} +li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{padding-left:1em;background-color:#2f3640;list-style-type:decimal} +.str{color:#ffce54} +.kwd{color:#4fc1e9} +.com{color:#656d78} +.typ{color:#4fc1e9} +.lit{color:#ac92ec} +.pun{color:#e6e9ed} +.opn{color:#e6e9ed} +.clo{color:#e6e9ed} +.tag{color:#ed5565} +.atn{color:#a0d468} +.atv{color:#ffce54} +.dec{color:#ac92ec} +.var{color:#e6e9ed} +.fun{color:#e6e9ed} diff --git a/test/org/activity/bad-from-date.mustache b/test/org/activity/bad-from-date.mustache index a465f757..c764bccc 100644 --- a/test/org/activity/bad-from-date.mustache +++ b/test/org/activity/bad-from-date.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Expected "from" date to be in the format YYYY-MM-DD{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Expected "from" date to be in the format YYYY-MM-DD{{/red}} diff --git a/test/org/activity/bad-to-date.mustache b/test/org/activity/bad-to-date.mustache index 3a9ebbfc..7853e629 100644 --- a/test/org/activity/bad-to-date.mustache +++ b/test/org/activity/bad-to-date.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Expected "to" date to be in the format YYYY-MM-DD{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Expected "to" date to be in the format YYYY-MM-DD{{/red}} diff --git a/test/org/activity/not-authenticated.mustache b/test/org/activity/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/org/activity/not-authenticated.mustache +++ b/test/org/activity/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/org/list/non-existent-account.mustache b/test/org/list/non-existent-account.mustache index 1d155c43..0b75cb37 100644 --- a/test/org/list/non-existent-account.mustache +++ b/test/org/list/non-existent-account.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Account "foo" not found{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Account "foo" not found{{/red}} diff --git a/test/org/list/not-authenticated.mustache b/test/org/list/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/org/list/not-authenticated.mustache +++ b/test/org/list/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/org/list/not-platform-account.mustache b/test/org/list/not-platform-account.mustache index 8f154948..0936e1b9 100644 --- a/test/org/list/not-platform-account.mustache +++ b/test/org/list/not-platform-account.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: Account "test_client:service@bar.com" is not a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Account "test_client:service@bar.com" is not a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/org/test-org.js b/test/org/test-org.js index c1c5d733..7f3937c9 100644 --- a/test/org/test-org.js +++ b/test/org/test-org.js @@ -1,3 +1,4 @@ +import { expect } from 'chai'; import { initHomeDir, renderRegexFromFile, @@ -5,7 +6,7 @@ import { runAxwaySync, startServers, stopServers -} from '../helpers'; +} from '../helpers/index.js'; describe('axway org', () => { describe('help', () => { @@ -68,7 +69,7 @@ describe('axway org', () => { "active": true, "childOrgs": null, "guid": "1000", - "id": 100, + "org_id": 100, "name": "Foo org", "entitlements": { "_a": 10, @@ -221,19 +222,19 @@ describe('axway org', () => { { "default": false, "guid": "2000", - "id": 200, + "org_id": 200, "name": "Bar org" }, { "default": false, "guid": "3000", - "id": 300, + "org_id": 300, "name": "Baz org" }, { "default": true, "guid": "1000", - "id": 100, + "org_id": 100, "name": "Foo org" } ] @@ -251,7 +252,7 @@ describe('axway org', () => { // }); - describe('usage', () => { + describe.skip('usage', () => { afterEach(stopServers); afterEach(resetHomeDir); diff --git a/test/org/usage/bad-org.mustache b/test/org/usage/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/org/usage/bad-org.mustache +++ b/test/org/usage/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/org/usage/not-authenticated.mustache b/test/org/usage/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/org/usage/not-authenticated.mustache +++ b/test/org/usage/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/pm/install/acs-installed.mustache b/test/pm/install/acs-installed.mustache index bc85031f..a57165e7 100644 --- a/test/pm/install/acs-installed.mustache +++ b/test/pm/install/acs-installed.mustache @@ -8,7 +8,6 @@ Registering {{#cyan}}acs@{{version}}{{/cyan}} Installed {{#cyan}}acs@{{version}}{{/cyan}} Installed {{#cyan}}acs@{{version}}{{/cyan}} [completed] -To use this new extension, run one of the following: +To use this new extension, run: {{#cyan}} axway acs{{/cyan}} -{{#cyan}} axway ack{{/cyan}} diff --git a/test/pm/purge/not-installed.mustache b/test/pm/purge/not-installed.mustache index 1e970ee5..5479fe7e 100644 --- a/test/pm/purge/not-installed.mustache +++ b/test/pm/purge/not-installed.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Package "acs" is not installed{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Package "acs" is not installed{{/red}} diff --git a/test/pm/test-pm.js b/test/pm/test-pm.js index f631b9fc..c125c1e9 100644 --- a/test/pm/test-pm.js +++ b/test/pm/test-pm.js @@ -1,8 +1,9 @@ +import { expect } from 'chai'; import { renderRegexFromFile, resetHomeDir, runAxwaySync -} from '../helpers'; +} from '../helpers/index.js'; describe('axway pm', () => { describe('help', () => { @@ -99,8 +100,8 @@ describe('axway pm', () => { this.slow(60000); let { status, stdout, stderr } = await runAxwaySync([ 'pm', 'install', 'acs' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('install/acs-installed')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'pm', 'list', '--json' ])); expect(status).to.equal(0); @@ -164,8 +165,8 @@ describe('axway pm', () => { this.slow(60000); let { status, stdout } = await runAxwaySync([ 'pm', 'install', 'acs' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('install/acs-installed')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'pm', 'list', '--json' ])); expect(status).to.equal(0); @@ -174,10 +175,10 @@ describe('axway pm', () => { expect(results[0].name).to.equal('acs'); ({ status, stdout } = await runAxwaySync([ 'pm', 'uninstall', 'acs' ])); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('uninstall/acs-uninstalled', { packagePath: results[0].versions[results[0].version].path.replace(/\\/g, '\\\\') })); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'pm', 'list', '--json' ])); expect(status).to.equal(0); @@ -186,9 +187,9 @@ describe('axway pm', () => { }); it('should error uninstalling a package that is not installed', async () => { - let { status, stderr } = await runAxwaySync([ 'pm', 'uninstall', 'acs' ]); - expect(status).to.equal(1); + const { status, stderr } = await runAxwaySync([ 'pm', 'uninstall', 'acs' ]); expect(stderr).to.match(renderRegexFromFile('uninstall/not-installed')); + expect(status).to.equal(1); }); it('should output uninstall help', async () => { @@ -252,14 +253,14 @@ describe('axway pm', () => { afterEach(resetHomeDir); it('should handle update a package', async function () { - this.timeout(120000); + this.timeout(180000); this.slow(60000); await runAxwaySync([ 'pm', 'install', 'acs@2.1.9' ]); let { status, stdout } = await runAxwaySync([ 'pm', 'update' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('update/updated-acs')); + expect(status).to.equal(0); ({ status, stdout } = await runAxwaySync([ 'pm', 'list', '--json' ])); expect(status).to.equal(0); @@ -291,8 +292,8 @@ describe('axway pm', () => { this.slow(60000); const { status, stderr } = await runAxwaySync([ 'pm', 'update', 'acs' ]); - expect(status).to.equal(1); expect(stderr).to.match(renderRegexFromFile('update/not-installed')); + expect(status).to.equal(1); }); it('should output update help', async () => { @@ -312,11 +313,11 @@ describe('axway pm', () => { await runAxwaySync([ 'pm', 'install', 'acs@2.1.9' ]); await runAxwaySync([ 'pm', 'install', 'acs@2.1.10' ]); - let { status, stdout } = await runAxwaySync([ 'pm', 'purge' ]); - expect(status).to.equal(0); + let { status, stdout, stderr } = await runAxwaySync([ 'pm', 'purge' ]); expect(stdout).to.match(renderRegexFromFile('purge/purged-219')); + expect(status).to.equal(0); - ({ status, stdout } = await runAxwaySync([ 'pm', 'list', '--json' ])); + ({ status, stdout, stderr } = await runAxwaySync([ 'pm', 'list', '--json' ])); expect(status).to.equal(0); let results = JSON.parse(stdout); expect(results).to.have.lengthOf(1); @@ -394,8 +395,8 @@ describe('axway pm', () => { it('should display info for a specific package version', async () => { const { status, stdout } = await runAxwaySync([ 'pm', 'view', 'acs@2.1.9' ]); - expect(status).to.equal(0); expect(stdout).to.match(renderRegexFromFile('view/acs-not-installed')); + expect(status).to.equal(0); }); it('should error if package is not found', async () => { diff --git a/test/pm/uninstall/not-installed.mustache b/test/pm/uninstall/not-installed.mustache index 1e970ee5..5479fe7e 100644 --- a/test/pm/uninstall/not-installed.mustache +++ b/test/pm/uninstall/not-installed.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Package "acs" is not installed{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Package "acs" is not installed{{/red}} diff --git a/test/pm/update/not-installed.mustache b/test/pm/update/not-installed.mustache index 1e970ee5..5479fe7e 100644 --- a/test/pm/update/not-installed.mustache +++ b/test/pm/update/not-installed.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Package "acs" is not installed{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Package "acs" is not installed{{/red}} diff --git a/test/pm/update/updated-acs.mustache b/test/pm/update/updated-acs.mustache index 2337e1dd..34c58bb0 100644 --- a/test/pm/update/updated-acs.mustache +++ b/test/pm/update/updated-acs.mustache @@ -14,6 +14,6 @@ Registering {{#cyan}}acs@{{version}}{{/cyan}} The following package versions can be purged: - {{#bold}}acs{{/bold}} 2.1.9 + {{#bold}}acs{{/bold}} {{version}} To purge these unused packages, run: {{#cyan}}axway pm purge{{/cyan}} diff --git a/test/pm/use/acs-2110-not-installed.mustache b/test/pm/use/acs-2110-not-installed.mustache index 8bae00bf..70be743b 100644 --- a/test/pm/use/acs-2110-not-installed.mustache +++ b/test/pm/use/acs-2110-not-installed.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: Package "acs@2.1.10" is not installed{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Package "acs@2.1.10" is not installed{{/red}} {{#red}}Please run {{#cyan}}"axway pm install acs@2.1.10"{{/cyan}}{{startRed}} to install it{{/red}} diff --git a/test/pm/use/not-found.mustache b/test/pm/use/not-found.mustache index 3aa0a5e0..c72e7ac9 100644 --- a/test/pm/use/not-found.mustache +++ b/test/pm/use/not-found.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: Package "abcdef" is not installed{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Package "abcdef" is not installed{{/red}} {{#red}}Please run {{#cyan}}"axway pm install abcdef"{{/cyan}}{{startRed}} to install it{{/red}} diff --git a/test/pm/view/acs-installed.mustache b/test/pm/view/acs-installed.mustache index a820ad9a..55d052e3 100644 --- a/test/pm/view/acs-installed.mustache +++ b/test/pm/view/acs-installed.mustache @@ -6,5 +6,6 @@ Appcelerator Server Side Node AVAILABLE VERSIONS: {{versionList}} -INSTALLED VERSIONS: -{{versionList}} +To install this package, run: + + {{#cyan}}axway pm install acs{{/cyan}} \ No newline at end of file diff --git a/test/pm/view/not-found.mustache b/test/pm/view/not-found.mustache index 06ad46de..38e78348 100644 --- a/test/pm/view/not-found.mustache +++ b/test/pm/view/not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Package "abcdef" not found{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Package "abcdef" not found{{/red}} diff --git a/test/service-account/add-team/bad-org.mustache b/test/service-account/add-team/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/add-team/bad-org.mustache +++ b/test/service-account/add-team/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/add-team/invalid-role.mustache b/test/service-account/add-team/invalid-role.mustache index 211f4954..6ea8af78 100644 --- a/test/service-account/add-team/invalid-role.mustache +++ b/test/service-account/add-team/invalid-role.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Invalid team role "bar"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Invalid team role "bar"{{/red}} diff --git a/test/service-account/add-team/missing-id.mustache b/test/service-account/add-team/missing-id.mustache index 2d8e747d..0074fc76 100644 --- a/test/service-account/add-team/missing-id.mustache +++ b/test/service-account/add-team/missing-id.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Missing required argument "client-id"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Missing required argument "client-id"{{/red}} diff --git a/test/service-account/add-team/missing-role.mustache b/test/service-account/add-team/missing-role.mustache index 6e1aa4bc..9e97b5f8 100644 --- a/test/service-account/add-team/missing-role.mustache +++ b/test/service-account/add-team/missing-role.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Missing required argument "role"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Missing required argument "role"{{/red}} diff --git a/test/service-account/add-team/missing-team.mustache b/test/service-account/add-team/missing-team.mustache index de0d41ff..13736a37 100644 --- a/test/service-account/add-team/missing-team.mustache +++ b/test/service-account/add-team/missing-team.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Missing required argument "team-guid"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Missing required argument "team-guid"{{/red}} diff --git a/test/service-account/add-team/not-authenticated.mustache b/test/service-account/add-team/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/service-account/add-team/not-authenticated.mustache +++ b/test/service-account/add-team/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/service-account/add-team/service-account-not-found.mustache b/test/service-account/add-team/service-account-not-found.mustache index ed5b037f..9d192702 100644 --- a/test/service-account/add-team/service-account-not-found.mustache +++ b/test/service-account/add-team/service-account-not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} diff --git a/test/service-account/add-team/team-not-found.mustache b/test/service-account/add-team/team-not-found.mustache index 4e97c620..f9d93656 100644 --- a/test/service-account/add-team/team-not-found.mustache +++ b/test/service-account/add-team/team-not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find team "foo" in the "Foo org" organization{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find team "foo" in the "Foo org" organization{{/red}} diff --git a/test/service-account/create/bad-org.mustache b/test/service-account/create/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/create/bad-org.mustache +++ b/test/service-account/create/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/create/bad-public-key.mustache b/test/service-account/create/bad-public-key.mustache index deeb40d8..f178be8e 100644 --- a/test/service-account/create/bad-public-key.mustache +++ b/test/service-account/create/bad-public-key.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Public key {{string}} is not a PEM formatted file{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Public key {{string}} is not a PEM formatted file{{/red}} diff --git a/test/service-account/create/no-auth-method.mustache b/test/service-account/create/no-auth-method.mustache index 5e058a27..69c66400 100644 --- a/test/service-account/create/no-auth-method.mustache +++ b/test/service-account/create/no-auth-method.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Missing required --secret or --public-key {{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Missing required --secret or --public-key {{/red}} diff --git a/test/service-account/create/public-key-not-a-file.mustache b/test/service-account/create/public-key-not-a-file.mustache index 350d1a1d..06b510a2 100644 --- a/test/service-account/create/public-key-not-a-file.mustache +++ b/test/service-account/create/public-key-not-a-file.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Public key {{string}} is not a file{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Public key {{string}} is not a file{{/red}} diff --git a/test/service-account/create/public-key-not-found.mustache b/test/service-account/create/public-key-not-found.mustache index 94e3ccbf..edeebe0f 100644 --- a/test/service-account/create/public-key-not-found.mustache +++ b/test/service-account/create/public-key-not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Public key {{string}} does not exist{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Public key {{string}} does not exist{{/red}} diff --git a/test/service-account/list/bad-org.mustache b/test/service-account/list/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/list/bad-org.mustache +++ b/test/service-account/list/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/list/not-authenticated.mustache b/test/service-account/list/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/service-account/list/not-authenticated.mustache +++ b/test/service-account/list/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/service-account/remove-team/bad-org.mustache b/test/service-account/remove-team/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/remove-team/bad-org.mustache +++ b/test/service-account/remove-team/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/remove-team/missing-id.mustache b/test/service-account/remove-team/missing-id.mustache index 2d8e747d..0074fc76 100644 --- a/test/service-account/remove-team/missing-id.mustache +++ b/test/service-account/remove-team/missing-id.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Missing required argument "client-id"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Missing required argument "client-id"{{/red}} diff --git a/test/service-account/remove-team/missing-team.mustache b/test/service-account/remove-team/missing-team.mustache index de0d41ff..13736a37 100644 --- a/test/service-account/remove-team/missing-team.mustache +++ b/test/service-account/remove-team/missing-team.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Missing required argument "team-guid"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Missing required argument "team-guid"{{/red}} diff --git a/test/service-account/remove-team/not-authenticated.mustache b/test/service-account/remove-team/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/service-account/remove-team/not-authenticated.mustache +++ b/test/service-account/remove-team/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/service-account/remove-team/service-account-not-found.mustache b/test/service-account/remove-team/service-account-not-found.mustache index ed5b037f..9d192702 100644 --- a/test/service-account/remove-team/service-account-not-found.mustache +++ b/test/service-account/remove-team/service-account-not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} diff --git a/test/service-account/remove-team/team-not-found.mustache b/test/service-account/remove-team/team-not-found.mustache index 4e97c620..f9d93656 100644 --- a/test/service-account/remove-team/team-not-found.mustache +++ b/test/service-account/remove-team/team-not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find team "foo" in the "Foo org" organization{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find team "foo" in the "Foo org" organization{{/red}} diff --git a/test/service-account/remove/bad-org.mustache b/test/service-account/remove/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/remove/bad-org.mustache +++ b/test/service-account/remove/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/remove/not-authenticated.mustache b/test/service-account/remove/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/service-account/remove/not-authenticated.mustache +++ b/test/service-account/remove/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/service-account/remove/not-found.mustache b/test/service-account/remove/not-found.mustache index ed5b037f..9d192702 100644 --- a/test/service-account/remove/not-found.mustache +++ b/test/service-account/remove/not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} diff --git a/test/service-account/roles/bad-org.mustache b/test/service-account/roles/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/roles/bad-org.mustache +++ b/test/service-account/roles/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/roles/not-authenticated.mustache b/test/service-account/roles/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/service-account/roles/not-authenticated.mustache +++ b/test/service-account/roles/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/service-account/test-service-account.js b/test/service-account/test-service-account.js index 496ab979..468c9f0d 100644 --- a/test/service-account/test-service-account.js +++ b/test/service-account/test-service-account.js @@ -1,3 +1,8 @@ +import fs from 'fs-extra'; +import path from 'path'; +import tmp from 'tmp'; +import { expect } from 'chai'; +import { fileURLToPath } from 'url'; import { initHomeDir, renderRegexFromFile, @@ -5,10 +10,9 @@ import { runAxwaySync, startServers, stopServers -} from '../helpers'; -import fs from 'fs-extra'; -import path from 'path'; -import tmp from 'tmp'; +} from '../helpers/index.js'; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); tmp.setGracefulCleanup(); diff --git a/test/service-account/update/bad-org.mustache b/test/service-account/update/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/update/bad-org.mustache +++ b/test/service-account/update/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/update/bad-public-key.mustache b/test/service-account/update/bad-public-key.mustache index deeb40d8..f178be8e 100644 --- a/test/service-account/update/bad-public-key.mustache +++ b/test/service-account/update/bad-public-key.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Public key {{string}} is not a PEM formatted file{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Public key {{string}} is not a PEM formatted file{{/red}} diff --git a/test/service-account/update/change-auth-method.mustache b/test/service-account/update/change-auth-method.mustache index 2b6e8335..079be6b7 100644 --- a/test/service-account/update/change-auth-method.mustache +++ b/test/service-account/update/change-auth-method.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Service account "Test" uses auth method "Client Secret" and cannot be changed to "Client Certificate"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Service account "Test" uses auth method "Client Secret" and cannot be changed to "Client Certificate"{{/red}} diff --git a/test/service-account/update/not-authenticated.mustache b/test/service-account/update/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/service-account/update/not-authenticated.mustache +++ b/test/service-account/update/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/service-account/update/not-found.mustache b/test/service-account/update/not-found.mustache index ed5b037f..9d192702 100644 --- a/test/service-account/update/not-found.mustache +++ b/test/service-account/update/not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} diff --git a/test/service-account/update/public-key-not-a-file.mustache b/test/service-account/update/public-key-not-a-file.mustache index 350d1a1d..06b510a2 100644 --- a/test/service-account/update/public-key-not-a-file.mustache +++ b/test/service-account/update/public-key-not-a-file.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Public key {{string}} is not a file{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Public key {{string}} is not a file{{/red}} diff --git a/test/service-account/update/public-key-not-found.mustache b/test/service-account/update/public-key-not-found.mustache index 94e3ccbf..edeebe0f 100644 --- a/test/service-account/update/public-key-not-found.mustache +++ b/test/service-account/update/public-key-not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Public key {{string}} does not exist{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Public key {{string}} does not exist{{/red}} diff --git a/test/service-account/view/bad-org.mustache b/test/service-account/view/bad-org.mustache index 44a1a5da..1b448824 100644 --- a/test/service-account/view/bad-org.mustache +++ b/test/service-account/view/bad-org.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Unable to find the organization "does_not_exist"{{/red}} diff --git a/test/service-account/view/not-authenticated.mustache b/test/service-account/view/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/service-account/view/not-authenticated.mustache +++ b/test/service-account/view/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/service-account/view/not-found.mustache b/test/service-account/view/not-found.mustache index ed5b037f..9d192702 100644 --- a/test/service-account/view/not-found.mustache +++ b/test/service-account/view/not-found.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Service account "does_not_exist" not found{{/red}} diff --git a/test/setup.js b/test/setup.js new file mode 100644 index 00000000..afa57345 --- /dev/null +++ b/test/setup.js @@ -0,0 +1,3 @@ +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +chai.use(chaiAsPromised); diff --git a/test/team/test-team.js b/test/team/test-team.js index 5b0e20b7..b4ff9899 100644 --- a/test/team/test-team.js +++ b/test/team/test-team.js @@ -1,3 +1,4 @@ +import { expect } from 'chai'; import { initHomeDir, renderRegexFromFile, @@ -5,7 +6,7 @@ import { runAxwaySync, startServers, stopServers -} from '../helpers'; +} from '../helpers/index.js'; describe('axway team', () => { describe('help', () => { diff --git a/test/team/user/add/not_authenticated.mustache b/test/team/user/add/not_authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/team/user/add/not_authenticated.mustache +++ b/test/team/user/add/not_authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/user/activity/bad-from-date.mustache b/test/user/activity/bad-from-date.mustache index a465f757..c764bccc 100644 --- a/test/user/activity/bad-from-date.mustache +++ b/test/user/activity/bad-from-date.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Expected "from" date to be in the format YYYY-MM-DD{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Expected "from" date to be in the format YYYY-MM-DD{{/red}} diff --git a/test/user/activity/bad-to-date.mustache b/test/user/activity/bad-to-date.mustache index 3a9ebbfc..7853e629 100644 --- a/test/user/activity/bad-to-date.mustache +++ b/test/user/activity/bad-to-date.mustache @@ -1 +1 @@ -{{#red}}{{x}} Error: Expected "to" date to be in the format YYYY-MM-DD{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: Expected "to" date to be in the format YYYY-MM-DD{{/red}} diff --git a/test/user/activity/not-authenticated.mustache b/test/user/activity/not-authenticated.mustache index 2d163735..7a8efe6b 100644 --- a/test/user/activity/not-authenticated.mustache +++ b/test/user/activity/not-authenticated.mustache @@ -1,3 +1,3 @@ -{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} +{{{nodeExperimentalWarning}}}{{#red}}{{x}} Error: You must be logged into a platform account{{/red}} {{#red}}To login, run: axway auth login{{/red}} diff --git a/test/user/test-user.js b/test/user/test-user.js index 550b96d2..fcd24469 100644 --- a/test/user/test-user.js +++ b/test/user/test-user.js @@ -1,3 +1,4 @@ +import { expect } from 'chai'; import { initHomeDir, renderRegexFromFile, @@ -5,7 +6,7 @@ import { runAxwaySync, startServers, stopServers -} from '../helpers'; +} from '../helpers/index.js'; describe('axway user', () => { describe('help', () => { @@ -132,18 +133,18 @@ describe('axway user', () => { await runAxwaySync([ 'auth', 'login' ], { env: { DISPLAY: 1 } }); let { status, stdout, stderr } = await runAxwaySync([ 'user', 'activity', '--from', 'foo' ]); - expect(status).to.equal(1); expect(stderr.toString()).to.match(renderRegexFromFile('activity/bad-from-date')); + expect(status).to.equal(1); ({ status, stderr } = await runAxwaySync([ 'user', 'activity', '--to', 'bar' ])); - expect(status).to.equal(1); expect(stderr.toString()).to.match(renderRegexFromFile('activity/bad-to-date')); + expect(status).to.equal(1); }); it('should output activity help', async () => { const { status, stdout } = await runAxwaySync([ 'user', 'activity', '--help' ]); - expect(status).to.equal(2); expect(stdout.toString()).to.match(renderRegexFromFile('activity/help')); + expect(status).to.equal(2); }); }); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..ff725b66 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "allowJs": true, + "allowSyntheticDefaultImports": true, + "declaration": true, + "esModuleInterop": true, + "isolatedModules": true, + "lib": [ + "ES2019" + ], + "module": "esnext", + "moduleResolution": "node", + "sourceMap": true, + "strict": true, + "target": "ES2019", + "typeRoots": [ + "./node_modules/@types", + "./node_modules/http-proxy-agent/dist", + "./node_modules/https-proxy-agent/dist", + "./types" + ] + }, + "exclude": [ "node_modules" ] +} diff --git a/turbo.json b/turbo.json new file mode 100644 index 00000000..d7c8864a --- /dev/null +++ b/turbo.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://turborepo.org/schema.json", + "baseBranch": "origin/master", + "pipeline": { + "build": { + "dependsOn": [ "^build" ], + "outputs": [ "dist/**" ] + }, + "test": { + "dependsOn": [ "^build" ], + "outputs": [] + } + } +} diff --git a/types/check-kit/index.d.ts b/types/check-kit/index.d.ts new file mode 100644 index 00000000..7e3d7023 --- /dev/null +++ b/types/check-kit/index.d.ts @@ -0,0 +1,38 @@ +declare module 'check-kit' { + class RequestTimeout { + request: number; + } + + class CheckKitOptions { + applyOwner?: boolean; + caFile?: Buffer | string; + certFile?: Buffer | string; + checkInterval?: number; + cwd?: string; + distTag?: string; + force?: boolean; + keyFile?: string; + metaDir: string; + pkg: string | any; + proxy?: string; + registryUrl?: string; + strictSSL?: boolean; + timeout?: RequestTimeout | number; + } + + class CheckKitResults { + current: string; + latest: string; + name: string; + updateAvailable: boolean; + } + + function check(opts: CheckKitOptions): Promise; + + export default check; + + export type { + CheckKitOptions, + CheckKitResults + }; +} diff --git a/types/cli-kit/index.d.ts b/types/cli-kit/index.d.ts new file mode 100644 index 00000000..257ffb31 --- /dev/null +++ b/types/cli-kit/index.d.ts @@ -0,0 +1,211 @@ +declare module 'cli-kit' { + import tty from 'tty'; + + class CLI extends CLIContext { + constructor(opts: CLIOptions); + exec(): Promise; + on(event: string, handler: (ctx: CLIState, next: CLINextIterator) => Promise): Promise; + } + + class CLIArgument { + redact?: boolean; + } + + class CLIArgv { + [key: string]: boolean | number | string | string[]; + } + + type CLIBannerCallback = (state: CLIState) => string; + type CLIBannerAsyncCallback = (state: CLIState) => Promise; + + class CLICommand extends CLIContext { + parent: CLICommand; + prop: (key: string) => string | boolean | CLIBannerCallback | CLIBannerAsyncCallback; + skipExtensionUpdateCheck?: boolean; // this is an ad-hoc Axway CLI specific property + } + + class CLIContext { + desc?: string; + emitAction(event: string, payload: any): Promise; + name: string; + [key: string]: any; + } + + class CLIError extends Error { + showHelp: boolean; + } + + class CLIHelpConfig { + footer: (this: CLIContext, helpOpts?: CLIHelpOptions) => Promise | string; + header: (this: CLIContext, helpOpts?: CLIHelpOptions) => Promise | string; + } + + class CLIHelpOptions { + style: { + alert: (s?: string | number) => string, + bold: (s?: string | number) => string, + cyan: (s?: string | number) => string, + gray: (s?: string | number) => string, + green: (s?: string | number) => string + heading: (s?: string | number) => string, + highlight: (s?: string | number) => string, + magenta: (s?: string | number) => string, + note: (s?: string | number) => string, + ok: (s?: string | number) => string, + red: (s?: string | number) => string, + yellow: (s?: string | number) => string + } + } + + type CLINextIterator = () => Promise; + + class CLIOption { + hidden?: boolean; + isFlag?: boolean; + redact?: boolean; + } + + class CLIOptions { + banner: CLIBannerCallback; + commands: string; + desc: string; + extensions: string[]; + help: CLIHelpConfig | boolean; + helpExitCode: number; + helpTemplateFile: string; + name: string; + options: CLIOptionsMap; + version: string; + } + + class CLIOptionsMap { + [key: string]: CLIOption; + } + + class CLIOptionCallbackState { + ctx: CLIContext; + data: any; + exitCode: (code?: number) => number; + input: string[]; + name: string; + next: CLINextIterator; + opts: CLIOptionsMap; + option: CLIOption; + parser: CLIParser; + value: string | number | boolean | undefined; + } + + class CLIParser { + // + } + + class CLIParsedArgument { + arg: CLIArgument; + input: string[]; + option: CLIOption; + type: string; + } + + class CLIState { + __argv: CLIParsedArgument[]; + argv: CLIArgv; + cli: CLI; + cmd: CLICommand; + console: Console; + contexts: CLIContext[]; + ctx: CLIContext; + err?: Error; + exitCode: (code?: number) => number; + help: () => Promise; + setExitCode: (code: number) => number; + terminal: CLITerminal; + warnings: string[]; + } + + class CLITerminal { + stdout: tty.WriteStream; + stderr: tty.WriteStream; + once(event: string, handler: (...args: any) => void): this; + } + + class Extension { + exports: { + [cmd: string]: CLICommand + }; + constructor(path: string); + } + + const ansi: { + bel: string, + clear: string, + cursor: { + show: string, + hide: string, + save: string, + restore: string, + get: string, + home: string, + left: string, + + down(n: number): string, + up(n: number): string, + + backward(n: number): string, + forward(n: number): string, + + move(dx: number, dy: number): string, + to(x: number, y: number): string, + + position: string, + + next(n: number): string, + prev(n: number): string + }, + custom: { + echo(enabled: boolean): string, + exec(command: string): string, + exit(code: number): string, + keypress(key: string): string + }, + erase: { + down: string, + line: string, + lines(count: number): string, + screen: string, + toEnd: string, + toStart: string, + up: string + }, + scroll: { + down: string, + up: string + }, + link(text: string, url: string): string, + split(str: string): string[], + strip(str: string): string, + toLowerCase(str: string): string, + toUpperCase(str: string): string, + trim(str: string): string, + trimStart(str: string): string, + trimEnd(str: string): string + }; + + export default CLI; + export { + ansi, + CLI, + Extension + }; + + export type { + CLIBannerCallback, + CLICommand, + CLIContext, + CLIError, + CLIHelpOptions, + CLINextIterator, + CLIOptionCallbackState, + CLIParsedArgument, + CLIState + }; +} diff --git a/types/config-kit/index.d.ts b/types/config-kit/index.d.ts new file mode 100644 index 00000000..90ce0f32 --- /dev/null +++ b/types/config-kit/index.d.ts @@ -0,0 +1,23 @@ +interface ConfigOptions { + data?: {}, + file?: string +} + +declare class Config { + static Base: string; + + data(key: string): any; + delete(key: string, id?: string | Symbol): boolean; + get(key?: string, defaultValue?: any): any; + init(opts?: ConfigOptions): Promise; + pop(key: string, id?: string): Promise; + push(key: string, value: any, id?: string | Symbol): Promise; + set(key: string, value: any, id?: string | Symbol): Promise; + shift(key: string, id?: string | Symbol): Promise; + save(): Promise; + unshift(key: string, value: any, id?: string | Symbol): Promise; +} + +declare module 'config-kit' { + export = Config; +} diff --git a/types/snooplogg/index.d.ts b/types/snooplogg/index.d.ts new file mode 100644 index 00000000..c1865601 --- /dev/null +++ b/types/snooplogg/index.d.ts @@ -0,0 +1,184 @@ +declare module 'snooplogg' { + import { Transform, Writable } from 'stream'; + + class Functionator extends Function { + constructor(fn: any); + } + + class Logger extends Functionator { + error: (s: any) => void; + log: (s: any) => void; + warn: (s: any) => void; + + constructor(namespace: string, parent?: Logger, root?: SnoopLogg, style?: string); + + get console(): Console; + + createStream({ fd, type }?: { + fd: number; + type: string; + }): StdioDispatcher; + + get enabled(): boolean; + + get namespace(): string | null; + } + + class SnoopLogg extends Logger { + chalk: { + bold: (s?: string) => string, + cyan: (s?: string) => string, + gray: (s?: string) => string, + green: (s?: string) => string, + red: (s?: string) => string, + yellow: (s?: string) => string + }; + + styles: { + alert: (s?: string | number) => string, + bold: (s?: string | number) => string, + cyan: (s?: string | number) => string, + gray: (s?: string | number) => string, + green: (s?: string | number) => string + highlight: (s?: string | number) => string, + note: (s?: string | number) => string, + ok: (s?: string | number) => string, + red: (s?: string | number) => string, + yellow: (s?: string | number) => string, + [key: string]: (s?: string | number) => string + }; + + constructor(opts: any); + + applyStyle(style: string, text: any): string; + + /** + * Allows settings to be changed. + * + * @param {Object} [opts] - Various options. + * @param {String|Array.} [opts.colors] - An array or comma-separated list of colors to + * choose from when auto-styling. + * @param {Object} [opts.inspectOptions] - Options to pass into `util.inspect()` when + * stringifying objects. Set to `null` to stringify objects using Node's `util.format()`. + * @param {Number} [opts.maxBufferSize] - The max buffer size. + * @returns {SnoopLogg} + * @access public + */ + config(opts?: {}): this; + + /** + * Dispatches a message object through the middlewares, filters, and eventually to all output + * streams. + * + * @param {Object} msg - A message object. + * @param {Array} msg.args - An array of zero or more arguments that will be formatted into the + * final log message. + * @access public + */ + dispatch(msg: any): void; + + enable(pattern?: string): this; + + isEnabled(namespace: string): boolean; + + ns(namespace: string): Logger; + + /** + * Adds a stream to pipe log messages to. + * + * @param {stream.Writable} stream - The stream to pipe messages to. + * @param {Object} [opts] - Various options. + * @param {Boolean} [opts.flush=false] - When true, immediately flushes the buffer of log + * messages to the stream. + * @param {String} [opts.theme] - The theme to apply to all messages written to this stream. + * @returns {SnoopLogg} + * @access public + */ + pipe(stream: Writable, opts?: {}): this; + + snoop(nsPrefix?: string): this; + + get stdio(): this; + + /** + * Registers a function that applies a style to a message. + * + * @param {String} name - The name of the style. + * @param {Function} fn - A function to call that applies the style. + * @returns {SnoopLogg} + * @access public + */ + style(name: string, fn: any): this; + + /** + * Registers a function that applies a theme to a message. + * + * @param {String} name - The name of the theme. + * @param {Function} fn - A function to call that applies the theme. + * @returns {SnoopLogg} + * @access public + */ + theme(name: string, fn: any): this; + + /** + * Registers a new log type. + * + * @param {String} name - The log type name. + * @param {Object} [opts] - Various options. + * @param {String} [opts.style] - The color to associate with this type. + * @param {String} [opts.label] - The label to display when print this type of log message. + * @param {Number} [opts.fd] - The file descriptor. Use `0` for stdout and `1` for stderr. + * @returns {SnoopLogg} + * @access public + */ + type(name: string, opts?: {}): this; + + unpipe(stream: Writable): this; + + unsnoop(): this; + + /** + * Adds a middleware function to the message dispatching system. + * + * @param {Function} middleware - A middleware function to add to the list. + * @param {Number} [priority=0] - The middleware priority. Negative priority is run before + * positive values. + * @returns {SnoopLogg} + * @access public + */ + use(middleware: any, priority?: number): this; + } + + class StripColors extends Transform { + constructor(opts?: {}); + _transform(msg: any, enc: any, cb: any): void; + } + + class Format extends Transform { + constructor(opts?: {}); + _transform(msg: any, enc: any, cb: any): void; + } + + class StdioStream extends Writable { + constructor(opts?: {}); + _write(msg: any, enc: any, cb: any): void; + } + + class StdioDispatcher extends Writable { + constructor(logger: any, params: any); + _write(data: any, enc: any, cb: any): void; + } + + function createInstanceWithDefaults(): SnoopLogg; + const instance: SnoopLogg; + + export default instance; + export { + createInstanceWithDefaults, + Format, + Logger, + SnoopLogg, + StdioStream, + StripColors + }; +} diff --git a/yarn.lock b/yarn.lock index ccd003f0..204138ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,331 +2,57 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== - dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@axway/amplify-request@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@axway/amplify-request/-/amplify-request-2.1.4.tgz#b1ac20bfad0fe9e8fac32af83af98672c3dbb460" - integrity sha512-AfpeGvb5f4MvrxIbMoUbpj18ybkDzqy7sPu45RK6Af4KEerjWjsNXcE+LKxszawdoIMgcaNhkQL7sHGKMlFxog== +"@babel/code-frame@^7.0.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: - appcd-util "^3.1.6" - got "^11.8.2" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - pretty-bytes "^5.6.0" - snooplogg "^3.0.2" - source-map-support "^0.5.19" + "@babel/highlight" "^7.18.6" -"@axway/gulp-tasks@^4.1.4": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@axway/gulp-tasks/-/gulp-tasks-4.1.4.tgz#713be266713f3c85b0e94aef21d3ce427f36e485" - integrity sha512-84/fwqnUUNkJ9bWCtxw76kszcRdgEH9KbAr3FjqhNwI+Jzs7/x+wxNmgTIKmPMc7wjijmQgGlH6t8JDDDA3YBQ== - dependencies: - "@babel/core" "^7.17.2" - "@babel/eslint-parser" "^7.17.0" - "@babel/eslint-plugin" "^7.16.5" - "@babel/plugin-proposal-optional-chaining" "^7.16.7" - "@babel/plugin-transform-modules-commonjs" "^7.16.8" - "@babel/register" "^7.17.0" - ansi-colors "^4.1.1" - babel-plugin-dynamic-import-node "^2.3.3" - chai "^4.3.6" - chai-as-promised "^7.1.1" - core-js "^3.21.0" - esdoc "^1.1.0" - esdoc-ecmascript-proposal-plugin "^1.0.0" - esdoc-standard-plugin "^1.0.0" - eslint "^7.32.0" - eslint-config-axway "^6.0.2" - eslint-plugin-chai-friendly "^0.7.2" - eslint-plugin-mocha "^9.0.0" - eslint-plugin-node "^11.1.0" - fancy-log "^2.0.0" - fs-extra "^10.0.0" - gulp "^4.0.2" - gulp-babel "^8.0.0" - gulp-debug "^4.0.0" - gulp-eslint "^6.0.0" - gulp-load-plugins "^2.0.7" - gulp-plumber "^1.2.1" - gulp-sourcemaps "^3.0.0" - mocha "^9.2.0" - mocha-jenkins-reporter "^0.4.7" - nyc "^15.1.0" - sinon "^11.1.2" - sinon-chai "^3.7.0" - -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - -"@babel/compat-data@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" - integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== - -"@babel/core@^7.17.2", "@babel/core@^7.7.5": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.10.tgz#74ef0fbf56b7dfc3f198fc2d927f4f03e12f4b05" - integrity sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.10" - "@babel/helper-compilation-targets" "^7.17.10" - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helpers" "^7.17.9" - "@babel/parser" "^7.17.10" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.10" - "@babel/types" "^7.17.10" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== -"@babel/eslint-parser@^7.17.0": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz#eabb24ad9f0afa80e5849f8240d0e5facc2d90d6" - integrity sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA== +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== dependencies: - eslint-scope "^5.1.1" - eslint-visitor-keys "^2.1.0" - semver "^6.3.0" - -"@babel/eslint-plugin@^7.16.5": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.17.7.tgz#4ee1d5b29b79130f3bb5a933358376bcbee172b8" - integrity sha512-JATUoJJXSgwI0T8juxWYtK1JSgoLpIGUsCHIv+NMXcUDA2vIe6nvAHR9vnuJgs/P1hOFw7vPwibixzfqBBLIVw== - dependencies: - eslint-rule-composer "^0.3.0" - -"@babel/generator@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.10.tgz#c281fa35b0c349bbe9d02916f4ae08fc85ed7189" - integrity sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg== - dependencies: - "@babel/types" "^7.17.10" - "@jridgewell/gen-mapping" "^0.1.0" - jsesc "^2.5.1" - -"@babel/helper-compilation-targets@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz#09c63106d47af93cf31803db6bc49fef354e2ebe" - integrity sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ== - dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.20.2" - semver "^6.3.0" - -"@babel/helper-environment-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" - integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-function-name@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" - integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== - dependencies: - "@babel/template" "^7.16.7" - "@babel/types" "^7.17.0" - -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-transforms@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" - integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" - -"@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" - integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== - -"@babel/helper-simple-access@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" - integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== - dependencies: - "@babel/types" "^7.17.0" - -"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" - integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - -"@babel/helpers@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" - integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - -"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" - integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-validator-identifier" "^7.18.6" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.16.7", "@babel/parser@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" - integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== - -"@babel/plugin-proposal-optional-chaining@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" - integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-transform-modules-commonjs@^7.16.8": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz#274be1a2087beec0254d4abd4d86e52442e1e5b6" - integrity sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw== - dependencies: - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/register@^7.17.0": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.17.7.tgz#5eef3e0f4afc07e25e847720e7b987ae33f08d0b" - integrity sha512-fg56SwvXRifootQEDQAu1mKdjh5uthPzdO0N6t358FktfL4XjAVXuH58ULoiW8mesxiOgNIrxiImqEwv0+hRRA== - dependencies: - clone-deep "^4.0.1" - find-cache-dir "^2.0.0" - make-dir "^2.1.0" - pirates "^4.0.5" - source-map-support "^0.5.16" - -"@babel/template@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/traverse@^7.17.10", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.10.tgz#1ee1a5ac39f4eac844e6cf855b35520e5eb6f8b5" - integrity sha512-VmbrTHQteIdUUQNTb+zE12SHS/xQVIShmBPhlNP12hD5poF2pbITW1Z4172d03HegaQWhLffdkRJYtAzp0AGcw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.10" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.10" - "@babel/types" "^7.17.10" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.17.10": - version "7.17.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4" - integrity sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@eslint/eslintrc@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" + integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" + debug "^4.3.2" + espree "^9.3.2" + globals "^13.15.0" + ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" + js-yaml "^4.1.0" + minimatch "^3.1.2" strip-json-comments "^3.1.1" "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": @@ -334,25 +60,6 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@gulp-sourcemaps/identity-map@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz#a6e8b1abec8f790ec6be2b8c500e6e68037c0019" - integrity sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q== - dependencies: - acorn "^6.4.1" - normalize-path "^3.0.0" - postcss "^7.0.16" - source-map "^0.6.0" - through2 "^3.0.1" - -"@gulp-sourcemaps/map-sources@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz#890ae7c5d8c877f6d384860215ace9d7ec945bda" - integrity sha1-iQrnxdjId/bThIYCFazp1+yUW9o= - dependencies: - normalize-path "^2.0.1" - through2 "^2.0.3" - "@hapi/hoek@^9.0.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" @@ -365,16 +72,16 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== +"@humanwhocodes/config-array@^0.9.2": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" + integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== dependencies: - "@humanwhocodes/object-schema" "^1.2.0" + "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" -"@humanwhocodes/object-schema@^1.2.0": +"@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== @@ -384,238 +91,225 @@ resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== -"@istanbuljs/load-nyc-config@^1.0.0": +"@isaacs/string-locale-compare@^1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" + resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" + integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ== -"@istanbuljs/schema@^0.1.2": +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/resolve-uri@^3.0.3": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe" - integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== - -"@jridgewell/set-array@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea" - integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.13" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c" - integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" - integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@koa/router@^10.1.1": - version "10.1.1" - resolved "https://registry.yarnpkg.com/@koa/router/-/router-10.1.1.tgz#8e5a85c9b243e0bc776802c0de564561e57a5f78" - integrity sha512-ORNjq5z4EmQPriKbR0ER3k4Gh7YGNhWDL7JBW+8wXDrHLbWYKYSJaOJ9aN06npF5tbTxe2JBOsurpJDAvjiXKw== +"@jridgewell/trace-mapping@^0.3.12": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== dependencies: - debug "^4.1.1" - http-errors "^1.7.3" + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@koa/router@^11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@koa/router/-/router-11.0.1.tgz#9df822273511ea6d4f709d646eb32c063f4acbc0" + integrity sha512-jZ5ISytdHJWUPiXmxIpT/rk7rCRD/gnwYP3WKlQ0kOLWAtCeFbURTlP2zG0VyALKq4NtVMf0uEMFreQJWFOhaw== + dependencies: + http-errors "^2.0.0" koa-compose "^4.1.0" methods "^1.1.2" - path-to-regexp "^6.1.0" - -"@lerna/add@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/add/-/add-4.0.0.tgz#c36f57d132502a57b9e7058d1548b7a565ef183f" - integrity sha512-cpmAH1iS3k8JBxNvnMqrGTTjbY/ZAiKa1ChJzFevMYY3eeqbvhsBKnBcxjRXtdrJ6bd3dCQM+ZtK+0i682Fhng== - dependencies: - "@lerna/bootstrap" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/filter-options" "4.0.0" - "@lerna/npm-conf" "4.0.0" - "@lerna/validation-error" "4.0.0" + path-to-regexp "^6.2.1" + +"@lerna/add@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-5.1.8.tgz#9710a838cb1616cf84c47e85aab5a7cc5a36ce21" + integrity sha512-ABplk8a5MmiT8lG1b9KHijRUwj/nOePMuezBHjJEpNeQ8Bw5w3IV/6hpdmApx/w1StBwWWf0UG42klrxXlfl/g== + dependencies: + "@lerna/bootstrap" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/filter-options" "5.1.8" + "@lerna/npm-conf" "5.1.8" + "@lerna/validation-error" "5.1.8" dedent "^0.7.0" npm-package-arg "^8.1.0" p-map "^4.0.0" - pacote "^11.2.6" + pacote "^13.4.1" semver "^7.3.4" -"@lerna/bootstrap@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-4.0.0.tgz#5f5c5e2c6cfc8fcec50cb2fbe569a8c607101891" - integrity sha512-RkS7UbeM2vu+kJnHzxNRCLvoOP9yGNgkzRdy4UV2hNalD7EP41bLvRVOwRYQ7fhc2QcbhnKNdOBihYRL0LcKtw== - dependencies: - "@lerna/command" "4.0.0" - "@lerna/filter-options" "4.0.0" - "@lerna/has-npm-version" "4.0.0" - "@lerna/npm-install" "4.0.0" - "@lerna/package-graph" "4.0.0" - "@lerna/pulse-till-done" "4.0.0" - "@lerna/rimraf-dir" "4.0.0" - "@lerna/run-lifecycle" "4.0.0" - "@lerna/run-topologically" "4.0.0" - "@lerna/symlink-binary" "4.0.0" - "@lerna/symlink-dependencies" "4.0.0" - "@lerna/validation-error" "4.0.0" +"@lerna/bootstrap@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-5.1.8.tgz#b8664d7eef6bd1072fe3ea5285848cc0c590a9bc" + integrity sha512-/QZJc6aRxi6csSR59jdqRXPFh33fbn60F1k/SWtCCELGkZub23fAPLKaO7SlMcyghN3oKlfTfVymu/NWEcptJQ== + dependencies: + "@lerna/command" "5.1.8" + "@lerna/filter-options" "5.1.8" + "@lerna/has-npm-version" "5.1.8" + "@lerna/npm-install" "5.1.8" + "@lerna/package-graph" "5.1.8" + "@lerna/pulse-till-done" "5.1.8" + "@lerna/rimraf-dir" "5.1.8" + "@lerna/run-lifecycle" "5.1.8" + "@lerna/run-topologically" "5.1.8" + "@lerna/symlink-binary" "5.1.8" + "@lerna/symlink-dependencies" "5.1.8" + "@lerna/validation-error" "5.1.8" + "@npmcli/arborist" "5.2.0" dedent "^0.7.0" get-port "^5.1.1" multimatch "^5.0.0" npm-package-arg "^8.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" p-map "^4.0.0" p-map-series "^2.1.0" p-waterfall "^2.1.1" - read-package-tree "^5.3.1" semver "^7.3.4" -"@lerna/changed@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-4.0.0.tgz#b9fc76cea39b9292a6cd263f03eb57af85c9270b" - integrity sha512-cD+KuPRp6qiPOD+BO6S6SN5cARspIaWSOqGBpGnYzLb4uWT8Vk4JzKyYtc8ym1DIwyoFXHosXt8+GDAgR8QrgQ== +"@lerna/changed@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-5.1.8.tgz#7db0c16703440ba6bf53ad3719fd13ba748aaf27" + integrity sha512-JA9jX9VTHrwSMRJTgLEzdyyx4zi35X0yP6fUUFuli9a0zrB4HV4IowSn1XM03H8iebbDLB0eWBbosqhYwSP8Sw== dependencies: - "@lerna/collect-updates" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/listable" "4.0.0" - "@lerna/output" "4.0.0" + "@lerna/collect-updates" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/listable" "5.1.8" + "@lerna/output" "5.1.8" -"@lerna/check-working-tree@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-4.0.0.tgz#257e36a602c00142e76082a19358e3e1ae8dbd58" - integrity sha512-/++bxM43jYJCshBiKP5cRlCTwSJdRSxVmcDAXM+1oUewlZJVSVlnks5eO0uLxokVFvLhHlC5kHMc7gbVFPHv6Q== +"@lerna/check-working-tree@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-5.1.8.tgz#9529006f1c57cf1d783539063a381777aa983054" + integrity sha512-3QyiV75cYt9dtg9JhUt+Aiyk44mFjlyqIIJ/XZ2Cp/Xcwws/QrNKOTs5iYFX5XWzlpTgotOHcu1MH/mY55Czlw== dependencies: - "@lerna/collect-uncommitted" "4.0.0" - "@lerna/describe-ref" "4.0.0" - "@lerna/validation-error" "4.0.0" + "@lerna/collect-uncommitted" "5.1.8" + "@lerna/describe-ref" "5.1.8" + "@lerna/validation-error" "5.1.8" -"@lerna/child-process@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-4.0.0.tgz#341b96a57dffbd9705646d316e231df6fa4df6e1" - integrity sha512-XtCnmCT9eyVsUUHx6y/CTBYdV9g2Cr/VxyseTWBgfIur92/YKClfEtJTbOh94jRT62hlKLqSvux/UhxXVh613Q== +"@lerna/child-process@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-5.1.8.tgz#4350eb58fe4c478000317a65f62985d212ee4f89" + integrity sha512-P0o4Y/sdiUJ53spZpaVv53NdAcl15UAi5//W3uT2T250xQPlVROwKy11S3Wzqglh94FYdi6XUy293x1uwBlFPw== dependencies: chalk "^4.1.0" execa "^5.0.0" strong-log-transformer "^2.1.0" -"@lerna/clean@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-4.0.0.tgz#8f778b6f2617aa2a936a6b5e085ae62498e57dc5" - integrity sha512-uugG2iN9k45ITx2jtd8nEOoAtca8hNlDCUM0N3lFgU/b1mEQYAPRkqr1qs4FLRl/Y50ZJ41wUz1eazS+d/0osA== - dependencies: - "@lerna/command" "4.0.0" - "@lerna/filter-options" "4.0.0" - "@lerna/prompt" "4.0.0" - "@lerna/pulse-till-done" "4.0.0" - "@lerna/rimraf-dir" "4.0.0" +"@lerna/clean@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-5.1.8.tgz#dbf4634bbc3f5c526eec38c850eaa6882bb6eb2c" + integrity sha512-xMExZgjan5/8ZTjJkZoLoTKY1MQOMk7W1YXslbg9BpLevBycPk041MlLauzCyO8XdOpqpVnFCg/9W66fltqmQg== + dependencies: + "@lerna/command" "5.1.8" + "@lerna/filter-options" "5.1.8" + "@lerna/prompt" "5.1.8" + "@lerna/pulse-till-done" "5.1.8" + "@lerna/rimraf-dir" "5.1.8" p-map "^4.0.0" p-map-series "^2.1.0" p-waterfall "^2.1.1" -"@lerna/cli@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-4.0.0.tgz#8eabd334558836c1664df23f19acb95e98b5bbf3" - integrity sha512-Neaw3GzFrwZiRZv2g7g6NwFjs3er1vhraIniEs0jjVLPMNC4eata0na3GfE5yibkM/9d3gZdmihhZdZ3EBdvYA== +"@lerna/cli@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-5.1.8.tgz#b094a2d2eb70522ced850da60c94a2e0bf8c5adc" + integrity sha512-0Ghhd9M9QvY6qZtnjTq5RHOIac2ttsW2VNFLFso8ov3YV+rJF4chLhyVaVBvLSA+5ZhwFH+xQ3/yeUx1tDO8GA== dependencies: - "@lerna/global-options" "4.0.0" + "@lerna/global-options" "5.1.8" dedent "^0.7.0" - npmlog "^4.1.2" + npmlog "^6.0.2" yargs "^16.2.0" -"@lerna/collect-uncommitted@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-uncommitted/-/collect-uncommitted-4.0.0.tgz#855cd64612969371cfc2453b90593053ff1ba779" - integrity sha512-ufSTfHZzbx69YNj7KXQ3o66V4RC76ffOjwLX0q/ab//61bObJ41n03SiQEhSlmpP+gmFbTJ3/7pTe04AHX9m/g== +"@lerna/collect-uncommitted@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/collect-uncommitted/-/collect-uncommitted-5.1.8.tgz#1caf374998402883b4a345dffed8c1cddd57e76a" + integrity sha512-pRsIYu82A3DxLahQI/3azoi/kjj6QSSHHAOx4y1YVefeDCaVtAm8aesNbpnyNVfJrie/1Gt5GMEpjfm/KScjlw== dependencies: - "@lerna/child-process" "4.0.0" + "@lerna/child-process" "5.1.8" chalk "^4.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/collect-updates@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-4.0.0.tgz#8e208b1bafd98a372ff1177f7a5e288f6bea8041" - integrity sha512-bnNGpaj4zuxsEkyaCZLka9s7nMs58uZoxrRIPJ+nrmrZYp1V5rrd+7/NYTuunOhY2ug1sTBvTAxj3NZQ+JKnOw== +"@lerna/collect-updates@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-5.1.8.tgz#b4d2f1a333abb690b74e4c5def45763347070754" + integrity sha512-ZPQmYKzwDJ4T+t2fRUI/JjaCzC8Lv02kWIeSXrcIG+cf2xrbM0vK4iQMAKhagTsiWt9hrFwvtMgLp4a6+Ht8Qg== dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/describe-ref" "4.0.0" + "@lerna/child-process" "5.1.8" + "@lerna/describe-ref" "5.1.8" minimatch "^3.0.4" - npmlog "^4.1.2" + npmlog "^6.0.2" slash "^3.0.0" -"@lerna/command@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/command/-/command-4.0.0.tgz#991c7971df8f5bf6ae6e42c808869a55361c1b98" - integrity sha512-LM9g3rt5FsPNFqIHUeRwWXLNHJ5NKzOwmVKZ8anSp4e1SPrv2HNc1V02/9QyDDZK/w+5POXH5lxZUI1CHaOK/A== - dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/package-graph" "4.0.0" - "@lerna/project" "4.0.0" - "@lerna/validation-error" "4.0.0" - "@lerna/write-log-file" "4.0.0" +"@lerna/command@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-5.1.8.tgz#0dcca15a7148ce3326178c7358d5f907430dc328" + integrity sha512-j/Q++APvkyN2t8GqOpK+4OxH1bB7OZGVWIKh0JQlwbtqH1Y06wlSyNdwpPmv8h1yO9fS1pY/xHwFbs1IicxwzA== + dependencies: + "@lerna/child-process" "5.1.8" + "@lerna/package-graph" "5.1.8" + "@lerna/project" "5.1.8" + "@lerna/validation-error" "5.1.8" + "@lerna/write-log-file" "5.1.8" clone-deep "^4.0.1" dedent "^0.7.0" execa "^5.0.0" is-ci "^2.0.0" - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/conventional-commits@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-4.0.0.tgz#660fb2c7b718cb942ead70110df61f18c6f99750" - integrity sha512-CSUQRjJHFrH8eBn7+wegZLV3OrNc0Y1FehYfYGhjLE2SIfpCL4bmfu/ViYuHh9YjwHaA+4SX6d3hR+xkeseKmw== +"@lerna/conventional-commits@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-5.1.8.tgz#5d6f87ebb024d4468024b22ced0ea948246d593f" + integrity sha512-UduSVDp/+2WlEV6ZO5s7yTzkfhYyPdEsqR6aaUtIJZe9wejcCK4Lc3BJ2BAYIOdtDArNY2CJPsz1LYvFDtPRkw== dependencies: - "@lerna/validation-error" "4.0.0" + "@lerna/validation-error" "5.1.8" conventional-changelog-angular "^5.0.12" conventional-changelog-core "^4.2.2" conventional-recommended-bump "^6.1.0" fs-extra "^9.1.0" get-stream "^6.0.0" - lodash.template "^4.5.0" npm-package-arg "^8.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" pify "^5.0.0" semver "^7.3.4" -"@lerna/create-symlink@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-4.0.0.tgz#8c5317ce5ae89f67825443bd7651bf4121786228" - integrity sha512-I0phtKJJdafUiDwm7BBlEUOtogmu8+taxq6PtIrxZbllV9hWg59qkpuIsiFp+no7nfRVuaasNYHwNUhDAVQBig== +"@lerna/create-symlink@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-5.1.8.tgz#36b3cb34d3e434f021a878c7353a6dd0ccacd6bd" + integrity sha512-5acQITDsJ7dqywPRrF1mpTUPm/EXFfiv/xF6zX+ySUjp4h0Zhhnsm8g2jFdRPDSjIxFD0rV/5iU4X6qmflXlAg== dependencies: cmd-shim "^4.1.0" fs-extra "^9.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/create@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-4.0.0.tgz#b6947e9b5dfb6530321952998948c3e63d64d730" - integrity sha512-mVOB1niKByEUfxlbKTM1UNECWAjwUdiioIbRQZEeEabtjCL69r9rscIsjlGyhGWCfsdAG5wfq4t47nlDXdLLag== +"@lerna/create@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-5.1.8.tgz#ccb485e460d4d9f1b34cbe74e79b0261c710af3a" + integrity sha512-n9qLLeg1e0bQeuk8pA8ELEP05Ktl50e1EirdXGRqqvaXdCn41nYHo4PilUgb77/o/t3Z5N4/ic+0w8OvGVakNg== dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/npm-conf" "4.0.0" - "@lerna/validation-error" "4.0.0" + "@lerna/child-process" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/npm-conf" "5.1.8" + "@lerna/validation-error" "5.1.8" dedent "^0.7.0" fs-extra "^9.1.0" globby "^11.0.2" init-package-json "^2.0.2" npm-package-arg "^8.1.0" p-reduce "^2.1.0" - pacote "^11.2.6" + pacote "^13.4.1" pify "^5.0.0" semver "^7.3.4" slash "^3.0.0" @@ -624,493 +318,504 @@ whatwg-url "^8.4.0" yargs-parser "20.2.4" -"@lerna/describe-ref@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-4.0.0.tgz#53c53b4ea65fdceffa072a62bfebe6772c45d9ec" - integrity sha512-eTU5+xC4C5Gcgz+Ey4Qiw9nV2B4JJbMulsYJMW8QjGcGh8zudib7Sduj6urgZXUYNyhYpRs+teci9M2J8u+UvQ== - dependencies: - "@lerna/child-process" "4.0.0" - npmlog "^4.1.2" - -"@lerna/diff@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-4.0.0.tgz#6d3071817aaa4205a07bf77cfc6e932796d48b92" - integrity sha512-jYPKprQVg41+MUMxx6cwtqsNm0Yxx9GDEwdiPLwcUTFx+/qKCEwifKNJ1oGIPBxyEHX2PFCOjkK39lHoj2qiag== - dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/validation-error" "4.0.0" - npmlog "^4.1.2" - -"@lerna/exec@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-4.0.0.tgz#eb6cb95cb92d42590e9e2d628fcaf4719d4a8be6" - integrity sha512-VGXtL/b/JfY84NB98VWZpIExfhLOzy0ozm/0XaS4a2SmkAJc5CeUfrhvHxxkxiTBLkU+iVQUyYEoAT0ulQ8PCw== - dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/filter-options" "4.0.0" - "@lerna/profiler" "4.0.0" - "@lerna/run-topologically" "4.0.0" - "@lerna/validation-error" "4.0.0" +"@lerna/describe-ref@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-5.1.8.tgz#b0f5d252f97d9d96ca404f2b99c91d426f2b7577" + integrity sha512-/u5b2ho09icPcvPb1mlh/tPC07nSFc1cvvFjM9Yg5kfVs23vzVWeA8y0Bk5djlaaSzyHECyqviriX0aoaY47Wg== + dependencies: + "@lerna/child-process" "5.1.8" + npmlog "^6.0.2" + +"@lerna/diff@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-5.1.8.tgz#112f68a99025e5732d4ec8ec6cb6db323555846a" + integrity sha512-BLoi6l/v8p43IkAHTkpjZ4Kq27kYK7iti6y6gYoZuljSwNj38TjgqRb2ohHezQ5c0KFAj8xHEOuZM3Ou6tGyTQ== + dependencies: + "@lerna/child-process" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/validation-error" "5.1.8" + npmlog "^6.0.2" + +"@lerna/exec@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-5.1.8.tgz#a5a808ebb40c74c1a339e73816ea1aa1c53dc284" + integrity sha512-U+owlBKoAUfULqRz0oBtHx/I6tYQy9I7xfPP0GoaXa8lpF7esnpCxsJG8GpdzFqIS30o6a2PtyHvp4jkrQF8Zw== + dependencies: + "@lerna/child-process" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/filter-options" "5.1.8" + "@lerna/profiler" "5.1.8" + "@lerna/run-topologically" "5.1.8" + "@lerna/validation-error" "5.1.8" p-map "^4.0.0" -"@lerna/filter-options@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-4.0.0.tgz#ac94cc515d7fa3b47e2f7d74deddeabb1de5e9e6" - integrity sha512-vV2ANOeZhOqM0rzXnYcFFCJ/kBWy/3OA58irXih9AMTAlQLymWAK0akWybl++sUJ4HB9Hx12TOqaXbYS2NM5uw== +"@lerna/filter-options@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-5.1.8.tgz#cb18431a92a138e9428af0217b01bfa89adb9b13" + integrity sha512-ene6xj1BRSFgIgcVg9xABp1cCiRnqm3Uetk9InxOtECbofpSDa7cQy5lsPv6GGAgXFbT91SURQiipH9FAOP+yQ== dependencies: - "@lerna/collect-updates" "4.0.0" - "@lerna/filter-packages" "4.0.0" + "@lerna/collect-updates" "5.1.8" + "@lerna/filter-packages" "5.1.8" dedent "^0.7.0" - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/filter-packages@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-4.0.0.tgz#b1f70d70e1de9cdd36a4e50caa0ac501f8d012f2" - integrity sha512-+4AJIkK7iIiOaqCiVTYJxh/I9qikk4XjNQLhE3kixaqgMuHl1NQ99qXRR0OZqAWB9mh8Z1HA9bM5K1HZLBTOqA== +"@lerna/filter-packages@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-5.1.8.tgz#5dd32c05c646f4d3ad55adde8e67d60661c2bead" + integrity sha512-2pdtZ+I2Sb+XKfUa/q8flVUyaY0hhwqFYMXll7Nut7Phb1w1TtkEXc2/N0Ac1yia6qSJB/5WrsbAcLF/ITp1vA== dependencies: - "@lerna/validation-error" "4.0.0" + "@lerna/validation-error" "5.1.8" multimatch "^5.0.0" - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/get-npm-exec-opts@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-4.0.0.tgz#dc955be94a4ae75c374ef9bce91320887d34608f" - integrity sha512-yvmkerU31CTWS2c7DvmAWmZVeclPBqI7gPVr5VATUKNWJ/zmVcU4PqbYoLu92I9Qc4gY1TuUplMNdNuZTSL7IQ== +"@lerna/get-npm-exec-opts@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-5.1.8.tgz#71ea0a8760231322c5a4fe103aab659e3de062a3" + integrity sha512-oujoIkEDDVK2+5ooPMEPI+xGs/iwPmGJ63AZu1h7P42YU9tHKQmF5yPybF3Jn99W8+HggM6APUGiX+5oHRvKXA== dependencies: - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/get-packed@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-4.0.0.tgz#0989d61624ac1f97e393bdad2137c49cd7a37823" - integrity sha512-rfWONRsEIGyPJTxFzC8ECb3ZbsDXJbfqWYyeeQQDrJRPnEJErlltRLPLgC2QWbxFgFPsoDLeQmFHJnf0iDfd8w== +"@lerna/get-packed@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-5.1.8.tgz#c8020be24befbe018fc535cf513efa5863a4a1a2" + integrity sha512-3vabIFlfUFQPbFnlOaDCNY4p7mufrhIFPoXxWu15JnjJsSDf9UB2a98xX43xNlxjgZLvnLai3bhCNfrKonI4Kw== dependencies: fs-extra "^9.1.0" ssri "^8.0.1" tar "^6.1.0" -"@lerna/github-client@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-4.0.0.tgz#2ced67721363ef70f8e12ffafce4410918f4a8a4" - integrity sha512-2jhsldZtTKXYUBnOm23Lb0Fx8G4qfSXF9y7UpyUgWUj+YZYd+cFxSuorwQIgk5P4XXrtVhsUesIsli+BYSThiw== +"@lerna/github-client@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-5.1.8.tgz#1b0a3d5ae9996d56e7977d319d5b95ec2c24df8f" + integrity sha512-y1oweMZ9xc/htIHy42hy2FuMUR/LS3CQlslXG9PAHzl5rE1VDDjvSv61kS50ZberGfB9xmkCxqH+2LgROG9B1A== dependencies: - "@lerna/child-process" "4.0.0" + "@lerna/child-process" "5.1.8" "@octokit/plugin-enterprise-rest" "^6.0.1" "@octokit/rest" "^18.1.0" - git-url-parse "^11.4.4" - npmlog "^4.1.2" + git-url-parse "^12.0.0" + npmlog "^6.0.2" -"@lerna/gitlab-client@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/gitlab-client/-/gitlab-client-4.0.0.tgz#00dad73379c7b38951d4b4ded043504c14e2b67d" - integrity sha512-OMUpGSkeDWFf7BxGHlkbb35T7YHqVFCwBPSIR6wRsszY8PAzCYahtH3IaJzEJyUg6vmZsNl0FSr3pdA2skhxqA== +"@lerna/gitlab-client@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/gitlab-client/-/gitlab-client-5.1.8.tgz#84e9063c79b0543570ca02ad50f7ad54446ab78d" + integrity sha512-/EMKdkGnBU4ldyAQ4pXp2TKi1znvY3MiCULt8Hy42p4HhfFl/AxZYDovQYfop1NHVk29BQrGHfvlpyBNqZ2a8g== dependencies: node-fetch "^2.6.1" - npmlog "^4.1.2" + npmlog "^6.0.2" whatwg-url "^8.4.0" -"@lerna/global-options@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-4.0.0.tgz#c7d8b0de6a01d8a845e2621ea89e7f60f18c6a5f" - integrity sha512-TRMR8afAHxuYBHK7F++Ogop2a82xQjoGna1dvPOY6ltj/pEx59pdgcJfYcynYqMkFIk8bhLJJN9/ndIfX29FTQ== +"@lerna/global-options@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-5.1.8.tgz#ba760c9a9a686bc0109d9b09017737a7365b7649" + integrity sha512-VCfTilGh0O4T6Lk4DKYA5cUl1kPjwFfRUS/GSpdJx0Lf/dyDbFihrmTHefgUe9N2/nTQySDIdPk9HBr45tozWQ== -"@lerna/has-npm-version@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-4.0.0.tgz#d3fc3292c545eb28bd493b36e6237cf0279f631c" - integrity sha512-LQ3U6XFH8ZmLCsvsgq1zNDqka0Xzjq5ibVN+igAI5ccRWNaUsE/OcmsyMr50xAtNQMYMzmpw5GVLAivT2/YzCg== +"@lerna/has-npm-version@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-5.1.8.tgz#9ea80ee3616006df1094cc18c1bc58f3f1008299" + integrity sha512-yN5j9gje2ND8zQf4tN52QDQ/yFb24o9Kasm4PZm99FzBURRIwFWCnvo3edOMaiJg0DpA660L+Kq9G0L+ZRKRZQ== dependencies: - "@lerna/child-process" "4.0.0" + "@lerna/child-process" "5.1.8" semver "^7.3.4" -"@lerna/import@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/import/-/import-4.0.0.tgz#bde656c4a451fa87ae41733ff8a8da60547c5465" - integrity sha512-FaIhd+4aiBousKNqC7TX1Uhe97eNKf5/SC7c5WZANVWtC7aBWdmswwDt3usrzCNpj6/Wwr9EtEbYROzxKH8ffg== - dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/prompt" "4.0.0" - "@lerna/pulse-till-done" "4.0.0" - "@lerna/validation-error" "4.0.0" +"@lerna/import@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-5.1.8.tgz#b1eebfaab1df618ec0a92a639c45010c1fcd1098" + integrity sha512-m1+TEhlgS9i14T7o0/8o6FMZJ1O2PkQdpCjqUa5xdLITqvPozoMNujNgiX3ZVLg/XcFOjMtbCsYtspqtKyEsMQ== + dependencies: + "@lerna/child-process" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/prompt" "5.1.8" + "@lerna/pulse-till-done" "5.1.8" + "@lerna/validation-error" "5.1.8" dedent "^0.7.0" fs-extra "^9.1.0" p-map-series "^2.1.0" -"@lerna/info@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/info/-/info-4.0.0.tgz#b9fb0e479d60efe1623603958a831a88b1d7f1fc" - integrity sha512-8Uboa12kaCSZEn4XRfPz5KU9XXoexSPS4oeYGj76s2UQb1O1GdnEyfjyNWoUl1KlJ2i/8nxUskpXIftoFYH0/Q== +"@lerna/info@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/info/-/info-5.1.8.tgz#99aab0f599cf9d9f1f144dbc110e38f6337e0a77" + integrity sha512-VNCBNOrd5Q1iv1MOF++PzMrdAnTn6KTDbb5hcXHdWBRZUuOs3QOwVYGzAlTFMvwVmmlcER4z8BYyUsbxk3sIdQ== dependencies: - "@lerna/command" "4.0.0" - "@lerna/output" "4.0.0" + "@lerna/command" "5.1.8" + "@lerna/output" "5.1.8" envinfo "^7.7.4" -"@lerna/init@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/init/-/init-4.0.0.tgz#dadff67e6dfb981e8ccbe0e6a310e837962f6c7a" - integrity sha512-wY6kygop0BCXupzWj5eLvTUqdR7vIAm0OgyV9WHpMYQGfs1V22jhztt8mtjCloD/O0nEe4tJhdG62XU5aYmPNQ== +"@lerna/init@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-5.1.8.tgz#7ad1433d50e283ba01cae84f9640cf99b0a8a047" + integrity sha512-vEMnq/70u/c031/vURA4pZSxlBRAwjg7vOP7mt9M4dmKz/vkVnQ/5Ig9K0TKqC31hQg957/4m20obYEiFgC3Pw== dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/command" "4.0.0" + "@lerna/child-process" "5.1.8" + "@lerna/command" "5.1.8" fs-extra "^9.1.0" p-map "^4.0.0" write-json-file "^4.3.0" -"@lerna/link@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/link/-/link-4.0.0.tgz#c3a38aabd44279d714e90f2451e31b63f0fb65ba" - integrity sha512-KlvPi7XTAcVOByfaLlOeYOfkkDcd+bejpHMCd1KcArcFTwijOwXOVi24DYomIeHvy6HsX/IUquJ4PPUJIeB4+w== +"@lerna/link@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-5.1.8.tgz#f9d5736640f524c9f255007d3d7b3792846042ef" + integrity sha512-qOtZiMzB9JYyNPUlvpqTxh0Z1EmNVde8pFUIYybv+s3btrKEBPgsvvrOrob/mha3QJxnwcPDPjHt/wCHFxLruA== dependencies: - "@lerna/command" "4.0.0" - "@lerna/package-graph" "4.0.0" - "@lerna/symlink-dependencies" "4.0.0" + "@lerna/command" "5.1.8" + "@lerna/package-graph" "5.1.8" + "@lerna/symlink-dependencies" "5.1.8" p-map "^4.0.0" slash "^3.0.0" -"@lerna/list@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/list/-/list-4.0.0.tgz#24b4e6995bd73f81c556793fe502b847efd9d1d7" - integrity sha512-L2B5m3P+U4Bif5PultR4TI+KtW+SArwq1i75QZ78mRYxPc0U/piau1DbLOmwrdqr99wzM49t0Dlvl6twd7GHFg== +"@lerna/list@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-5.1.8.tgz#72268a7ab4042f4d4463cc41e247c1473ad7c7cf" + integrity sha512-fVN9o/wKtgcOyuYwvYTg2HI6ORX2kOoBkCJ+PI/uZ/ImwLMTJ2Bf8i/Vsysl3bLFHhQFglzPZ7V1SQP/ku0Sdw== dependencies: - "@lerna/command" "4.0.0" - "@lerna/filter-options" "4.0.0" - "@lerna/listable" "4.0.0" - "@lerna/output" "4.0.0" + "@lerna/command" "5.1.8" + "@lerna/filter-options" "5.1.8" + "@lerna/listable" "5.1.8" + "@lerna/output" "5.1.8" -"@lerna/listable@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-4.0.0.tgz#d00d6cb4809b403f2b0374fc521a78e318b01214" - integrity sha512-/rPOSDKsOHs5/PBLINZOkRIX1joOXUXEtyUs5DHLM8q6/RP668x/1lFhw6Dx7/U+L0+tbkpGtZ1Yt0LewCLgeQ== +"@lerna/listable@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-5.1.8.tgz#d101e7a6c1bb9df670b4514422621684edab7770" + integrity sha512-nQ/40cbVZLFBv8o9Dz6ivHFZhosfDTYOPm4oHNu0xdexaTXWz5bQUlM4HtOm7K0dJ1fvLEVqiQNAuFSEhARt9g== dependencies: - "@lerna/query-graph" "4.0.0" + "@lerna/query-graph" "5.1.8" chalk "^4.1.0" - columnify "^1.5.4" + columnify "^1.6.0" -"@lerna/log-packed@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-4.0.0.tgz#95168fe2e26ac6a71e42f4be857519b77e57a09f" - integrity sha512-+dpCiWbdzgMAtpajLToy9PO713IHoE6GV/aizXycAyA07QlqnkpaBNZ8DW84gHdM1j79TWockGJo9PybVhrrZQ== +"@lerna/log-packed@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-5.1.8.tgz#22e02f41b99e7202a45b066f8747dc8451e0b18e" + integrity sha512-alaCIzCtKV5oKyu632emda0hUQMw/BcL2U3v4ObLu90sU8P7mu6TipKRvR9OZxOLDnZGnPE7CMHSU8gsQoIasw== dependencies: byte-size "^7.0.0" - columnify "^1.5.4" + columnify "^1.6.0" has-unicode "^2.0.1" - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/npm-conf@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-4.0.0.tgz#b259fd1e1cee2bf5402b236e770140ff9ade7fd2" - integrity sha512-uS7H02yQNq3oejgjxAxqq/jhwGEE0W0ntr8vM3EfpCW1F/wZruwQw+7bleJQ9vUBjmdXST//tk8mXzr5+JXCfw== +"@lerna/npm-conf@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-5.1.8.tgz#a36b216c1af65c0524c4278b2f53ed50295110ed" + integrity sha512-d/pIcO4RwO3fXNlUbhQ6+qwULxGSiW/xcOtiETVf4ZfjaDqjkCaIxZaeZfm5gWDtII5klpQn3f2d71FCnZG5lw== dependencies: config-chain "^1.1.12" pify "^5.0.0" -"@lerna/npm-dist-tag@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-4.0.0.tgz#d1e99b4eccd3414142f0548ad331bf2d53f3257a" - integrity sha512-F20sg28FMYTgXqEQihgoqSfwmq+Id3zT23CnOwD+XQMPSy9IzyLf1fFVH319vXIw6NF6Pgs4JZN2Qty6/CQXGw== +"@lerna/npm-dist-tag@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-5.1.8.tgz#f5b26dfd9e97a0eb72987c8175d3b1bd2a7d82a0" + integrity sha512-vZXO0/EClOzRRHHfqB4APhZkxiJpQbsQAAFwaXQCNJE+3S+I/MD0S3iiUWrNs4QnN/8Lj1KyzUfznVDXX7AIUQ== dependencies: - "@lerna/otplease" "4.0.0" + "@lerna/otplease" "5.1.8" npm-package-arg "^8.1.0" npm-registry-fetch "^9.0.0" - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/npm-install@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-4.0.0.tgz#31180be3ab3b7d1818a1a0c206aec156b7094c78" - integrity sha512-aKNxq2j3bCH3eXl3Fmu4D54s/YLL9WSwV8W7X2O25r98wzrO38AUN6AB9EtmAx+LV/SP15et7Yueg9vSaanRWg== +"@lerna/npm-install@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-5.1.8.tgz#03aada74bd17e196288d417ec2f7d3399e289c01" + integrity sha512-AiYQyz4W1+NDeBw3qmdiiatfCtwtaGOi7zHtN1eAqheVTxEMuuYjNHt+8hu6nSpDFYtonz0NsKFvaqRJ5LbVmw== dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/get-npm-exec-opts" "4.0.0" + "@lerna/child-process" "5.1.8" + "@lerna/get-npm-exec-opts" "5.1.8" fs-extra "^9.1.0" npm-package-arg "^8.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" signal-exit "^3.0.3" write-pkg "^4.0.0" -"@lerna/npm-publish@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-4.0.0.tgz#84eb62e876fe949ae1fd62c60804423dbc2c4472" - integrity sha512-vQb7yAPRo5G5r77DRjHITc9piR9gvEKWrmfCH7wkfBnGWEqu7n8/4bFQ7lhnkujvc8RXOsYpvbMQkNfkYibD/w== +"@lerna/npm-publish@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-5.1.8.tgz#259550c25d1d277c296dc3eb4e3e20f626e64510" + integrity sha512-Gup/1d8ovc21x3spKPhFK0tIYYn8HOjnpCAg5ytINIW1QM/QcLAigY58If8uiyt+aojz6lubWrSR8/OHf9CXBw== dependencies: - "@lerna/otplease" "4.0.0" - "@lerna/run-lifecycle" "4.0.0" + "@lerna/otplease" "5.1.8" + "@lerna/run-lifecycle" "5.1.8" fs-extra "^9.1.0" libnpmpublish "^4.0.0" npm-package-arg "^8.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" pify "^5.0.0" read-package-json "^3.0.0" -"@lerna/npm-run-script@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-4.0.0.tgz#dfebf4f4601442e7c0b5214f9fb0d96c9350743b" - integrity sha512-Jmyh9/IwXJjOXqKfIgtxi0bxi1pUeKe5bD3S81tkcy+kyng/GNj9WSqD5ZggoNP2NP//s4CLDAtUYLdP7CU9rA== +"@lerna/npm-run-script@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-5.1.8.tgz#6472bd96cf667feb829101a5e4db587b2e009d33" + integrity sha512-HzvukNC+hDIR25EpYWOvIGJItd0onXqzS9Ivdtw98ZQG3Jexi2Mn18A9tDqHOKCEGO3pVYrI9ep8VWkah2Bj1w== dependencies: - "@lerna/child-process" "4.0.0" - "@lerna/get-npm-exec-opts" "4.0.0" - npmlog "^4.1.2" + "@lerna/child-process" "5.1.8" + "@lerna/get-npm-exec-opts" "5.1.8" + npmlog "^6.0.2" -"@lerna/otplease@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/otplease/-/otplease-4.0.0.tgz#84972eb43448f8a1077435ba1c5e59233b725850" - integrity sha512-Sgzbqdk1GH4psNiT6hk+BhjOfIr/5KhGBk86CEfHNJTk9BK4aZYyJD4lpDbDdMjIV4g03G7pYoqHzH765T4fxw== +"@lerna/otplease@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/otplease/-/otplease-5.1.8.tgz#b0019f71b8a86e1594f277abf0f9c95aeebd2419" + integrity sha512-/OVZ7Rbs8/ft14f4i/9HEFDsxJkBSg74rMUqyqFH3fID/RL3ja9hW5bI1bENxvYgs0bp/THy4lV5V75ZcI81zQ== dependencies: - "@lerna/prompt" "4.0.0" + "@lerna/prompt" "5.1.8" -"@lerna/output@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/output/-/output-4.0.0.tgz#b1d72215c0e35483e4f3e9994debc82c621851f2" - integrity sha512-Un1sHtO1AD7buDQrpnaYTi2EG6sLF+KOPEAMxeUYG5qG3khTs2Zgzq5WE3dt2N/bKh7naESt20JjIW6tBELP0w== +"@lerna/output@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/output/-/output-5.1.8.tgz#ca4d96379bbe7556035039bf2f416f36d363082a" + integrity sha512-dXsKY8X2eAdPKRKHDZTASlWn95Eav1oQX9doUXkvV3o4UwIgqOCIsU7RqSED3EAEQz6VUH0rXNb/+d3uVeAoJQ== dependencies: - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/pack-directory@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-4.0.0.tgz#8b617db95d20792f043aaaa13a9ccc0e04cb4c74" - integrity sha512-NJrmZNmBHS+5aM+T8N6FVbaKFScVqKlQFJNY2k7nsJ/uklNKsLLl6VhTQBPwMTbf6Tf7l6bcKzpy7aePuq9UiQ== +"@lerna/pack-directory@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-5.1.8.tgz#09e02134acaecd6be81a17dec7b9fdc7f66a29b7" + integrity sha512-aaH28ttS+JVimLFrVeZRWZ9Cii4GG2vkJXmQNikWBNQiFL/7S1x83NjMk4SQRdmtpYJkcQpQMZ2hDUdNxLnDCg== dependencies: - "@lerna/get-packed" "4.0.0" - "@lerna/package" "4.0.0" - "@lerna/run-lifecycle" "4.0.0" + "@lerna/get-packed" "5.1.8" + "@lerna/package" "5.1.8" + "@lerna/run-lifecycle" "5.1.8" + "@lerna/temp-write" "5.1.8" npm-packlist "^2.1.4" - npmlog "^4.1.2" + npmlog "^6.0.2" tar "^6.1.0" - temp-write "^4.0.0" -"@lerna/package-graph@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-4.0.0.tgz#16a00253a8ac810f72041481cb46bcee8d8123dd" - integrity sha512-QED2ZCTkfXMKFoTGoccwUzjHtZMSf3UKX14A4/kYyBms9xfFsesCZ6SLI5YeySEgcul8iuIWfQFZqRw+Qrjraw== +"@lerna/package-graph@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-5.1.8.tgz#38339c3ad6e1469118ea3d52cf818ce7950d41c3" + integrity sha512-aGwXTwCpPfhUPiSRhdppogZjOqJPm39EBxHFDa1E0+/Qaig5avJs4hI6OrPLyjsTywAswtCMOArvD1QZqxwvrQ== dependencies: - "@lerna/prerelease-id-from-version" "4.0.0" - "@lerna/validation-error" "4.0.0" + "@lerna/prerelease-id-from-version" "5.1.8" + "@lerna/validation-error" "5.1.8" npm-package-arg "^8.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" semver "^7.3.4" -"@lerna/package@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/package/-/package-4.0.0.tgz#1b4c259c4bcff45c876ee1d591a043aacbc0d6b7" - integrity sha512-l0M/izok6FlyyitxiQKr+gZLVFnvxRQdNhzmQ6nRnN9dvBJWn+IxxpM+cLqGACatTnyo9LDzNTOj2Db3+s0s8Q== +"@lerna/package@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-5.1.8.tgz#17e119553b8c957915f92e43a5f4284ec98439c2" + integrity sha512-Ot+wu6XZ93tw8p9oSTJJA15TzGhVpo8VbgNhKPcI3JJjkxVq2D5L5jVeBkjQvFEQBonLibTr339uLLXyZ0RMzg== dependencies: load-json-file "^6.2.0" npm-package-arg "^8.1.0" write-pkg "^4.0.0" -"@lerna/prerelease-id-from-version@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-4.0.0.tgz#c7e0676fcee1950d85630e108eddecdd5b48c916" - integrity sha512-GQqguzETdsYRxOSmdFZ6zDBXDErIETWOqomLERRY54f4p+tk4aJjoVdd9xKwehC9TBfIFvlRbL1V9uQGHh1opg== +"@lerna/prerelease-id-from-version@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-5.1.8.tgz#83f27db93b19ccb74187e85b8174e4bd4f46e091" + integrity sha512-wfWv/8lHSk2/pl4FjopbDelFSLCz9s6J9AY5o7Sju9HtD9QUXcQHaXnEP1Rum9/rJZ8vWdFURcp9kzz8nxQ1Ow== dependencies: semver "^7.3.4" -"@lerna/profiler@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/profiler/-/profiler-4.0.0.tgz#8a53ab874522eae15d178402bff90a14071908e9" - integrity sha512-/BaEbqnVh1LgW/+qz8wCuI+obzi5/vRE8nlhjPzdEzdmWmZXuCKyWSEzAyHOJWw1ntwMiww5dZHhFQABuoFz9Q== +"@lerna/profiler@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/profiler/-/profiler-5.1.8.tgz#1f757c2bf87cdfad592d58f7d17f60e3648d956f" + integrity sha512-vpAFN85BvMHfIGA53IcwaUnS9FHAismEnNyFCjMkzKV55mmXFZlWpZyO36ESdSQRWCo5/25f3Ln0Y6YubY3Dvw== dependencies: fs-extra "^9.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" upath "^2.0.1" -"@lerna/project@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/project/-/project-4.0.0.tgz#ff84893935833533a74deff30c0e64ddb7f0ba6b" - integrity sha512-o0MlVbDkD5qRPkFKlBZsXZjoNTWPyuL58564nSfZJ6JYNmgAptnWPB2dQlAc7HWRZkmnC2fCkEdoU+jioPavbg== +"@lerna/project@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-5.1.8.tgz#6c379d258eed12acff0d4fe8524f8f084e3892a4" + integrity sha512-zTFp91kmyJ0VHBmNXEArVrMSZVxnBJ7pHTt8C7RY91WSZhw8XDNumqMHDM+kEM1z/AtDBAAAGqBE3sjk5ONDXQ== dependencies: - "@lerna/package" "4.0.0" - "@lerna/validation-error" "4.0.0" + "@lerna/package" "5.1.8" + "@lerna/validation-error" "5.1.8" cosmiconfig "^7.0.0" dedent "^0.7.0" dot-prop "^6.0.1" glob-parent "^5.1.1" globby "^11.0.2" load-json-file "^6.2.0" - npmlog "^4.1.2" + npmlog "^6.0.2" p-map "^4.0.0" resolve-from "^5.0.0" write-json-file "^4.3.0" -"@lerna/prompt@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-4.0.0.tgz#5ec69a803f3f0db0ad9f221dad64664d3daca41b" - integrity sha512-4Ig46oCH1TH5M7YyTt53fT6TuaKMgqUUaqdgxvp6HP6jtdak6+amcsqB8YGz2eQnw/sdxunx84DfI9XpoLj4bQ== +"@lerna/prompt@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-5.1.8.tgz#292639f0c4064f088462bc45b1825b9496a265c9" + integrity sha512-Cmq0FV/vyCHu00kySxXMfuPvutsi8qoME2/nFcICIktvDqxXr5aSFY8QqB123awNCbpb4xcHykjFnEj/RNdb2Q== dependencies: inquirer "^7.3.3" - npmlog "^4.1.2" - -"@lerna/publish@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-4.0.0.tgz#f67011305adeba120066a3b6d984a5bb5fceef65" - integrity sha512-K8jpqjHrChH22qtkytA5GRKIVFEtqBF6JWj1I8dWZtHs4Jywn8yB1jQ3BAMLhqmDJjWJtRck0KXhQQKzDK2UPg== - dependencies: - "@lerna/check-working-tree" "4.0.0" - "@lerna/child-process" "4.0.0" - "@lerna/collect-updates" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/describe-ref" "4.0.0" - "@lerna/log-packed" "4.0.0" - "@lerna/npm-conf" "4.0.0" - "@lerna/npm-dist-tag" "4.0.0" - "@lerna/npm-publish" "4.0.0" - "@lerna/otplease" "4.0.0" - "@lerna/output" "4.0.0" - "@lerna/pack-directory" "4.0.0" - "@lerna/prerelease-id-from-version" "4.0.0" - "@lerna/prompt" "4.0.0" - "@lerna/pulse-till-done" "4.0.0" - "@lerna/run-lifecycle" "4.0.0" - "@lerna/run-topologically" "4.0.0" - "@lerna/validation-error" "4.0.0" - "@lerna/version" "4.0.0" + npmlog "^6.0.2" + +"@lerna/publish@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-5.1.8.tgz#a503d88ea74f197bfc4b02c23e43414b75e94583" + integrity sha512-Q88WxXVNAh/ZWj7vYG83RZUfQyQlJMg7tDhsVTvZzy3VpkkCPtmJXZfX+g4RmE0PNyjsXx9QLYAOZnOB613WyA== + dependencies: + "@lerna/check-working-tree" "5.1.8" + "@lerna/child-process" "5.1.8" + "@lerna/collect-updates" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/describe-ref" "5.1.8" + "@lerna/log-packed" "5.1.8" + "@lerna/npm-conf" "5.1.8" + "@lerna/npm-dist-tag" "5.1.8" + "@lerna/npm-publish" "5.1.8" + "@lerna/otplease" "5.1.8" + "@lerna/output" "5.1.8" + "@lerna/pack-directory" "5.1.8" + "@lerna/prerelease-id-from-version" "5.1.8" + "@lerna/prompt" "5.1.8" + "@lerna/pulse-till-done" "5.1.8" + "@lerna/run-lifecycle" "5.1.8" + "@lerna/run-topologically" "5.1.8" + "@lerna/validation-error" "5.1.8" + "@lerna/version" "5.1.8" fs-extra "^9.1.0" libnpmaccess "^4.0.1" npm-package-arg "^8.1.0" npm-registry-fetch "^9.0.0" - npmlog "^4.1.2" + npmlog "^6.0.2" p-map "^4.0.0" p-pipe "^3.1.0" - pacote "^11.2.6" + pacote "^13.4.1" semver "^7.3.4" -"@lerna/pulse-till-done@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-4.0.0.tgz#04bace7d483a8205c187b806bcd8be23d7bb80a3" - integrity sha512-Frb4F7QGckaybRhbF7aosLsJ5e9WuH7h0KUkjlzSByVycxY91UZgaEIVjS2oN9wQLrheLMHl6SiFY0/Pvo0Cxg== +"@lerna/pulse-till-done@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/pulse-till-done/-/pulse-till-done-5.1.8.tgz#585ebc121841d9f1c587c553a3990601ac0e4168" + integrity sha512-KsyOazHG6wnjfdJhIdhTaTNwhj8Np/aPPei/ac9WzcuzgLS/uCs1IVFFIYBv5JdTmyVBKmguSZxdYjk7JzKBew== dependencies: - npmlog "^4.1.2" + npmlog "^6.0.2" -"@lerna/query-graph@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/query-graph/-/query-graph-4.0.0.tgz#09dd1c819ac5ee3f38db23931143701f8a6eef63" - integrity sha512-YlP6yI3tM4WbBmL9GCmNDoeQyzcyg1e4W96y/PKMZa5GbyUvkS2+Jc2kwPD+5KcXou3wQZxSPzR3Te5OenaDdg== +"@lerna/query-graph@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/query-graph/-/query-graph-5.1.8.tgz#8ef6059f81e0fb64c4236f5fb664582568225af9" + integrity sha512-+p+bjPI403Hwv1djTS5aJe7DtPWIDw0a427BE68h1mmrPc9oTe3GG+0lingbfGR8woA2rOmjytgK2jeErOryPg== dependencies: - "@lerna/package-graph" "4.0.0" + "@lerna/package-graph" "5.1.8" -"@lerna/resolve-symlink@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-4.0.0.tgz#6d006628a210c9b821964657a9e20a8c9a115e14" - integrity sha512-RtX8VEUzqT+uLSCohx8zgmjc6zjyRlh6i/helxtZTMmc4+6O4FS9q5LJas2uGO2wKvBlhcD6siibGt7dIC3xZA== +"@lerna/resolve-symlink@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-5.1.8.tgz#dbccd14caf2701a9c968f1cb869b2bab28f0144a" + integrity sha512-OJa8ct4Oo2BcD95FmJqkc5qZMepaQK5RZAWoTqEXG/13Gs0mPc0fZGIhnnpTqtm3mgNhlT7ypCHG42I7hKiSeg== dependencies: fs-extra "^9.1.0" - npmlog "^4.1.2" + npmlog "^6.0.2" read-cmd-shim "^2.0.0" -"@lerna/rimraf-dir@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-4.0.0.tgz#2edf3b62d4eb0ef4e44e430f5844667d551ec25a" - integrity sha512-QNH9ABWk9mcMJh2/muD9iYWBk1oQd40y6oH+f3wwmVGKYU5YJD//+zMiBI13jxZRtwBx0vmBZzkBkK1dR11cBg== +"@lerna/rimraf-dir@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-5.1.8.tgz#b0546a785cef0eb549b9b21a831e732ac56a7d84" + integrity sha512-3pT1X8kzW8xHUuAmRgzSKAF+/H1h1eSWq5+ACzeTWnvgqE7++0URee7TXwVCP/5FZPTZIzIclQCh4G0WD9Jfjg== dependencies: - "@lerna/child-process" "4.0.0" - npmlog "^4.1.2" + "@lerna/child-process" "5.1.8" + npmlog "^6.0.2" path-exists "^4.0.0" rimraf "^3.0.2" -"@lerna/run-lifecycle@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-4.0.0.tgz#e648a46f9210a9bcd7c391df6844498cb5079334" - integrity sha512-IwxxsajjCQQEJAeAaxF8QdEixfI7eLKNm4GHhXHrgBu185JcwScFZrj9Bs+PFKxwb+gNLR4iI5rpUdY8Y0UdGQ== +"@lerna/run-lifecycle@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-5.1.8.tgz#bac65e96f20b395a1e05db3823fa68d82a7796c8" + integrity sha512-5rRpovujhLJufKRzMp5sl2BIIqrPeoXxjniQbzkpSxZ2vnD+bE9xOoaciHQxOsmXfXhza0C+k3xYMM5+B/bVzg== dependencies: - "@lerna/npm-conf" "4.0.0" - npm-lifecycle "^3.1.5" - npmlog "^4.1.2" + "@lerna/npm-conf" "5.1.8" + "@npmcli/run-script" "^3.0.2" + npmlog "^6.0.2" -"@lerna/run-topologically@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/run-topologically/-/run-topologically-4.0.0.tgz#af846eeee1a09b0c2be0d1bfb5ef0f7b04bb1827" - integrity sha512-EVZw9hGwo+5yp+VL94+NXRYisqgAlj0jWKWtAIynDCpghRxCE5GMO3xrQLmQgqkpUl9ZxQFpICgYv5DW4DksQA== +"@lerna/run-topologically@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/run-topologically/-/run-topologically-5.1.8.tgz#5c49ab5ebf0a871c5f705db74648d0023448c387" + integrity sha512-isuulfBdNsrgV2QF/HwCKCecfR9mPEU9N4Nf8n9nQQgakwOscoDlwGp2xv27pvcQKI52q/o/ISEjz3JeoEQiOA== dependencies: - "@lerna/query-graph" "4.0.0" + "@lerna/query-graph" "5.1.8" p-queue "^6.6.2" -"@lerna/run@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/run/-/run-4.0.0.tgz#4bc7fda055a729487897c23579694f6183c91262" - integrity sha512-9giulCOzlMPzcZS/6Eov6pxE9gNTyaXk0Man+iCIdGJNMrCnW7Dme0Z229WWP/UoxDKg71F2tMsVVGDiRd8fFQ== - dependencies: - "@lerna/command" "4.0.0" - "@lerna/filter-options" "4.0.0" - "@lerna/npm-run-script" "4.0.0" - "@lerna/output" "4.0.0" - "@lerna/profiler" "4.0.0" - "@lerna/run-topologically" "4.0.0" - "@lerna/timer" "4.0.0" - "@lerna/validation-error" "4.0.0" +"@lerna/run@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-5.1.8.tgz#ede8db4df9ae19e87e1cc372a820f29a9ef5079b" + integrity sha512-E5mI3FswVN9zQ3bCYUQxxPlLL400vnKpwLSzzRNFy//TR8Geu0LeR6NY+Jf0jklsKxwWGMJgqL6VqPqxDaNtdw== + dependencies: + "@lerna/command" "5.1.8" + "@lerna/filter-options" "5.1.8" + "@lerna/npm-run-script" "5.1.8" + "@lerna/output" "5.1.8" + "@lerna/profiler" "5.1.8" + "@lerna/run-topologically" "5.1.8" + "@lerna/timer" "5.1.8" + "@lerna/validation-error" "5.1.8" p-map "^4.0.0" -"@lerna/symlink-binary@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-4.0.0.tgz#21009f62d53a425f136cb4c1a32c6b2a0cc02d47" - integrity sha512-zualodWC4q1QQc1pkz969hcFeWXOsVYZC5AWVtAPTDfLl+TwM7eG/O6oP+Rr3fFowspxo6b1TQ6sYfDV6HXNWA== +"@lerna/symlink-binary@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-5.1.8.tgz#0e92997547d13d3da7efe437ecad64b919ff0383" + integrity sha512-s7VfKNJZnWvTKZ7KR8Yxh1rYhE/ARMioD5axyu3FleS3Xsdla2M5sQsLouCrdfM3doTO8lMxPVvVSFmL7q0KOA== dependencies: - "@lerna/create-symlink" "4.0.0" - "@lerna/package" "4.0.0" + "@lerna/create-symlink" "5.1.8" + "@lerna/package" "5.1.8" fs-extra "^9.1.0" p-map "^4.0.0" -"@lerna/symlink-dependencies@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-4.0.0.tgz#8910eca084ae062642d0490d8972cf2d98e9ebbd" - integrity sha512-BABo0MjeUHNAe2FNGty1eantWp8u83BHSeIMPDxNq0MuW2K3CiQRaeWT3EGPAzXpGt0+hVzBrA6+OT0GPn7Yuw== +"@lerna/symlink-dependencies@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-5.1.8.tgz#a8738d122b4274397e65a565d444540b9a10df61" + integrity sha512-U5diiaKdWUlvoFMh3sYIEESBLa8Z3Q/EpkLl5o4YkcbPBjFHJFpmoqCGomwL9sf9HQUV2S9Lt9szJT8qgQm86Q== dependencies: - "@lerna/create-symlink" "4.0.0" - "@lerna/resolve-symlink" "4.0.0" - "@lerna/symlink-binary" "4.0.0" + "@lerna/create-symlink" "5.1.8" + "@lerna/resolve-symlink" "5.1.8" + "@lerna/symlink-binary" "5.1.8" fs-extra "^9.1.0" p-map "^4.0.0" p-map-series "^2.1.0" -"@lerna/timer@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-4.0.0.tgz#a52e51bfcd39bfd768988049ace7b15c1fd7a6da" - integrity sha512-WFsnlaE7SdOvjuyd05oKt8Leg3ENHICnvX3uYKKdByA+S3g+TCz38JsNs7OUZVt+ba63nC2nbXDlUnuT2Xbsfg== - -"@lerna/validation-error@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-4.0.0.tgz#af9d62fe8304eaa2eb9a6ba1394f9aa807026d35" - integrity sha512-1rBOM5/koiVWlRi3V6dB863E1YzJS8v41UtsHgMr6gB2ncJ2LsQtMKlJpi3voqcgh41H8UsPXR58RrrpPpufyw== +"@lerna/temp-write@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/temp-write/-/temp-write-5.1.8.tgz#e3e16743160fdde2fadbff6e1855c4050495b38e" + integrity sha512-4/guYB5XotugyM8P/F1z6b+hNlSCe/QuZsmiZwgXOw2lmYnkSzLWDVjqsdZtNYqojK0lioxcPjZiL5qnEkk1PQ== dependencies: - npmlog "^4.1.2" - -"@lerna/version@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/version/-/version-4.0.0.tgz#532659ec6154d8a8789c5ab53878663e244e3228" - integrity sha512-otUgiqs5W9zGWJZSCCMRV/2Zm2A9q9JwSDS7s/tlKq4mWCYriWo7+wsHEA/nPTMDyYyBO5oyZDj+3X50KDUzeA== - dependencies: - "@lerna/check-working-tree" "4.0.0" - "@lerna/child-process" "4.0.0" - "@lerna/collect-updates" "4.0.0" - "@lerna/command" "4.0.0" - "@lerna/conventional-commits" "4.0.0" - "@lerna/github-client" "4.0.0" - "@lerna/gitlab-client" "4.0.0" - "@lerna/output" "4.0.0" - "@lerna/prerelease-id-from-version" "4.0.0" - "@lerna/prompt" "4.0.0" - "@lerna/run-lifecycle" "4.0.0" - "@lerna/run-topologically" "4.0.0" - "@lerna/validation-error" "4.0.0" + graceful-fs "^4.1.15" + is-stream "^2.0.0" + make-dir "^3.0.0" + temp-dir "^1.0.0" + uuid "^8.3.2" + +"@lerna/timer@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-5.1.8.tgz#8613aca7ed121a7c9f73f754a5b07e9891bf2e5e" + integrity sha512-Ua4bw2YOO3U+sFujE+MsUG+lllU0X7u6PCTj1QKe0QlR0zr2gCa0pcwjUQPdNfxnpJpPY+hdbfTUv2viDloaiA== + +"@lerna/validation-error@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-5.1.8.tgz#e12f6ee6bb9bd18bc1f3b2d0ae3045882d2a4f32" + integrity sha512-n+IiaxN2b08ZMYnezsmwL6rXB15/VvweusC04GMh1XtWunnMzSg9JDM7y6bw2vfpBBQx6cBFhLKSpD2Fcq5D5Q== + dependencies: + npmlog "^6.0.2" + +"@lerna/version@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-5.1.8.tgz#fa2034bbbbcdaf5493d6235109f6e4813f8f7a60" + integrity sha512-3f4P7KjIs6Gn2iaGkA5EASE9izZeDKtEzE8i2DE7YfVdw/P+EwFfKv2mKBXGbckYw42YO1tL6aD2QH0C8XbwlA== + dependencies: + "@lerna/check-working-tree" "5.1.8" + "@lerna/child-process" "5.1.8" + "@lerna/collect-updates" "5.1.8" + "@lerna/command" "5.1.8" + "@lerna/conventional-commits" "5.1.8" + "@lerna/github-client" "5.1.8" + "@lerna/gitlab-client" "5.1.8" + "@lerna/output" "5.1.8" + "@lerna/prerelease-id-from-version" "5.1.8" + "@lerna/prompt" "5.1.8" + "@lerna/run-lifecycle" "5.1.8" + "@lerna/run-topologically" "5.1.8" + "@lerna/temp-write" "5.1.8" + "@lerna/validation-error" "5.1.8" chalk "^4.1.0" dedent "^0.7.0" load-json-file "^6.2.0" minimatch "^3.0.4" - npmlog "^4.1.2" + npmlog "^6.0.2" p-map "^4.0.0" p-pipe "^3.1.0" p-reduce "^2.1.0" p-waterfall "^2.1.1" semver "^7.3.4" slash "^3.0.0" - temp-write "^4.0.0" write-json-file "^4.3.0" -"@lerna/write-log-file@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-4.0.0.tgz#18221a38a6a307d6b0a5844dd592ad53fa27091e" - integrity sha512-XRG5BloiArpXRakcnPHmEHJp+4AtnhRtpDIHSghmXD5EichI1uD73J7FgPp30mm2pDRq3FdqB0NbwSEsJ9xFQg== +"@lerna/write-log-file@5.1.8": + version "5.1.8" + resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-5.1.8.tgz#b464c7fab43c14adb96ba41d92900b8907d8d14d" + integrity sha512-B+shMH3TpzA7Q5GGbuNkOmdPQdD1LXRFj7R17LINkn82PhP9CUgubwYuiVzrLa16ADi0V5Ad76pqtHi/6kD0nA== dependencies: - npmlog "^4.1.2" + npmlog "^6.0.2" write-file-atomic "^3.0.3" "@nodelib/fs.scandir@2.1.5": @@ -1134,6 +839,46 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@npmcli/arborist@5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-5.2.0.tgz#ee40dfe1f81ae1524819ee39c8f3e7022b0d6269" + integrity sha512-zWV7scFGL0SmpvfQyIWnMFbU/0YgtMNyvJiJwR98kyjUSntJGWFFR0O600d5W+TrDcTg0GyDbY+HdzGEg+GXLg== + dependencies: + "@isaacs/string-locale-compare" "^1.1.0" + "@npmcli/installed-package-contents" "^1.0.7" + "@npmcli/map-workspaces" "^2.0.3" + "@npmcli/metavuln-calculator" "^3.0.1" + "@npmcli/move-file" "^2.0.0" + "@npmcli/name-from-folder" "^1.0.1" + "@npmcli/node-gyp" "^2.0.0" + "@npmcli/package-json" "^2.0.0" + "@npmcli/run-script" "^3.0.0" + bin-links "^3.0.0" + cacache "^16.0.6" + common-ancestor-path "^1.0.1" + json-parse-even-better-errors "^2.3.1" + json-stringify-nice "^1.1.4" + mkdirp "^1.0.4" + mkdirp-infer-owner "^2.0.0" + nopt "^5.0.0" + npm-install-checks "^5.0.0" + npm-package-arg "^9.0.0" + npm-pick-manifest "^7.0.0" + npm-registry-fetch "^13.0.0" + npmlog "^6.0.2" + pacote "^13.0.5" + parse-conflict-json "^2.0.1" + proc-log "^2.0.0" + promise-all-reject-late "^1.0.0" + promise-call-limit "^1.0.1" + read-package-json-fast "^2.0.2" + readdir-scoped-modules "^1.1.0" + rimraf "^3.0.2" + semver "^7.3.7" + ssri "^9.0.0" + treeverse "^2.0.0" + walk-up-path "^1.0.0" + "@npmcli/ci-detect@^1.0.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz#18478bbaa900c37bfbd8a2006a6262c62e8b0fe1" @@ -1155,21 +900,22 @@ "@gar/promisify" "^1.1.3" semver "^7.3.5" -"@npmcli/git@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6" - integrity sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw== +"@npmcli/git@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-3.0.1.tgz#049b99b1381a2ddf7dc56ba3e91eaf76ca803a8d" + integrity sha512-UU85F/T+F1oVn3IsB/L6k9zXIMpXBuUBE25QDH0SsURwT6IOBqkC7M16uqo2vVZIyji3X1K4XH9luip7YekH1A== dependencies: - "@npmcli/promise-spawn" "^1.3.2" - lru-cache "^6.0.0" + "@npmcli/promise-spawn" "^3.0.0" + lru-cache "^7.4.4" mkdirp "^1.0.4" - npm-pick-manifest "^6.1.1" + npm-pick-manifest "^7.0.0" + proc-log "^2.0.0" promise-inflight "^1.0.1" promise-retry "^2.0.1" semver "^7.3.5" which "^2.0.2" -"@npmcli/installed-package-contents@^1.0.6": +"@npmcli/installed-package-contents@^1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== @@ -1177,6 +923,26 @@ npm-bundled "^1.1.1" npm-normalize-package-bin "^1.0.1" +"@npmcli/map-workspaces@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-2.0.3.tgz#2d3c75119ee53246e9aa75bc469a55281cd5f08f" + integrity sha512-X6suAun5QyupNM8iHkNPh0AHdRC2rb1W+MTdMvvA/2ixgmqZwlq5cGUBgmKHUHT2LgrkKJMAXbfAoTxOigpK8Q== + dependencies: + "@npmcli/name-from-folder" "^1.0.1" + glob "^8.0.1" + minimatch "^5.0.1" + read-package-json-fast "^2.0.3" + +"@npmcli/metavuln-calculator@^3.0.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.1.tgz#9359bd72b400f8353f6a28a25c8457b562602622" + integrity sha512-n69ygIaqAedecLeVH3KnO39M6ZHiJ2dEv5A7DGvcqCB8q17BGUgW8QaanIkbWUo2aYGZqJaOORTLAlIvKjNDKA== + dependencies: + cacache "^16.0.0" + json-parse-even-better-errors "^2.3.1" + pacote "^13.0.3" + semver "^7.3.5" + "@npmcli/move-file@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" @@ -1193,37 +959,50 @@ mkdirp "^1.0.4" rimraf "^3.0.2" -"@npmcli/node-gyp@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33" - integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA== +"@npmcli/name-from-folder@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz#77ecd0a4fcb772ba6fe927e2e2e155fbec2e6b1a" + integrity sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA== -"@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" - integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== - dependencies: - infer-owner "^1.0.4" +"@npmcli/node-gyp@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz#8c20e53e34e9078d18815c1d2dda6f2420d75e35" + integrity sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A== -"@npmcli/run-script@^1.8.2": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.6.tgz#18314802a6660b0d4baa4c3afe7f1ad39d8c28b7" - integrity sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g== +"@npmcli/package-json@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-2.0.0.tgz#3bbcf4677e21055adbe673d9f08c9f9cde942e4a" + integrity sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA== dependencies: - "@npmcli/node-gyp" "^1.0.2" - "@npmcli/promise-spawn" "^1.3.2" - node-gyp "^7.1.0" - read-package-json-fast "^2.0.1" + json-parse-even-better-errors "^2.3.1" -"@npmcli/run-script@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-2.0.0.tgz#9949c0cab415b17aaac279646db4f027d6f1e743" - integrity sha512-fSan/Pu11xS/TdaTpTB0MRn9guwGU8dye+x56mEVgBEd/QsybBbYcAL0phPXi8SGWFEChkQd6M9qL4y6VOpFig== +"@npmcli/promise-spawn@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz#53283b5f18f855c6925f23c24e67c911501ef573" + integrity sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g== dependencies: - "@npmcli/node-gyp" "^1.0.2" - "@npmcli/promise-spawn" "^1.3.2" - node-gyp "^8.2.0" - read-package-json-fast "^2.0.1" + infer-owner "^1.0.4" + +"@npmcli/run-script@^3.0.0", "@npmcli/run-script@^3.0.2": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-3.0.3.tgz#66afa6e0c4c3484056195f295fa6c1d1a45ddf58" + integrity sha512-ZXL6qgC5NjwfZJ2nET+ZSLEz/PJgJ/5CU90C2S66dZY4Jw73DasS4ZCXuy/KHWYP0imjJ4VtA+Gebb5BxxKp9Q== + dependencies: + "@npmcli/node-gyp" "^2.0.0" + "@npmcli/promise-spawn" "^3.0.0" + node-gyp "^8.4.1" + read-package-json-fast "^2.0.3" + +"@npmcli/run-script@^4.1.0": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-4.1.5.tgz#d60a7d41321612a9c0e1433797c10c19d0213d55" + integrity sha512-FyrZkZ+O0bCnQqm+mRb6sKbEJgyJudInwFN84gCcMUcxrWkR15Ags1uOHwnxHYdpj3T5eqrCZNW/Ys20MGTQ6Q== + dependencies: + "@npmcli/node-gyp" "^2.0.0" + "@npmcli/promise-spawn" "^3.0.0" + node-gyp "^9.0.0" + read-package-json-fast "^2.0.3" + which "^2.0.2" "@octokit/auth-token@^2.4.4": version "2.5.0" @@ -1263,10 +1042,10 @@ "@octokit/types" "^6.0.3" universal-user-agent "^6.0.0" -"@octokit/openapi-types@^11.2.0": - version "11.2.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-11.2.0.tgz#b38d7fc3736d52a1e96b230c1ccd4a58a2f400a6" - integrity sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA== +"@octokit/openapi-types@^12.7.0": + version "12.8.0" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-12.8.0.tgz#f4708cf948724d6e8f7d878cfd91584c1c5c0523" + integrity sha512-ydcKLs2KKcxlhpdWLzJxEBDEk/U5MUeqtqkXlrtAUXXFPs6vLl1PEGghFC/BbpleosB7iXs0Z4P2DGe7ZT5ZNg== "@octokit/plugin-enterprise-rest@^6.0.1": version "6.0.1" @@ -1274,11 +1053,11 @@ integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== "@octokit/plugin-paginate-rest@^2.16.8": - version "2.17.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz#32e9c7cab2a374421d3d0de239102287d791bce7" - integrity sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw== + version "2.21.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.1.tgz#9ab7a21e9f35a6d5526a3082da3f8f43908449e4" + integrity sha512-NVNTK63yoTFp07GqISWK+uDfGH1CAPhQXS7LzsJBvaK5W+UlvG549pLZC55FK0FqANVl6q/9ra3SR5c97xF/sw== dependencies: - "@octokit/types" "^6.34.0" + "@octokit/types" "^6.38.2" "@octokit/plugin-request-log@^1.0.4": version "1.0.4" @@ -1286,11 +1065,11 @@ integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== "@octokit/plugin-rest-endpoint-methods@^5.12.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz#8c46109021a3412233f6f50d28786f8e552427ba" - integrity sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA== + version "5.16.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz#7ee8bf586df97dd6868cf68f641354e908c25342" + integrity sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw== dependencies: - "@octokit/types" "^6.34.0" + "@octokit/types" "^6.39.0" deprecation "^2.3.1" "@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0": @@ -1324,12 +1103,27 @@ "@octokit/plugin-request-log" "^1.0.4" "@octokit/plugin-rest-endpoint-methods" "^5.12.0" -"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.34.0": - version "6.34.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.34.0.tgz#c6021333334d1ecfb5d370a8798162ddf1ae8218" - integrity sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw== +"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.38.2", "@octokit/types@^6.39.0": + version "6.39.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.39.0.tgz#46ce28ca59a3d4bac0e487015949008302e78eee" + integrity sha512-Mq4N9sOAYCitTsBtDdRVrBE80lIrMBhL9Jbrw0d+j96BAzlq4V+GLHFJbHokEsVvO/9tQupQdoFdgVYhD2C8UQ== + dependencies: + "@octokit/openapi-types" "^12.7.0" + +"@pnpm/network.ca-file@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@pnpm/network.ca-file/-/network.ca-file-1.0.1.tgz#16f88d057c68cd5419c1ef3dfa281296ea80b047" + integrity sha512-gkINruT2KUhZLTaiHxwCOh1O4NVnFT0wLjWFBHmTz9vpKag/C/noIMJXBxFe4F0mYpUVX2puLwAieLYFg2NvoA== + dependencies: + graceful-fs "4.2.10" + +"@pnpm/npm-conf@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-1.0.4.tgz#e2c927a933f55e9211e12ef6cc4885ce915211ce" + integrity sha512-o5YFq/+ksEJMbSzzkaQDHlp00aonLDU5xNPVTRL12hTWBbVSSeWXxPukq75h+mvXnoOWT95vV2u1HSTw2C4XOw== dependencies: - "@octokit/openapi-types" "^11.2.0" + "@pnpm/network.ca-file" "^1.0.1" + config-chain "^1.1.11" "@sideway/address@^4.1.3": version "4.1.4" @@ -1348,52 +1142,17 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@sindresorhus/is@^4.0.0": +"@sindresorhus/is@^4.6.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== -"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.3": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@>=5": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sinonjs/fake-timers@^7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" - integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sinonjs/samsam@^6.0.2": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-6.1.1.tgz#627f7f4cbdb56e6419fa2c1a3e4751ce4f6a00b1" - integrity sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA== - dependencies: - "@sinonjs/commons" "^1.6.0" - lodash.get "^4.4.2" - type-detect "^4.0.8" - -"@sinonjs/text-encoding@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" - integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== - -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== dependencies: - defer-to-connect "^2.0.0" + defer-to-connect "^2.0.1" "@tootallnate/once@1": version "1.1.2" @@ -1405,7 +1164,42 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/cacheable-request@^6.0.1": +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + +"@types/accepts@*": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== + dependencies: + "@types/node" "*" + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/cacheable-request@^6.0.2": version "6.0.2" resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== @@ -1415,20 +1209,124 @@ "@types/node" "*" "@types/responselike" "*" +"@types/chai-as-promised@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" + integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.1.tgz#e2c6e73e0bdeb2521d00756d099218e9f5d90a04" + integrity sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ== + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/content-disposition@*": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.5.tgz#650820e95de346e1f84e30667d168c8fd25aa6e3" + integrity sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA== + +"@types/cookies@*": + version "0.7.7" + resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.7.7.tgz#7a92453d1d16389c05a5301eef566f34946cfd81" + integrity sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA== + dependencies: + "@types/connect" "*" + "@types/express" "*" + "@types/keygrip" "*" + "@types/node" "*" + +"@types/cross-spawn@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.2.tgz#168309de311cd30a2b8ae720de6475c2fbf33ac7" + integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== + dependencies: + "@types/node" "*" + +"@types/ejs@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.1.tgz#29c539826376a65e7f7d672d51301f37ed718f6d" + integrity sha512-RQul5wEfY7BjWm0sYY86cmUN/pcXWGyVxWX93DFFJvcrxax5zKlieLwA3T77xJGwNcZW0YW6CYG70p1m8xPFmA== + +"@types/express-serve-static-core@^4.17.18": + version "4.17.29" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz#2a1795ea8e9e9c91b4a4bbe475034b20c1ec711c" + integrity sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/fs-extra@^9.0.13": + version "9.0.13" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.13.tgz#7594fbae04fe7f1918ce8b3d213f74ff44ac1f45" + integrity sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA== + dependencies: + "@types/node" "*" + +"@types/http-assert@*": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.3.tgz#ef8e3d1a8d46c387f04ab0f2e8ab8cb0c5078661" + integrity sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA== + "@types/http-cache-semantics@*": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== +"@types/http-errors@*": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.2.tgz#7315b4c4c54f82d13fa61c228ec5c2ea5cc9e0e1" + integrity sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w== + +"@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + "@types/json-buffer@~3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/json-buffer/-/json-buffer-3.0.0.tgz#85c1ff0f0948fc159810d4b5be35bf8c20875f64" integrity sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ== +"@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/jws@^3.2.4": + version "3.2.4" + resolved "https://registry.yarnpkg.com/@types/jws/-/jws-3.2.4.tgz#153638ce95d1b0b7cdb4d252f3ada2441431b3df" + integrity sha512-aqtH4dPw1wUjFZaeMD1ak/pf8iXlu/odFe+trJrvw0g1sTh93i+SCykg0Ek8C6B7rVK3oBORbfZAsKO7P10etg== + dependencies: + "@types/node" "*" + +"@types/keygrip@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" + integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== "@types/keyv@*": version "3.1.4" @@ -1437,30 +1335,164 @@ dependencies: "@types/node" "*" -"@types/minimatch@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== +"@types/koa-bodyparser@^4.3.7": + version "4.3.7" + resolved "https://registry.yarnpkg.com/@types/koa-bodyparser/-/koa-bodyparser-4.3.7.tgz#3ac41f2dec9d97db7a6f798bbb2e2368be762714" + integrity sha512-21NhEp7LjZm4zbNV5alHHmrNY4J+S7B8lYTO6CzRL8ShTMnl20Gd14dRgVhAxraLaW5iZMofox+BycbuiDvj2Q== + dependencies: + "@types/koa" "*" -"@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== +"@types/koa-compose@*": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d" + integrity sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ== + dependencies: + "@types/koa" "*" -"@types/node@*": - version "17.0.32" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.32.tgz#51d59d7a90ef2d0ae961791e0900cad2393a0149" - integrity sha512-eAIcfAvhf/BkHcf4pkLJ7ECpBAhh9kcxRBpip9cTiO+hf+aJrsxYxBeS6OXvOd9WqNAJmavXVpZvY1rBjNsXmw== +"@types/koa-session@^5.10.6": + version "5.10.6" + resolved "https://registry.yarnpkg.com/@types/koa-session/-/koa-session-5.10.6.tgz#879d677cc454c784c50a58ece52bb0e071db3092" + integrity sha512-p4rgkeRmiJu8XGC3eH2duRCNgnLUl6sjadEXH/AsieH/9fqYfXSZoZNC9CAe+FQK+QmM76hVyvuJ5Jrl5xxNeA== + dependencies: + "@types/cookies" "*" + "@types/koa" "*" -"@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== +"@types/koa@*", "@types/koa@^2.13.4": + version "2.13.4" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.13.4.tgz#10620b3f24a8027ef5cbae88b393d1b31205726b" + integrity sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw== + dependencies: + "@types/accepts" "*" + "@types/content-disposition" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/http-errors" "*" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/koa__router@^8.0.11": + version "8.0.11" + resolved "https://registry.yarnpkg.com/@types/koa__router/-/koa__router-8.0.11.tgz#d7b37e6db934fc072ea1baa2ab92bc8ac4564f3e" + integrity sha512-WXgKWpBsbS14kzmzD9LeFapOIa678h7zvUHxDwXwSx4ETKXhXLVUAToX6jZ/U7EihM7qwyD9W/BZvB0MRu7MTQ== + dependencies: + "@types/koa" "*" + +"@types/libnpmsearch@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/libnpmsearch/-/libnpmsearch-2.0.3.tgz#6a7bba71e533d5344cd04ceac4fe81b6b1ab9ceb" + integrity sha512-f/tTUDiOaUNk+m1mfvXO4/7ZasYUaKdosLgvzMdrFHNFqJENqwT9kKE+Gd6N3nsoD5kCZ7q4Pw7ApPIjXQArbA== + dependencies: + "@types/node" "*" + "@types/npm-registry-fetch" "*" + +"@types/lodash.get@^4.4.7": + version "4.4.7" + resolved "https://registry.yarnpkg.com/@types/lodash.get/-/lodash.get-4.4.7.tgz#1ea63d8b94709f6bc9e231f252b31440abe312cf" + integrity sha512-af34Mj+KdDeuzsJBxc/XeTtOx0SZHZNLd+hdrn+PcKGQs0EG2TJTzQAOTCZTgDJCArahlCzLWSy8c2w59JRz7Q== + dependencies: + "@types/lodash" "*" + +"@types/lodash.set@^4.3.7": + version "4.3.7" + resolved "https://registry.yarnpkg.com/@types/lodash.set/-/lodash.set-4.3.7.tgz#784fccea3fbef4d0949d1897a780f592da700942" + integrity sha512-bS5Wkg/nrT82YUfkNYPSccFrNZRL+irl7Yt4iM6OTSQ0VZJED2oUIVm15NkNtUAQ8SRhCe+axqERUV6MJgkeEg== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.182" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" + integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/minimatch@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + +"@types/minimist@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" + integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + +"@types/mocha@^9.1.1": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== + +"@types/node-fetch@*": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" + integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*", "@types/node@^18.0.3": + version "18.0.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.3.tgz#463fc47f13ec0688a33aec75d078a0541a447199" + integrity sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ== + +"@types/normalize-package-data@^2.4.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + +"@types/npm-package-arg@*", "@types/npm-package-arg@^6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@types/npm-package-arg/-/npm-package-arg-6.1.1.tgz#9e2d8adc04d39824a3d9f36f738010a3f7da3c1a" + integrity sha512-452/1Kp9IdM/oR10AyqAgZOxUt7eLbm+EMJ194L6oarMYdZNiFIFAOJ7IIr0OrZXTySgfHjJezh2oiyk2kc3ag== + +"@types/npm-registry-fetch@*": + version "8.0.4" + resolved "https://registry.yarnpkg.com/@types/npm-registry-fetch/-/npm-registry-fetch-8.0.4.tgz#77b2737cde22314ccda1dfdb9568fd7769e95b90" + integrity sha512-R9yEj6+NDmXLpKNS19cIaMyaHfV0aHjy/1qbo8K9jiHyjyaYg0CEmuOV/L0Q91DZDi3SuxlYY+2XYwh9TbB+eQ== + dependencies: + "@types/node" "*" + "@types/node-fetch" "*" + "@types/npm-package-arg" "*" + "@types/npmlog" "*" + "@types/ssri" "*" + +"@types/npmlog@*": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.4.tgz#30eb872153c7ead3e8688c476054ddca004115f6" + integrity sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ== + +"@types/pacote@^11.1.5": + version "11.1.5" + resolved "https://registry.yarnpkg.com/@types/pacote/-/pacote-11.1.5.tgz#3efc5eb49069206a678f5483a7e008af06788a66" + integrity sha512-kMsfmhP2G45ngnpvH0LKd1celWnjgdiws1FHu3vMmYuoElGdqnd0ydf1ucZzeXamYnLe0NvSzGP2gYiETOEiQA== + dependencies: + "@types/node" "*" + "@types/npm-registry-fetch" "*" + "@types/npmlog" "*" + "@types/ssri" "*" + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/pluralize@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/pluralize/-/pluralize-0.0.29.tgz#6ffa33ed1fc8813c469b859681d09707eb40d03c" + integrity sha512-BYOID+l2Aco2nBik+iYS4SZX0Lf20KPILP5RGmM1IgzdwNdTs0eebiFriOPcej1sX9mLnSoiNte5zcFxssgpGA== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" @@ -1469,15 +1501,137 @@ dependencies: "@types/node" "*" +"@types/semver@^7.3.10": + version "7.3.10" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.10.tgz#5f19ee40cbeff87d916eedc8c2bfe2305d957f73" + integrity sha512-zsv3fsC7S84NN6nPK06u79oWgrPVd0NvOyqgghV1haPaFcVxIrP4DLomRwGAXk0ui4HZA7mOcSFL98sMVW9viw== + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/set-cookie-parser@^2.4.2": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz#b6a955219b54151bfebd4521170723df5e13caad" + integrity sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w== + dependencies: + "@types/node" "*" + +"@types/ssri@*": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/ssri/-/ssri-7.1.1.tgz#2a2c94abf0d3a8c3b07bb4ff08142dd571407bb5" + integrity sha512-DPP/jkDaqGiyU75MyMURxLWyYLwKSjnAuGe9ZCsLp9QZOpXmDfuevk769F0BS86TmRuD5krnp06qw9nSoNO+0g== + dependencies: + "@types/node" "*" + +"@types/tmp@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.3.tgz#908bfb113419fd6a42273674c00994d40902c165" + integrity sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA== + +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + +"@types/which@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/which/-/which-2.0.1.tgz#27ecd67f915b7c3d6ba552135bb1eecd66e63501" + integrity sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ== + +"@typescript-eslint/eslint-plugin@^5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.5.tgz#e9a0afd6eb3b1d663db91cf1e7bc7584d394503d" + integrity sha512-lftkqRoBvc28VFXEoRgyZuztyVUQ04JvUnATSPtIRFAccbXTWL6DEtXGYMcbg998kXw1NLUJm7rTQ9eUt+q6Ig== + dependencies: + "@typescript-eslint/scope-manager" "5.30.5" + "@typescript-eslint/type-utils" "5.30.5" + "@typescript-eslint/utils" "5.30.5" + debug "^4.3.4" + functional-red-black-tree "^1.0.1" + ignore "^5.2.0" + regexpp "^3.2.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.5.tgz#f667c34e4e4c299d98281246c9b1e68c03a92522" + integrity sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q== + dependencies: + "@typescript-eslint/scope-manager" "5.30.5" + "@typescript-eslint/types" "5.30.5" + "@typescript-eslint/typescript-estree" "5.30.5" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz#7f90b9d6800552c856a5f3644f5e55dd1469d964" + integrity sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg== + dependencies: + "@typescript-eslint/types" "5.30.5" + "@typescript-eslint/visitor-keys" "5.30.5" + +"@typescript-eslint/type-utils@5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.30.5.tgz#7a9656f360b4b1daea635c4621dab053d08bf8a9" + integrity sha512-k9+ejlv1GgwN1nN7XjVtyCgE0BTzhzT1YsQF0rv4Vfj2U9xnslBgMYYvcEYAFVdvhuEscELJsB7lDkN7WusErw== + dependencies: + "@typescript-eslint/utils" "5.30.5" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.5.tgz#36a0c05a72af3623cdf9ee8b81ea743b7de75a98" + integrity sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw== + +"@typescript-eslint/typescript-estree@5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz#c520e4eba20551c4ec76af8d344a42eb6c9767bb" + integrity sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ== + dependencies: + "@typescript-eslint/types" "5.30.5" + "@typescript-eslint/visitor-keys" "5.30.5" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.30.5.tgz#3999cbd06baad31b9e60d084f20714d1b2776765" + integrity sha512-o4SSUH9IkuA7AYIfAvatldovurqTAHrfzPApOZvdUq01hHojZojCFXx06D/aFpKCgWbMPRdJBWAC3sWp3itwTA== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.30.5" + "@typescript-eslint/types" "5.30.5" + "@typescript-eslint/typescript-estree" "5.30.5" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.30.5": + version "5.30.5" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz#d4bb969202019d5d5d849a0aaedc7370cc044b14" + integrity sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA== + dependencies: + "@typescript-eslint/types" "5.30.5" + eslint-visitor-keys "^3.3.0" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== -"@xmldom/xmldom@^0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d" - integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A== +"@xmldom/xmldom@^0.8.2": + version "0.8.2" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.2.tgz#b695ff674e8216efa632a3d36ad51ae9843380c0" + integrity sha512-+R0juSseERyoPvnBQ/cZih6bpF7IpCXlWbHRoCRzYzqpz6gWHOgf8o4MOEf6KBVuOyqU+gCNLkCWVIJAro8XyQ== JSONStream@^1.0.4: version "1.3.5" @@ -1487,11 +1641,6 @@ JSONStream@^1.0.4: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" - integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4= - abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -1505,37 +1654,25 @@ accepts@^1.3.5: mime-types "~2.1.34" negotiator "0.6.3" -acorn-globals@^1.0.4: - version "1.0.9" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-1.0.9.tgz#55bb5e98691507b74579d0513413217c380c54cf" - integrity sha1-VbtemGkVB7dFedBRNBMhfDgMVM8= - dependencies: - acorn "^2.1.0" - -acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^2.1.0, acorn@^2.4.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" - integrity sha1-q259nYhqrKiwhbwzEreaGYQz8Oc= - -acorn@^6.4.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^7.1.1, acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.4.1, acorn@^8.7.1: + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo= + integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== agent-base@6, agent-base@^6.0.2: version "6.0.2" @@ -1561,7 +1698,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1571,41 +1708,22 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-align@^3.0.0: +ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== dependencies: string-width "^4.1.0" -ansi-colors@4.1.1, ansi-colors@^4.1.1: +ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-colors@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" - integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== - dependencies: - ansi-wrap "^0.1.0" - -ansi-cyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" - integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= - dependencies: - ansi-wrap "0.1.0" +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.2" @@ -1614,41 +1732,17 @@ ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" - integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= - dependencies: - ansi-wrap "0.1.0" - -ansi-red@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" - integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= - dependencies: - ansi-wrap "0.1.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1662,18 +1756,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-wrap@0.1.0, ansi-wrap@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" +ansi-styles@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" + integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== anymatch@~3.1.2: version "3.1.2" @@ -1683,54 +1769,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -appcd-fs@^2.0.7: - version "2.1.2" - resolved "https://registry.yarnpkg.com/appcd-fs/-/appcd-fs-2.1.2.tgz#89f6eee2354a1742eba81d9f225550fd8abae366" - integrity sha512-nScYBOi4lZysEQ6dJD1h0eGECnVRbPoPkKR++5dFbGWg/Xf+ixEXy0KZzn/fFK0EptYZVK9DNy9SKiK8SFCoiw== - dependencies: - source-map-support "^0.5.19" - tmp "^0.2.1" - -appcd-util@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/appcd-util/-/appcd-util-3.1.6.tgz#dc05ca03bb63162046ec4dbf690fc55e8a244e86" - integrity sha512-SToNKGhVHNe1Q6DOWi8GFbm20tVz8ZoQggwZPL448Kn2+xr+CB9p/7tujzji4oH3IUSWkYJgY5lmMW4tTQpUeg== - dependencies: - appcd-fs "^2.0.7" - lodash.get "^4.4.2" - lodash.set "^4.3.2" - semver "^7.3.5" - source-map-support "^0.5.19" - -append-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" - integrity sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE= - dependencies: - buffer-equal "^1.0.0" - -append-transform@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-2.0.0.tgz#99d9d29c7b38391e6f428d28ce136551f0b77e12" - integrity sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg== - dependencies: - default-require-extensions "^3.0.0" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - "aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - are-we-there-yet@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" @@ -1739,20 +1782,10 @@ are-we-there-yet@^3.0.0: delegates "^1.0.0" readable-stream "^3.6.0" -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== argparse@^2.0.1: version "2.0.1" @@ -1762,69 +1795,17 @@ argparse@^2.0.1: argv-split@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argv-split/-/argv-split-2.0.1.tgz#be264117790dbd5ccd63ec3f449a1804814ac4c5" - integrity sha1-viZBF3kNvVzNY+w/RJoYBIFKxMU= - -arr-diff@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" - integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= - dependencies: - arr-flatten "^1.0.1" - array-slice "^0.2.3" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-filter@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" - integrity sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4= - dependencies: - make-iterator "^1.0.0" - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-map@^2.0.0, arr-map@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" - integrity sha1-Onc0X/wc814qkYJWAfnljy4kysQ= - dependencies: - make-iterator "^1.0.0" - -arr-union@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" - integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + integrity sha512-qp4ts4VbGX40y4xPdIrmKGXL3RK9mJ1ia5lnluS5vq9vL4oVtT0nIiYJNBrccd/66N376W7CUdiQI0tj28DlHw== array-differ@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== -array-each@^1.0.0, array-each@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" - integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= - array-ify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= + integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== array-includes@^3.1.4: version "3.1.5" @@ -1837,55 +1818,11 @@ array-includes@^3.1.4: get-intrinsic "^1.1.1" is-string "^1.0.7" -array-initial@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" - integrity sha1-L6dLJnOTccOUe9enrcc74zSz15U= - dependencies: - array-slice "^1.0.0" - is-number "^4.0.0" - -array-last@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" - integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== - dependencies: - is-number "^4.0.0" - -array-slice@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" - integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= - -array-slice@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" - integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== - -array-sort@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" - integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== - dependencies: - default-compare "^1.0.0" - get-value "^2.0.6" - kind-of "^5.0.2" - 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.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - array.prototype.flat@^1.2.5: version "1.3.0" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" @@ -1896,10 +1833,10 @@ array.prototype.flat@^1.2.5: es-abstract "^1.19.2" es-shim-unscopables "^1.0.0" -arrify@^1.0.1: +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== arrify@^2.0.1: version "2.0.1" @@ -1909,259 +1846,66 @@ arrify@^2.0.1: asap@^2.0.0: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async-done@^1.2.0, async-done@^1.2.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" - integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.2" - process-nextick-args "^2.0.0" - stream-exhaust "^1.0.1" - -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== - -async-settle@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" - integrity sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs= - dependencies: - async-done "^1.2.2" - async@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" - integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-generator@6.11.4: - version "6.11.4" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.11.4.tgz#14f6933abb20c62666d27e3b7b9f5b9dc0712a9a" - integrity sha1-FPaTOrsgxiZm0n47e59bncBxKpo= - dependencies: - babel-messages "^6.8.0" - babel-runtime "^6.9.0" - babel-types "^6.10.2" - detect-indent "^3.0.1" - lodash "^4.2.0" - source-map "^0.5.0" - -babel-generator@6.26.1: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-messages@^6.23.0, babel-messages@^6.8.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-source-map-support@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/babel-plugin-source-map-support/-/babel-plugin-source-map-support-2.1.3.tgz#e9de94e883a16beb871e205dc3f6d700cc2384de" - integrity sha512-BV5X1sJ6TmL8BUonudz4/9dRaxAJty/MMc6AjwnTLPsdnf6LfVGncDyI/3wDCF/2OA0xXjsWkJHUPrNU5N0EEg== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - -babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-traverse@6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.10.2, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@6.18.0, babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - -bach@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" - integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA= - dependencies: - arr-filter "^1.1.1" - arr-flatten "^1.0.1" - arr-map "^2.0.0" - array-each "^1.0.0" - array-initial "^1.0.0" - array-last "^1.1.1" - async-done "^1.2.2" - async-settle "^1.0.0" - now-and-later "^2.0.0" - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.1.2, base64-js@^1.3.1: +base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -beeper@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" - integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= - before-after-hook@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +bin-links@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-3.0.1.tgz#cc70ffb481988b22c527d3e6e454787876987a49" + integrity sha512-9vx+ypzVhASvHTS6K+YSGf7nwQdANoz7v6MTC0aCtYnOEZ87YvMf81aY737EZnGZdpbRM3sfWjO9oWkKmuIvyQ== + dependencies: + cmd-shim "^5.0.0" + mkdirp-infer-owner "^2.0.0" + npm-normalize-package-bin "^1.0.0" + read-cmd-shim "^3.0.0" + rimraf "^3.0.0" + write-file-atomic "^4.0.0" binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bl@^4.0.3, bl@^4.1.0: +bl@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -2170,24 +1914,28 @@ bl@^4.0.3, bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - -boxen@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== +bl@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-5.0.0.tgz#6928804a41e9da9034868e1c50ca88f21f57aea2" + integrity sha512-8vxFNZ0pflFfi0WXA3WQXlj6CaMEwsmh63I1CNp0q+wWv8sD0ARx1KovSQd0l2GkwrMIOyedq0EF1FxI+RCZLQ== dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" + buffer "^6.0.3" + inherits "^2.0.4" + readable-stream "^3.4.0" + +boxen@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32" + integrity sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg== + dependencies: + ansi-align "^3.0.1" + camelcase "^7.0.0" + chalk "^5.0.1" + cli-boxes "^3.0.0" + string-width "^5.1.2" + type-fest "^2.13.0" + widest-line "^4.0.1" + wrap-ansi "^8.0.1" brace-expansion@^1.1.7: version "1.1.11" @@ -2204,22 +1952,6 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -2227,47 +1959,22 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -brotli@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.2.tgz#525a9cad4fcba96475d7d388f6aecb13eed52f46" - integrity sha1-UlqcrU/LqWR119OI9q7LE+7VL0Y= - dependencies: - base64-js "^1.1.2" - browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.20.2: - version "4.20.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" - integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== - dependencies: - caniuse-lite "^1.0.30001332" - electron-to-chromium "^1.4.118" - escalade "^3.1.1" - node-releases "^2.0.3" - picocolors "^1.0.0" - -bryt@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bryt/-/bryt-1.0.2.tgz#041b58d0038aabb7517920e4d7ccad27f172cdd3" - integrity sha512-K/qt3xOAOU71q5Y2yJKOqleBwfeJ3J5tOn1pds9b/iQvQ/cq984oSzuv6iOXRxoTdZH3WGOazX1HXu0+sLU7VA== - dependencies: - brotli "^1.3.2" +bryt-lite@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bryt-lite/-/bryt-lite-2.0.1.tgz#8bb35d3219d541622ba6c9c32d051e91a60d54c5" + integrity sha512-m6QJ1DUuLc+XTFQ26uLLFZdS5Dcjc4tWDK8M49YLHLW8EtSAwnbzGZVyBV4XjXmoMmWsCJ/d6NvpydhW/KQwNA== buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - -buffer-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" - integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== -buffer-from@^1.0.0: +buffer-from@^1.0.0, buffer-from@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== @@ -2280,10 +1987,18 @@ buffer@^5.1.0, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtins@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== builtins@^5.0.0: version "5.0.1" @@ -2292,11 +2007,6 @@ builtins@^5.0.0: dependencies: semver "^7.0.0" -byline@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" - integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= - byte-size@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-7.0.1.tgz#b1daf3386de7ab9d706b941a748dbfc71130dee3" @@ -2307,6 +2017,24 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +c8@^7.11.3: + version "7.11.3" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.11.3.tgz#88c8459c1952ed4f701b619493c9ae732b057163" + integrity sha512-6YBmsaNmqRm9OS3ZbIiL2EZgi1+Xc4O24jL3vMYGE6idixYuGdy76rIfIdltSKDj9DpLNrcXSonUTR1miBD0wA== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@istanbuljs/schema" "^0.1.3" + find-up "^5.0.0" + foreground-child "^2.0.0" + istanbul-lib-coverage "^3.2.0" + istanbul-lib-report "^3.0.0" + istanbul-reports "^3.1.4" + rimraf "^3.0.2" + test-exclude "^6.0.0" + v8-to-istanbul "^9.0.0" + yargs "^16.2.0" + yargs-parser "^20.2.9" + cacache@^15.0.5, cacache@^15.2.0: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" @@ -2331,10 +2059,10 @@ cacache@^15.0.5, cacache@^15.2.0: tar "^6.0.2" unique-filename "^1.1.1" -cacache@^16.0.2: - version "16.0.7" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.0.7.tgz#74a5d9bc4c17b4c0b373c1f5d42dadf5dc06638d" - integrity sha512-a4zfQpp5vm4Ipdvbj+ZrPonikRhm6WBEd4zT1Yc1DXsmAxrPgDwWBLF/u/wTVXSFPIgOJ1U3ghSa2Xm4s3h28w== +cacache@^16.0.0, cacache@^16.0.6, cacache@^16.1.0: + version "16.1.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.1.tgz#4e79fb91d3efffe0630d5ad32db55cc1b870669c" + integrity sha512-VDKN+LHyCQXaaYZ7rA/qtkURU+/yYhviUdvqEv2LT6QPZU8jpyzEkEVAcKlKLt5dJ5BRp11ym8lo3NKLluEPLg== dependencies: "@npmcli/fs" "^2.1.0" "@npmcli/move-file" "^2.0.0" @@ -2355,21 +2083,6 @@ cacache@^16.0.2: tar "^6.1.11" unique-filename "^1.1.1" -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - cache-content-type@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" @@ -2378,10 +2091,10 @@ cache-content-type@^1.0.0: mime-types "^2.1.18" ylru "^1.2.0" -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== +cacheable-lookup@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.0.4.tgz#65c0e51721bb7f9f2cb513aed6da4a1b93ad7dc8" + integrity sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A== cacheable-request@^7.0.2: version "7.0.2" @@ -2396,16 +2109,6 @@ cacheable-request@^7.0.2: normalize-url "^6.0.1" responselike "^2.0.0" -caching-transform@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-4.0.0.tgz#00d297a4206d71e2163c39eaffa8157ac0651f0f" - integrity sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA== - dependencies: - hasha "^5.0.0" - make-dir "^3.0.0" - package-hash "^4.0.0" - write-file-atomic "^3.0.0" - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -2414,25 +2117,30 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -caller-callsite@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-4.1.0.tgz#3e33cb1d910e7b09332d59a3503b9af7462f7295" - integrity sha512-99nnnGlJexTc41xwQTr+mWl15OI5PPczUJzM4YRE7QjkefMKCXGa5gfQjCOuVrD+1TjI/fevIDHg2nz3iYN5Ig== +caller-callsite@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-5.0.0.tgz#e95f38263a0aa0c74ed339bc417ef5281647bdd5" + integrity sha512-l3+xZHsuNlFjchy1nl1kpQwi7PhKHgtQ7MOx5ijHwlouAjnwRNjq3AlxH8SGuWiF5XAhb/mSH+c90LIDFjJKtA== dependencies: - callsites "^3.1.0" + callsites "^4.0.0" -caller-path@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-3.0.1.tgz#bc932ecec3f943e10c2f8922146e23b132f932e4" - integrity sha512-fhmztL4wURO/BzwJUJ4aVRdnKEFskPBbrJ8fNgl7XdUiD1ygzzlt+nhPgUBSRq2ciEVubo6x+W8vJQzm55QLLQ== +caller-path@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-4.0.0.tgz#6509f6ba633c9db306bb6de9e86295383aa1e1af" + integrity sha512-18JFq7TTe4+cDKsyZETRk/IS9Xka3dRcU9VWm1C6XlkAjKPSR2bskpDSUHVQw7gvef34bi1gltzmCxToUw1oQw== dependencies: - caller-callsite "^4.1.0" + caller-callsite "^5.0.0" -callsites@^3.0.0, callsites@^3.1.0: +callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +callsites@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-4.0.0.tgz#8014cea4fedfe681a30e2f7d2d557dd95808a92a" + integrity sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ== + camelcase-keys@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" @@ -2442,30 +2150,20 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= - -camelcase@^5.0.0, camelcase@^5.3.1: +camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0, camelcase@^6.2.0: +camelcase@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001332: - version "1.0.30001339" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001339.tgz#f9aece4ea8156071613b27791547ba0b33f176cf" - integrity sha512-Es8PiVqCe+uXdms0Gu5xP5PF2bxLR7OBp3wUzUnuO7OHzhOfCyg3hdiGWVPVxhiuniOzng+hTc1u3fEQ0TlkSQ== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +camelcase@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.0.tgz#fd112621b212126741f998d614cbc2a8623fd174" + integrity sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ== chai-as-promised@^7.1.1: version "7.1.1" @@ -2487,18 +2185,7 @@ chai@^4.3.6: pathval "^1.1.1" type-detect "^4.0.5" -chalk@^1.0.0, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2507,7 +2194,7 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2515,6 +2202,11 @@ chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.0.0, chalk@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6" + integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w== + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -2523,84 +2215,22 @@ chardet@^0.7.0: check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -check-kit@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/check-kit/-/check-kit-1.2.1.tgz#51ed2f8c2912c6e97bf85ebda03f89cdb08456d5" - integrity sha512-RX6relK1orfNiBmoeD4h2q3OWle6NXEq289bMSbF90SDK5c/XWkH4YLB6OngM2GorMwYw28TnmO7axJbQNNU+A== - dependencies: - "@axway/amplify-request" "^2.1.4" - ci-info "^3.2.0" - fs-extra "^9.1.0" - registry-auth-token "4.2.1" - semver "^7.3.5" - snooplogg "^3.0.2" - source-map-support "^0.5.19" - tmp "^0.2.1" + integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== -check-kit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/check-kit/-/check-kit-2.0.0.tgz#65c8ca343dfc66e0c0ca3473cb88e3003a1705d5" - integrity sha512-HYJOowdiRJIi2he5bqzVBlI2lG6wuYksP2EiEokbTOARK87R9wtmaYhqkTERN1vg3xJHBJKptTEJR7U/46LLgg== +check-kit@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/check-kit/-/check-kit-3.0.1.tgz#2bb60af0a92231f54c434c3e62449f1c058ffeb5" + integrity sha512-LblKGe+PRJv/RS9Ge2kdXRnsNMlTLIaQ+eZlacw8kwxLR/E9+hJyk460ArUtDU7wf3HdT0KQl6hy89y3tYNZ0Q== dependencies: - "@axway/amplify-request" "^3.0.6" - babel-plugin-source-map-support "^2.1.3" - ci-info "^3.3.0" - fs-extra "^9.1.0" - registry-auth-token "4.2.1" - semver "^7.3.5" - snooplogg "^3.0.2" + "@axway/amplify-request" "^3.0.10" + ci-info "^3.3.2" + fs-extra "^10.1.0" + registry-auth-token "5.0.1" + semver "^7.3.7" + snooplogg "^5.0.0" source-map-support "^0.5.21" tmp "^0.2.1" -cheerio@0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.20.0.tgz#5c710f2bab95653272842ba01c6ea61b3545ec35" - integrity sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU= - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.0" - entities "~1.1.1" - htmlparser2 "~3.8.1" - lodash "^4.1.0" - optionalDependencies: - jsdom "^7.0.2" - -cheerio@0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" - integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.0" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash.assignin "^4.0.9" - lodash.bind "^4.1.4" - lodash.defaults "^4.0.1" - lodash.filter "^4.4.0" - lodash.flatten "^4.2.0" - lodash.foreach "^4.3.0" - lodash.map "^4.4.0" - lodash.merge "^4.4.0" - lodash.pick "^4.2.1" - lodash.reduce "^4.4.0" - lodash.reject "^4.4.0" - lodash.some "^4.4.0" - -cheerio@1.0.0-rc.2: - version "1.0.0-rc.2" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" - integrity sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs= - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.0" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash "^4.15.0" - parse5 "^3.0.1" - chokidar@3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -2610,32 +2240,13 @@ chokidar@3.5.3: braces "~3.0.2" glob-parent "~5.1.2" is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^2.0.0: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "^1.2.7" + fsevents "~2.3.2" -chownr@^1.1.1, chownr@^1.1.4: +chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -2650,30 +2261,20 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.2.0, ci-info@^3.3.0, ci-info@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.1.tgz#58331f6f472a25fe3a50a351ae3052936c2c7f32" - integrity sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" +ci-info@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" + integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +cli-boxes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" + integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== cli-cursor@^3.1.0: version "3.1.0" @@ -2682,25 +2283,30 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-kit@^1.16.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/cli-kit/-/cli-kit-1.16.0.tgz#145cdbd95d71d5b64d3f537bba00772497ff516e" - integrity sha512-HuaY/28iMkO6lQcK90iTnOSIBuPca10DrV8NamCh4+kclZSrnXL4zSP9KG3nd3oGCCKENuCok2prHU5RzgRxcw== +cli-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" + integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== + dependencies: + restore-cursor "^4.0.0" + +cli-kit@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cli-kit/-/cli-kit-2.0.2.tgz#a657a8ee6b96d280ff28561e7156442f4a489edc" + integrity sha512-6mhKh/W95iXgBHzmRz5vKhHaOW2a6IwcgxhtjLC9MGaTfCAsOlZm0MDSaoaoDT0kpGwbZ9jIyewWgELDi/VDAg== dependencies: argv-split "^2.0.1" fastest-levenshtein "^1.0.12" - fs-extra "^9.1.0" - hook-emitter "^4.1.2" + fs-extra "^10.1.0" + hook-emitter "^6.0.0" lodash.camelcase "^4.3.0" - pkg-dir "^5.0.0" + pkg-dir "^6.0.1" pluralize "^8.0.0" semver "^7.3.7" - snooplogg "^3.0.2" - source-map-support "^0.5.21" + snooplogg "^5.0.0" which "^2.0.2" - ws "^7.5.7" -cli-spinners@^2.5.0: +cli-spinners@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== @@ -2727,24 +2333,6 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -2754,11 +2342,6 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" -clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= - clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" @@ -2771,38 +2354,14 @@ clone-deep@^4.0.1: clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + integrity sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q== dependencies: mimic-response "^1.0.0" -clone-stats@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" - integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= - -clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= - -clone@^1.0.0, clone@^1.0.2: +clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -cloneable-readable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" - integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== - dependencies: - inherits "^2.0.1" - process-nextick-args "^2.0.0" - readable-stream "^2.3.5" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== cmd-shim@^4.1.0: version "4.1.0" @@ -2811,6 +2370,13 @@ cmd-shim@^4.1.0: dependencies: mkdirp-infer-owner "^2.0.0" +cmd-shim@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-5.0.0.tgz#8d0aaa1a6b0708630694c4dbde070ed94c707724" + integrity sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw== + dependencies: + mkdirp-infer-owner "^2.0.0" + co-body@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.1.0.tgz#d87a8efc3564f9bfe3aced8ef5cd04c7a8766547" @@ -2824,29 +2390,7 @@ co-body@^6.0.0: co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-map@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" - integrity sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw= - dependencies: - arr-map "^2.0.2" - for-own "^1.0.0" - make-iterator "^1.0.0" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== color-convert@^1.9.0: version "1.9.3" @@ -2862,20 +2406,10 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-logger@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/color-logger/-/color-logger-0.0.3.tgz#d9b22dd1d973e166b18bf313f9f481bba4df2018" - integrity sha1-2bIt0dlz4Waxi/MT+fSBu6TfIBg= - -color-logger@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/color-logger/-/color-logger-0.0.6.tgz#e56245ef29822657110c7cb75a9cd786cb69ed1b" - integrity sha1-5WJF7ymCJlcRDHy3WpzXhstp7Rs= - color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" @@ -2888,16 +2422,11 @@ color-support@^1.1.3: integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== colorette@^2.0.16: - version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -colors@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" - integrity sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w= - -columnify@^1.5.4: +columnify@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== @@ -2905,17 +2434,17 @@ columnify@^1.5.4: strip-ansi "^6.0.1" wcwidth "^1.0.0" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commondir@^1.0.1: +common-ancestor-path@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" + integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w== compare-func@^2.0.0: version "2.0.0" @@ -2925,11 +2454,6 @@ compare-func@^2.0.0: array-ify "^1.0.0" dot-prop "^5.1.0" -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - compress-brotli@^1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/compress-brotli/-/compress-brotli-1.3.8.tgz#0c0a60c97a989145314ec381e84e26682e7b38db" @@ -2941,17 +2465,7 @@ compress-brotli@^1.3.8: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-stream@^2.0.0: version "2.0.0" @@ -2963,7 +2477,22 @@ concat-stream@^2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" -config-chain@^1.1.12: +concurrently@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.2.2.tgz#4ad4a4dfd3945f668d727379de2a29502e6a531c" + integrity sha512-DcQkI0ruil5BA/g7Xy3EWySGrFJovF5RYAYxwGvv9Jf9q9B1v3jPFP2tl6axExNf1qgF30kjoNYrangZ0ey4Aw== + dependencies: + chalk "^4.1.0" + date-fns "^2.16.1" + lodash "^4.17.21" + rxjs "^7.0.0" + shell-quote "^1.7.3" + spawn-command "^0.0.2-1" + supports-color "^8.1.0" + tree-kill "^1.2.2" + yargs "^17.3.1" + +config-chain@^1.1.11, config-chain@^1.1.12: version "1.1.13" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== @@ -2971,23 +2500,22 @@ config-chain@^1.1.12: ini "^1.3.4" proto-list "~1.2.1" -config-kit@^1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/config-kit/-/config-kit-1.7.2.tgz#e431c1e725424dfb5499d081c42260f3b29b0e98" - integrity sha512-UtJ9+l6DfHhy2a5w5iBCjbJbJgOYBCGTEHFJRhkBduLsaZgY5X27w5YQZDdyV1M+aEzam0HJIIHYcF7I+7m3/g== +config-kit@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/config-kit/-/config-kit-2.1.0.tgz#2f1e6d8dc64b5f010905a5c7b990217bd94d201f" + integrity sha512-ge357aZhqwRmeLPAD30Oe/lVjPsQ/KrqACOTga4gg4CrfX5K0sHMxclVTvJjpE/6T8e1n/r3ypzIIxTxncXtvw== dependencies: - "@xmldom/xmldom" "^0.7.5" - detect-indent "^6.1.0" - fs-extra "^9.1.0" + "@xmldom/xmldom" "^0.8.2" + detect-indent "^7.0.0" + fs-extra "^10.1.0" import-fresh "^3.3.0" - joi "^17.5.0" - snooplogg "^3.0.2" - source-map-support "^0.5.21" + joi "^17.6.0" + snooplogg "^5.0.0" -console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: +console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== content-disposition@~0.5.2: version "0.5.4" @@ -3083,7 +2611,7 @@ conventional-recommended-bump@^6.1.0: meow "^8.0.0" q "^1.5.1" -convert-source-map@^1.0.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0: +convert-source-map@^1.6.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== @@ -3098,38 +2626,10 @@ cookies@~0.8.0: depd "~2.0.0" keygrip "~1.1.0" -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -copy-props@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2" - integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw== - dependencies: - each-props "^1.3.2" - is-plain-object "^5.0.0" - copy-to@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5" - integrity sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU= - -core-js@^2.4.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" - integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== - -core-js@^3.21.0: - version "3.22.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.5.tgz#a5f5a58e663d5c0ebb4e680cd7be37536fb2a9cf" - integrity sha512-VP/xYuvJ0MJWRAobcmQ8F2H6Bsn+s7zqAAjFaHGBMc5AQm7zaelhD1LGduFn2EehEcQcU+br6t+fwbpQ5d1ZWA== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + integrity sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w== core-util-is@^1.0.2, core-util-is@~1.0.0: version "1.0.3" @@ -3154,16 +2654,10 @@ crc@^3.4.4: dependencies: buffer "^5.1.0" -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" @@ -3174,137 +2668,65 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -css-select@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= - dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" - -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - -css@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" - integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== - dependencies: - inherits "^2.0.4" - source-map "^0.6.1" - source-map-resolve "^0.6.0" - -cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0": - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -"cssstyle@>= 0.2.29 < 0.3.0": - version "0.2.37" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" - integrity sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ= - dependencies: - cssom "0.3.x" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - dargs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -dateformat@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" - integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= +date-fns@^2.16.1: + version "2.28.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" + integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug-fabulous@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-1.1.0.tgz#af8a08632465224ef4174a9f06308c3c2a1ebc8e" - integrity sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg== - dependencies: - debug "3.X" - memoizee "0.4.X" - object-assign "4.X" - -debug@3.X, debug@^3.1.0, debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3: +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" +debug@^3.1.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw== decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + integrity sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg== dependencies: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0: +decamelize@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -3315,7 +2737,7 @@ decompress-response@^6.0.0: dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-eql@^3.0.1: version "3.0.1" @@ -3327,45 +2749,26 @@ deep-eql@^3.0.1: deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw== deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -default-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" - integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== - dependencies: - kind-of "^5.0.2" - -default-require-extensions@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-3.0.0.tgz#e03f93aac9b2b6443fc52e5e4a37b3ad9ad8df96" - integrity sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg== - dependencies: - strip-bom "^4.0.0" - -default-resolution@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" - integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= - defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + integrity sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA== dependencies: clone "^1.0.2" -defer-to-connect@^2.0.0: +defer-to-connect@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== @@ -3383,37 +2786,15 @@ define-properties@^1.1.3, define-properties@^1.1.4: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== depd@2.0.0, depd@^2.0.0, depd@~2.0.0: version "2.0.0" @@ -3423,7 +2804,7 @@ depd@2.0.0, depd@^2.0.0, depd@~2.0.0: depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" @@ -3435,47 +2816,26 @@ destroy@^1.0.4: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= - -detect-indent@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75" - integrity sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U= - dependencies: - get-stdin "^4.0.1" - minimist "^1.1.0" - repeating "^1.1.0" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= - dependencies: - repeating "^2.0.0" - detect-indent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= + integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== -detect-indent@^6.0.0, detect-indent@^6.1.0: +detect-indent@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== +detect-indent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-7.0.0.tgz#cab58e6ab1129c669e2101181a6c677917d43577" + integrity sha512-/6kJlmVv6RDFPqaHC/ZDcU8bblYcoph2dUQ3kB47QqhkUEqXe3VZPELK9BaEMrC73qu+wn0AQ7iSteceN+yuMw== + detect-libc@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== -detect-newline@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - dezalgo@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" @@ -3484,16 +2844,21 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" -diff@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" - integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== - -diff@5.0.0, diff@^5.0.0: +diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^3.1.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -3515,62 +2880,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-serializer@0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" - integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== - dependencies: - domelementtype "^2.0.1" - entities "^2.0.0" - -dom-serializer@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== - dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" - -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== - -domelementtype@^2.0.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" - integrity sha1-LeWaCCLVAn+r/28DLCsloqir5zg= - dependencies: - domelementtype "1" - -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - -domutils@1.5, domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - dot-prop@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -3585,43 +2894,15 @@ dot-prop@^6.0.1: dependencies: is-obj "^2.0.0" -duplexer2@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" - integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= - dependencies: - readable-stream "~1.1.9" - duplexer@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -each-props@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" - integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== - dependencies: - is-plain-object "^2.0.1" - object.defaults "^1.1.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ecdsa-sig-formatter@1.0.11: version "1.0.11" @@ -3633,34 +2914,29 @@ ecdsa-sig-formatter@1.0.11: ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -ejs@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.7.tgz#c544d9c7f715783dd92f0bddcf73a59e6962d006" - integrity sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw== +ejs@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" + integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.118: - version "1.4.137" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz#186180a45617283f1c012284458510cd99d6787f" - integrity sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + encodeurl@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== encoding@^0.1.12, encoding@^0.1.13: version "0.1.13" @@ -3669,35 +2945,20 @@ encoding@^0.1.12, encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enquirer@^2.3.5, enquirer@^2.3.6: +enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: ansi-colors "^4.1.1" -entities@1.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" - integrity sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY= - -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -3713,7 +2974,7 @@ err-code@^2.0.2: resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -3721,9 +2982,9 @@ error-ex@^1.2.0, error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: - version "1.20.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.0.tgz#b2d526489cceca004588296334726329e0a6bfb6" - integrity sha512-URbD8tgRthKD3YcC39vbvSDrX23upXnPcnGAjQfgxXF5ID75YcENawc9ZX/9iTP9ptUyfCLIxTTuMYoRfiOVKA== + version "1.20.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" + integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" @@ -3744,7 +3005,7 @@ es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19 object-inspect "^1.12.0" object-keys "^1.1.1" object.assign "^4.1.2" - regexp.prototype.flags "^1.4.1" + regexp.prototype.flags "^1.4.3" string.prototype.trimend "^1.0.5" string.prototype.trimstart "^1.0.5" unbox-primitive "^1.0.2" @@ -3765,197 +3026,38 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.61" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" - integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - next-tick "^1.1.0" - -es6-error@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -es6-iterator@^2.0.1, es6-iterator@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -es6-weak-map@^2.0.1, es6-weak-map@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" - integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== - dependencies: - d "1" - es5-ext "^0.10.46" - es6-iterator "^2.0.3" - es6-symbol "^3.1.1" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-html@1.0.3, escape-html@^1.0.3: +escape-html@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escodegen@^1.6.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -esdoc-accessor-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-accessor-plugin/-/esdoc-accessor-plugin-1.0.0.tgz#791ba4872e6c403515ce749b1348d6f0293ad9eb" - integrity sha1-eRukhy5sQDUVznSbE0jW8Ck62es= - -esdoc-brand-plugin@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/esdoc-brand-plugin/-/esdoc-brand-plugin-1.0.1.tgz#7c0e1ae90e84c30b2d3369d3a6449f9dc9f8d511" - integrity sha512-Yv9j3M7qk5PSLmSeD6MbPsfIsEf8K43EdH8qZpE/GZwnJCRVmDPrZJ1cLDj/fPu6P35YqgcEaJK4E2NL/CKA7g== - dependencies: - cheerio "0.22.0" - -esdoc-coverage-plugin@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/esdoc-coverage-plugin/-/esdoc-coverage-plugin-1.1.0.tgz#3869869cd7f87891f972625787695a299aece45c" - integrity sha1-OGmGnNf4eJH5cmJXh2laKZrs5Fw= - -esdoc-ecmascript-proposal-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-ecmascript-proposal-plugin/-/esdoc-ecmascript-proposal-plugin-1.0.0.tgz#390dc5656ba8a2830e39dba3570d79138df2ffd9" - integrity sha1-OQ3FZWuoooMOOdujVw15E43y/9k= - -esdoc-external-ecmascript-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-external-ecmascript-plugin/-/esdoc-external-ecmascript-plugin-1.0.0.tgz#78f565d4a0c5185ac63152614dce1fe1a86688db" - integrity sha1-ePVl1KDFGFrGMVJhTc4f4ahmiNs= - dependencies: - fs-extra "1.0.0" - -esdoc-integrate-manual-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-integrate-manual-plugin/-/esdoc-integrate-manual-plugin-1.0.0.tgz#1854a6aa1c081035d7c8c51e3bdd4fb65aa4711c" - integrity sha1-GFSmqhwIEDXXyMUeO91PtlqkcRw= - -esdoc-integrate-test-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-integrate-test-plugin/-/esdoc-integrate-test-plugin-1.0.0.tgz#e2d0d00090f7f0c35e5d2f2c033327a79e53e409" - integrity sha1-4tDQAJD38MNeXS8sAzMnp55T5Ak= - -esdoc-lint-plugin@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/esdoc-lint-plugin/-/esdoc-lint-plugin-1.0.2.tgz#4962930c6dc5b25d80cf6eff1b0f3c24609077f7" - integrity sha512-24AYqD2WbZI9We02I7/6dzAa7yUliRTFUaJCZAcYJMQicJT5gUrNFVaI8XmWEN/mhF3szIn1uZBNWeLul4CmNw== - -esdoc-publish-html-plugin@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/esdoc-publish-html-plugin/-/esdoc-publish-html-plugin-1.1.2.tgz#bdece7bc7a0a3e419933503252db7a6772879dab" - integrity sha512-hG1fZmTcEp3P/Hv/qKiMdG1qSp8MjnVZMMkxL5P5ry7I2sX0HQ4P9lt2lms+90Lt0r340HHhSuVx107UL7dphg== - dependencies: - babel-generator "6.11.4" - cheerio "0.22.0" - escape-html "1.0.3" - fs-extra "1.0.0" - ice-cap "0.0.4" - marked "0.3.19" - taffydb "2.7.2" - -esdoc-standard-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-standard-plugin/-/esdoc-standard-plugin-1.0.0.tgz#661201cac7ef868924902446fdac1527253c5d4d" - integrity sha1-ZhIBysfvhokkkCRG/awVJyU8XU0= - dependencies: - esdoc-accessor-plugin "^1.0.0" - esdoc-brand-plugin "^1.0.0" - esdoc-coverage-plugin "^1.0.0" - esdoc-external-ecmascript-plugin "^1.0.0" - esdoc-integrate-manual-plugin "^1.0.0" - esdoc-integrate-test-plugin "^1.0.0" - esdoc-lint-plugin "^1.0.0" - esdoc-publish-html-plugin "^1.0.0" - esdoc-type-inference-plugin "^1.0.0" - esdoc-undocumented-identifier-plugin "^1.0.0" - esdoc-unexported-identifier-plugin "^1.0.0" - -esdoc-type-inference-plugin@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/esdoc-type-inference-plugin/-/esdoc-type-inference-plugin-1.0.2.tgz#916e3f756de1d81d9c0dbe1c008e8dafd322cfaf" - integrity sha512-tMIcEHNe1uhUGA7lT1UTWc9hs2dzthnTgmqXpmeUhurk7fL2tinvoH+IVvG/sLROzwOGZQS9zW/F9KWnpMzLIQ== - -esdoc-undocumented-identifier-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-undocumented-identifier-plugin/-/esdoc-undocumented-identifier-plugin-1.0.0.tgz#82e05d371c32d12871140f1d5c81ec99fd9cc2c8" - integrity sha1-guBdNxwy0ShxFA8dXIHsmf2cwsg= - -esdoc-unexported-identifier-plugin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esdoc-unexported-identifier-plugin/-/esdoc-unexported-identifier-plugin-1.0.0.tgz#1f9874c6a7c2bebf9ad397c3ceb75c9c69dabab1" - integrity sha1-H5h0xqfCvr+a05fDzrdcnGnaurE= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -esdoc@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/esdoc/-/esdoc-1.1.0.tgz#07d40ebf791764cd537929c29111e20a857624f3" - integrity sha512-vsUcp52XJkOWg9m1vDYplGZN2iDzvmjDL5M/Mp8qkoDG3p2s0yIQCIjKR5wfPBaM3eV14a6zhQNYiNTCVzPnxA== - dependencies: - babel-generator "6.26.1" - babel-traverse "6.26.0" - babylon "6.18.0" - cheerio "1.0.0-rc.2" - color-logger "0.0.6" - escape-html "1.0.3" - fs-extra "5.0.0" - ice-cap "0.0.4" - marked "0.3.19" - minimist "1.2.0" - taffydb "2.7.3" - -eslint-config-axway@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/eslint-config-axway/-/eslint-config-axway-6.0.2.tgz#2ce7752650b2e4cec8beb9fa4cb1f8fbb05fdb80" - integrity sha512-+O+kCrTycij3Vyk+hJtljZy/Xa/Xz0PdkJm4c4DRed6YT7JuSVpoH4UPCST/xCT9/Nonpy8VuyuZTa3kneHdjw== +eslint-config-axway@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-axway/-/eslint-config-axway-7.0.1.tgz#11777c53d1f9b8642c8f69a16a0635316780cd6a" + integrity sha512-f5Gzs7HdaBV2npkfqft6mYu2xooh5aIX2aTGkzOLjEDyWhNo8DfKlizAHYX8zlfLmOyh+g96cq9GJPn1U44diQ== dependencies: - eslint-plugin-chai-expect "^2.2.0" - eslint-plugin-import "^2.22.1" + eslint-plugin-chai-expect "^3.0.0" + eslint-plugin-import "^2.26.0" eslint-plugin-node "^11.1.0" - eslint-plugin-promise "^5.1.0" - eslint-plugin-security "^1.4.0" + eslint-plugin-promise "^6.0.0" + eslint-plugin-security "^1.5.0" find-root "^1.1.0" - semver "^7.3.4" + semver "^7.3.7" eslint-import-resolver-node@^0.3.6: version "0.3.6" @@ -3973,10 +3075,10 @@ eslint-module-utils@^2.7.3: debug "^3.2.7" find-up "^2.1.0" -eslint-plugin-chai-expect@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz#ff41fb00067fe6ff26e72b04ab1011ecaf3cb249" - integrity sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ== +eslint-plugin-chai-expect@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-3.0.0.tgz#812d7384756177b2d424040cb3c20e78606db1b2" + integrity sha512-NS0YBcToJl+BRKBSMCwRs/oHJIX67fG5Gvb4tGked+9Wnd1/PzKijd82B2QVKcSSOwRe+pp4RAJ2AULeck4eQw== eslint-plugin-chai-friendly@^0.7.2: version "0.7.2" @@ -3991,7 +3093,7 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@^2.22.1: +eslint-plugin-import@^2.26.0: version "2.26.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== @@ -4010,13 +3112,13 @@ eslint-plugin-import@^2.22.1: resolve "^1.22.0" tsconfig-paths "^3.14.1" -eslint-plugin-mocha@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz#b4457d066941eecb070dc06ed301c527d9c61b60" - integrity sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg== +eslint-plugin-mocha@^10.0.5: + version "10.0.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-10.0.5.tgz#c3b1e9f59c01063566d8e64b64226533376ffccd" + integrity sha512-H5xuD5NStlpaKLqUWYC5BsMx8fHgrIYsdloFbONUTc2vgVNiJcWdKoX29Tt0BO75QgAltplPLIziByMozGGixA== dependencies: eslint-utils "^3.0.0" - ramda "^0.27.1" + rambda "^7.1.0" eslint-plugin-node@^11.1.0: version "11.1.0" @@ -4030,24 +3132,19 @@ eslint-plugin-node@^11.1.0: resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-promise@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz#a596acc32981627eb36d9d75f9666ac1a4564971" - integrity sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw== +eslint-plugin-promise@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.0.0.tgz#017652c07c9816413a41e11c30adc42c3d55ff18" + integrity sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw== -eslint-plugin-security@^1.4.0: +eslint-plugin-security@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/eslint-plugin-security/-/eslint-plugin-security-1.5.0.tgz#42dcd7990b0fced8fae8d6ca832ffc9954e8a09e" integrity sha512-hAFVwLZ/UeXrlyVD2TDarv/x00CoFVpaY0IUZhKjPjiFxqkuQVixsK4f2rxngeQOqSxi6OUjzJM/jMwKEVjJ8g== dependencies: safe-regex "^2.1.1" -eslint-rule-composer@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" - integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== - -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -4055,14 +3152,15 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== dependencies: - eslint-visitor-keys "^1.1.0" + esrecurse "^4.3.0" + estraverse "^5.2.0" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: +eslint-utils@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -4076,129 +3174,72 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: +eslint-visitor-keys@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: +eslint-visitor-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint@^6.0.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^7.32.0: - version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== +eslint@^8.19.0: + version "8.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.19.0.tgz#7342a3cbc4fbc5c106a1eefe0fd0b50b6b1a7d28" + integrity sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw== dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" + "@eslint/eslintrc" "^1.3.0" + "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.3.2" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" + glob-parent "^6.0.1" + globals "^13.15.0" + ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" + regexpp "^3.2.0" + strip-ansi "^6.0.1" strip-json-comments "^3.1.0" - table "^6.0.9" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== - dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" - -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.3.2: + version "9.3.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" + integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + acorn "^8.7.1" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" -esquery@^1.0.1, esquery@^1.4.0: +esquery@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== @@ -4212,7 +3253,7 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -4227,14 +3268,6 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -event-emitter@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= - dependencies: - d "1" - es5-ext "~0.10.14" - eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -4255,65 +3288,11 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - expand-template@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= - dependencies: - homedir-polyfill "^1.0.1" - -ext@^1.1.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" - integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== - dependencies: - type "^2.5.0" - -extend-shallow@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" - integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= - dependencies: - kind-of "^1.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -4323,47 +3302,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - -fancy-log@^1.1.0, fancy-log@^1.2.0, fancy-log@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" - integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== - dependencies: - ansi-gray "^0.1.1" - color-support "^1.1.3" - parse-node-version "^1.0.0" - time-stamp "^1.0.0" - -fancy-log@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-2.0.0.tgz#cad207b8396d69ae4796d74d17dff5f68b2f7343" - integrity sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA== - dependencies: - color-support "^1.1.3" - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -4385,15 +3323,10 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" - integrity sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk= - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastest-levenshtein@^1.0.12: version "1.0.12" @@ -4414,13 +3347,6 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -4428,28 +3354,13 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - filelist@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.3.tgz#448607750376484932f67ef1b9ff07386b036c83" - integrity sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q== + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: minimatch "^5.0.1" -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.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" @@ -4457,29 +3368,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -filter-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= - -find-cache-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-cache-dir@^3.2.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" @@ -4493,28 +3381,13 @@ find-up@5.0.0, find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== dependencies: locate-path "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -4523,60 +3396,13 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -findup-sync@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" - integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= - dependencies: - detect-file "^1.0.0" - is-glob "^3.1.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -findup-sync@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -findup-sync@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" - integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^4.0.2" - resolve-dir "^1.0.1" - -fined@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" - integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== - dependencies: - expand-tilde "^2.0.2" - is-plain-object "^2.0.3" - object.defaults "^1.1.0" - object.pick "^1.2.0" - parse-filepath "^1.0.1" - -flagged-respawn@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" - integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +find-up@^6.1.0, find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + locate-path "^7.1.0" + path-exists "^5.0.0" flat-cache@^3.0.4: version "3.0.4" @@ -4591,35 +3417,10 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - flatted@^3.1.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== - -flush-write-stream@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -for-in@^1.0.1, for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -for-own@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" - integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= - dependencies: - for-in "^1.0.1" + version "3.2.6" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" + integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== foreground-child@^2.0.0: version "2.0.0" @@ -4629,61 +3430,31 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data-encoder@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96" + integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - fresh@~0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fromentries@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" - integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - integrity sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - -fs-extra@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" - integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^10.0.0, fs-extra@^10.1.0: +fs-extra@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== @@ -4702,13 +3473,6 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -4716,26 +3480,10 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0: dependencies: minipass "^3.0.0" -fs-mkdirp-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" - integrity sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes= - dependencies: - graceful-fs "^4.1.11" - through2 "^2.0.3" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@~2.3.2: version "2.3.2" @@ -4760,7 +3508,7 @@ function.prototype.name@^1.1.5: functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== functions-have-names@^1.2.2: version "1.2.3" @@ -4781,31 +3529,7 @@ gauge@^4.0.3: strip-ansi "^6.0.1" wide-align "^1.1.5" -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: +get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -4813,26 +3537,16 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== dependencies: function-bind "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" - -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" - integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + has-symbols "^1.0.3" get-pkg-repo@^4.0.0: version "4.2.1" @@ -4849,10 +3563,10 @@ get-port@^5.1.1: resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= +get-port@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-6.1.2.tgz#c1228abb67ba0e17fb346da33b15187833b9c08a" + integrity sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw== get-stream@^5.1.0: version "5.2.0" @@ -4861,7 +3575,7 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" -get-stream@^6.0.0: +get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -4874,18 +3588,6 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - git-raw-commits@^2.0.8: version "2.0.11" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723" @@ -4900,7 +3602,7 @@ git-raw-commits@^2.0.8: git-remote-origin-url@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - integrity sha1-UoJlna4hBxRaERJhEq0yFuxfpl8= + integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== dependencies: gitconfiglocal "^1.0.0" pify "^2.3.0" @@ -4913,78 +3615,48 @@ git-semver-tags@^4.1.1: meow "^8.0.0" semver "^6.0.0" -git-up@^4.0.0: - version "4.0.5" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.5.tgz#e7bb70981a37ea2fb8fe049669800a1f9a01d759" - integrity sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA== +git-up@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-6.0.0.tgz#dbd6e4eee270338be847a0601e6d0763c90b74db" + integrity sha512-6RUFSNd1c/D0xtGnyWN2sxza2bZtZ/EmI9448n6rCZruFwV/ezeEn2fJP7XnUQGwf0RAtd/mmUCbtH6JPYA2SA== dependencies: - is-ssh "^1.3.0" - parse-url "^6.0.0" + is-ssh "^1.4.0" + parse-url "^7.0.2" -git-url-parse@^11.4.4: - version "11.6.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.6.0.tgz#c634b8de7faa66498a2b88932df31702c67df605" - integrity sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g== +git-url-parse@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-12.0.0.tgz#4ba70bc1e99138321c57e3765aaf7428e5abb793" + integrity sha512-I6LMWsxV87vysX1WfsoglXsXg6GjQRKq7+Dgiseo+h0skmp5Hp2rzmcEIRQot9CPA+uzU7x1x7jZdqvTFGnB+Q== dependencies: - git-up "^4.0.0" + git-up "^6.0.0" gitconfiglocal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - integrity sha1-QdBF84UaXqiPA/JMocYXgRRGS5s= + integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== dependencies: ini "^1.3.2" github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== -glob-parent@^5.0.0, glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob-stream@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" - integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: - extend "^3.0.0" - glob "^7.1.1" - glob-parent "^3.1.0" - is-negated-glob "^1.0.0" - ordered-read-streams "^1.0.0" - pumpify "^1.3.5" - readable-stream "^2.1.5" - remove-trailing-separator "^1.0.1" - to-absolute-glob "^2.0.0" - unique-stream "^2.0.2" - -glob-watcher@^5.0.3: - version "5.0.5" - resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.5.tgz#aa6bce648332924d9a8489be41e3e5c52d4186dc" - integrity sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw== - dependencies: - anymatch "^2.0.0" - async-done "^1.2.0" - chokidar "^2.0.0" - is-negated-glob "^1.0.0" - just-debounce "^1.0.0" - normalize-path "^3.0.0" - object.defaults "^1.1.0" + is-glob "^4.0.3" -glob@7.2.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -4996,63 +3668,37 @@ glob@7.2.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.1.tgz#00308f5c035aa0b2a447cd37ead267ddff1577d3" - integrity sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow== +glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^5.0.1" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== +glob@^8.0.1: + version "8.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" + integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== dependencies: - type-fest "^0.8.1" + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" -globals@^13.6.0, globals@^13.9.0: - version "13.14.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.14.0.tgz#daf3ff9b4336527cf56e98330b6f64bea9aff9df" - integrity sha512-ERO68sOYwm5UuLvSJTY7w7NP2c8S4UcXs3X1GBX8cwOr+ShOcDBbCY5mH4zxz0jsYCdJ8ve8Mv9n2YGJMB1aeg== +globals@^13.15.0: + version "13.16.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.16.0.tgz#9be4aca28f311aaeb974ea54978ebbb5e35ce46a" + integrity sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q== dependencies: type-fest "^0.20.2" -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - -globby@^11.0.2: +globby@^11.0.2, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -5064,186 +3710,30 @@ globby@^11.0.2: merge2 "^1.4.1" slash "^3.0.0" -glogg@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" - integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== - dependencies: - sparkles "^1.0.0" - -got@^11.8.2, got@^11.8.3, got@^11.8.5: - version "11.8.5" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046" - integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ== +got@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4" + integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig== dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" + "@sindresorhus/is" "^4.6.0" + "@szmarczak/http-timer" "^5.0.1" + "@types/cacheable-request" "^6.0.2" "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" + cacheable-lookup "^6.0.4" cacheable-request "^7.0.2" decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" + form-data-encoder "1.7.1" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" responselike "^2.0.0" -graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.6: +graceful-fs@4.2.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -gulp-babel@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-8.0.0.tgz#e0da96f4f2ec4a88dd3a3030f476e38ab2126d87" - integrity sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ== - dependencies: - plugin-error "^1.0.1" - replace-ext "^1.0.0" - through2 "^2.0.0" - vinyl-sourcemaps-apply "^0.2.0" - -gulp-chug@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/gulp-chug/-/gulp-chug-0.5.1.tgz#b1918881b2bb52fd47e3cb2371587fca4c45e5c6" - integrity sha1-sZGIgbK7Uv1H48sjcVh/ykxF5cY= - dependencies: - gulp-util "^3.0.7" - lodash "^4.0.0" - resolve "^1.1.6" - through2 "^2.0.0" - -gulp-cli@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" - integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== - dependencies: - ansi-colors "^1.0.1" - archy "^1.0.0" - array-sort "^1.0.0" - color-support "^1.1.3" - concat-stream "^1.6.0" - copy-props "^2.0.1" - fancy-log "^1.3.2" - gulplog "^1.0.0" - interpret "^1.4.0" - isobject "^3.0.1" - liftoff "^3.1.0" - matchdep "^2.0.0" - mute-stdout "^1.0.0" - pretty-hrtime "^1.0.0" - replace-homedir "^1.0.0" - semver-greatest-satisfied-range "^1.1.0" - v8flags "^3.2.0" - yargs "^7.1.0" - -gulp-debug@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/gulp-debug/-/gulp-debug-4.0.0.tgz#036f9539c3fb6af720e01a9ea5c195fc73f29d5b" - integrity sha512-cn/GhMD2nVZCVxAl5vWao4/dcoZ8wUJ8w3oqTvQaGDmC1vT7swNOEbhQTWJp+/otKePT64aENcqAQXDcdj5H1g== - dependencies: - chalk "^2.3.0" - fancy-log "^1.3.2" - plur "^3.0.0" - stringify-object "^3.0.0" - through2 "^2.0.0" - tildify "^1.1.2" - -gulp-eslint@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/gulp-eslint/-/gulp-eslint-6.0.0.tgz#7d402bb45f8a67652b868277011812057370a832" - integrity sha512-dCVPSh1sA+UVhn7JSQt7KEb4An2sQNbOdB3PA8UCfxsoPlAKjJHxYHGXdXC7eb+V1FAnilSFFqslPrq037l1ig== - dependencies: - eslint "^6.0.0" - fancy-log "^1.3.2" - plugin-error "^1.0.1" - -gulp-load-plugins@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/gulp-load-plugins/-/gulp-load-plugins-2.0.7.tgz#69d35d27e8f9b41a00a29cfcdf236d5d17c40dbe" - integrity sha512-/3nl/p7s9O03Yv6SSEqN2dXEbDE0+JpsKfJl6h/GgCLqqnkZT0bF+JWcz87HzcTBeh/MVzMosAJx4kLDTWrTNQ== - dependencies: - array-unique "^0.3.2" - fancy-log "^1.2.0" - findup-sync "^4.0.0" - gulplog "^1.0.0" - has-gulplog "^0.1.0" - micromatch "^4.0.2" - resolve "^1.17.0" - -gulp-plumber@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/gulp-plumber/-/gulp-plumber-1.2.1.tgz#d38700755a300b9d372318e4ffb5ff7ced0b2c84" - integrity sha512-mctAi9msEAG7XzW5ytDVZ9PxWMzzi1pS2rBH7lA095DhMa6KEXjm+St0GOCc567pJKJ/oCvosVAZEpAey0q2eQ== - dependencies: - chalk "^1.1.3" - fancy-log "^1.3.2" - plugin-error "^0.1.2" - through2 "^2.0.3" - -gulp-sourcemaps@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz#2e154e1a2efed033c0e48013969e6f30337b2743" - integrity sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ== - dependencies: - "@gulp-sourcemaps/identity-map" "^2.0.1" - "@gulp-sourcemaps/map-sources" "^1.0.0" - acorn "^6.4.1" - convert-source-map "^1.0.0" - css "^3.0.0" - debug-fabulous "^1.0.0" - detect-newline "^2.0.0" - graceful-fs "^4.0.0" - source-map "^0.6.0" - strip-bom-string "^1.0.0" - through2 "^2.0.0" - -gulp-util@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" - integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= - dependencies: - array-differ "^1.0.0" - array-uniq "^1.0.2" - beeper "^1.0.0" - chalk "^1.0.0" - dateformat "^2.0.0" - fancy-log "^1.1.0" - gulplog "^1.0.0" - has-gulplog "^0.1.0" - lodash._reescape "^3.0.0" - lodash._reevaluate "^3.0.0" - lodash._reinterpolate "^3.0.0" - lodash.template "^3.0.0" - minimist "^1.1.0" - multipipe "^0.1.2" - object-assign "^3.0.0" - replace-ext "0.0.1" - through2 "^2.0.0" - vinyl "^0.5.0" - -gulp@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" - integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA== - dependencies: - glob-watcher "^5.0.3" - gulp-cli "^2.2.0" - undertaker "^1.2.1" - vinyl-fs "^3.0.0" - -gulplog@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" - integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= - dependencies: - glogg "^1.0.0" - handlebars@^4.7.7: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -5256,31 +3746,11 @@ handlebars@^4.7.7: optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -5289,20 +3759,13 @@ has-bigints@^1.0.1, has-bigints@^1.0.2: has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-gulplog@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" - integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= - dependencies: - sparkles "^1.0.0" - has-property-descriptors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" @@ -5322,41 +3785,10 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.0, has-unicode@^2.0.1: +has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== has@^1.0.3: version "1.0.3" @@ -5365,32 +3797,15 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hasha@^5.0.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.2.tgz#a48477989b3b327aea3c04f53096d816d97522a1" - integrity sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ== - dependencies: - is-stream "^2.0.0" - type-fest "^0.8.0" - he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hook-emitter@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/hook-emitter/-/hook-emitter-4.1.2.tgz#c1d769a6c1aaa0117f34b93040f0dca2fed3ef79" - integrity sha512-MZiljszywN8f0cLsW2t/MYq36kP4oFEMtsbKhrNTlYHPAe6EGkHrMcQjv6vMiftymsT9SqjQ7J5KypzpLb1J6Q== - dependencies: - source-map-support "^0.5.19" +hook-emitter@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hook-emitter/-/hook-emitter-6.0.0.tgz#5c76e8dd3c2336eb9fe8c4880183f1da882ca9e6" + integrity sha512-iRFsSXlB8zyycmVEjvjFNvBHfVJ4yna5z5DEgxuz64VJ0GW76QJ1yxjwYa3soji8zKjVA5q87Wyg7WPt1YvBoA== hosted-git-info@^2.1.4: version "2.8.9" @@ -5416,29 +3831,6 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -htmlparser2@^3.9.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -htmlparser2@~3.8.1: - version "3.8.3" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" - integrity sha1-mWwosZFRaovoZQGn15dX5ccMEGg= - dependencies: - domelementtype "1" - domhandler "2.3" - domutils "1.5" - entities "1.0" - readable-stream "1.1" - http-assert@^1.3.0: version "1.5.0" resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f" @@ -5452,7 +3844,7 @@ http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -http-errors@2.0.0: +http-errors@2.0.0, http-errors@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== @@ -5463,7 +3855,7 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.8.0: +http-errors@^1.6.3, http-errors@~1.8.0: version "1.8.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== @@ -5492,22 +3884,13 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== +http2-wrapper@^2.1.10: + version "2.1.11" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.1.11.tgz#d7c980c7ffb85be3859b6a96c800b2951ae257ef" + integrity sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ== dependencies: quick-lru "^5.1.1" - resolve-alpn "^1.0.0" + resolve-alpn "^1.2.0" https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: version "5.0.1" @@ -5525,18 +3908,10 @@ human-signals@^2.1.0: humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== dependencies: ms "^2.0.0" -ice-cap@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/ice-cap/-/ice-cap-0.0.4.tgz#8a6d31ab4cac8d4b56de4fa946df3352561b6e18" - integrity sha1-im0xq0ysjUtW3k+pRt8zUlYbbhg= - dependencies: - cheerio "0.20.0" - color-logger "0.0.3" - iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5551,7 +3926,7 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -5563,17 +3938,12 @@ ignore-walk@^3.0.3: dependencies: minimatch "^3.0.4" -ignore-walk@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-4.0.1.tgz#fc840e8346cf88a3a9380c5b17933cd8f4d39fa3" - integrity sha512-rzDQLaW4jQbh2YrOFlJdCtX8qgJTehFRYiUB2r1osqTeDzV/3+Jh8fz1oAPzUThf3iku8Ds4IDqawI5d8mUiQw== +ignore-walk@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" + integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== dependencies: - minimatch "^3.0.4" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + minimatch "^5.0.1" ignore@^5.1.1, ignore@^5.2.0: version "5.2.0" @@ -5599,7 +3969,7 @@ import-local@^3.0.2: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" @@ -5614,17 +3984,17 @@ infer-owner@^1.0.4: inflation@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" - integrity sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8= + integrity sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw== inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -5647,7 +4017,7 @@ init-package-json@^2.0.2: validate-npm-package-license "^3.0.4" validate-npm-package-name "^3.0.0" -inquirer@^7.0.0, inquirer@^7.3.3: +inquirer@^7.3.3: version "7.3.3" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== @@ -5675,59 +4045,15 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -interpret@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - ip@^1.1.5: version "1.1.8" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== -irregular-plurals@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-2.0.0.tgz#39d40f05b00f656d0b7fa471230dd3b714af2872" - integrity sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw== - -is-absolute@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" - integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== - dependencies: - is-relative "^1.0.0" - is-windows "^1.0.1" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-bigint@^1.0.1: version "1.0.4" @@ -5736,13 +4062,6 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -5758,11 +4077,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" @@ -5780,27 +4094,13 @@ is-class-hotfix@~0.0.6: resolved "https://registry.yarnpkg.com/is-class-hotfix/-/is-class-hotfix-0.0.6.tgz#a527d31fb23279281dde5f385c77b5de70a72435" integrity sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ== -is-core-module@^2.5.0, is-core-module@^2.8.1: +is-core-module@^2.5.0, is-core-module@^2.8.1, is-core-module@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - is-date-object@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" @@ -5808,62 +4108,15 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" @@ -5877,13 +4130,6 @@ is-generator-function@^1.0.7: dependencies: has-tostringtag "^1.0.0" -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -5891,20 +4137,15 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-interactive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" + integrity sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== is-lambda@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= - -is-negated-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" - integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== is-negative-zero@^2.0.2: version "2.0.2" @@ -5918,28 +4159,11 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - 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-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -5948,14 +4172,14 @@ is-obj@^2.0.0: is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== is-plain-obj@^2.0.0, is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== @@ -5967,11 +4191,6 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-promise@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" - integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== - is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -5980,18 +4199,6 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= - -is-relative@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" - integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== - dependencies: - is-unc-path "^1.0.0" - is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -5999,12 +4206,12 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" -is-ssh@^1.3.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.3.tgz#7f133285ccd7f2c2c7fc897b771b53d95a2b2c7e" - integrity sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ== +is-ssh@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.0.tgz#4f8220601d2839d8fa624b3106f8e8884f01b8b2" + integrity sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ== dependencies: - protocols "^1.1.0" + protocols "^2.0.1" is-stream@^2.0.0: version "2.0.1" @@ -6028,7 +4235,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: is-text-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= + integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== dependencies: text-extensions "^1.0.0" @@ -6041,32 +4248,20 @@ is-type-of@^1.0.0: is-class-hotfix "~0.0.6" isstream "~0.1.2" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unc-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" - integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== - dependencies: - unc-path-regex "^0.1.2" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-utf8@^0.2.0, is-utf8@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-valid-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" - integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= +is-unicode-supported@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.2.0.tgz#f4f54f34d8ebc84a46b93559a036763b6d3e1014" + integrity sha512-wH+U77omcRzevfIG8dDhTS0V9zZyweakfD01FULl97+0EHiJTTZtJqxPSkIIo/SDPv/i07k/C9jAPY+jwLLeUQ== is-weakref@^1.0.2: version "1.0.2" @@ -6075,11 +4270,6 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" -is-windows@^1.0.1, is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -6087,73 +4277,31 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@~1.0.0: +isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isobject@^3.0.0, isobject@^3.0.1: +isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-hook@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz#8f84c9434888cc6b1d0a9d7092a76d239ebf0cc6" - integrity sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ== - dependencies: - append-transform "^2.0.0" - -istanbul-lib-instrument@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" - -istanbul-lib-processinfo@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz#e1426514662244b2f25df728e8fd1ba35fe53b9c" - integrity sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw== - dependencies: - archy "^1.0.0" - cross-spawn "^7.0.0" - istanbul-lib-coverage "^3.0.0-alpha.1" - make-dir "^3.0.0" - p-map "^3.0.0" - rimraf "^3.0.0" - uuid "^3.3.3" - istanbul-lib-report@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" @@ -6163,16 +4311,7 @@ istanbul-lib-report@^3.0.0: make-dir "^3.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.0.2: +istanbul-reports@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== @@ -6190,7 +4329,7 @@ jake@^10.8.5: filelist "^1.0.1" minimatch "^3.0.4" -joi@^17.5.0: +joi@^17.6.0: version "17.6.0" resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.0.tgz#0bb54f2f006c09a96e75ce687957bd04290054b2" integrity sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw== @@ -6201,67 +4340,18 @@ joi@^17.5.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: +js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - -js-yaml@4.1.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdom@^7.0.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-7.2.2.tgz#40b402770c2bda23469096bee91ab675e3b1fc6e" - integrity sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4= - dependencies: - abab "^1.0.0" - acorn "^2.4.0" - acorn-globals "^1.0.4" - cssom ">= 0.3.0 < 0.4.0" - cssstyle ">= 0.2.29 < 0.3.0" - escodegen "^1.6.1" - nwmatcher ">= 1.3.7 < 2.0.0" - parse5 "^1.5.1" - request "^2.55.0" - sax "^1.1.4" - symbol-tree ">= 3.1.0 < 4.0.0" - tough-cookie "^2.2.0" - webidl-conversions "^2.0.0" - whatwg-url-compat "~0.6.5" - xml-name-validator ">= 2.0.1 < 3.0.0" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - json-buffer@3.0.1, json-buffer@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -6272,7 +4362,7 @@ json-parse-better-errors@^1.0.1: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-parse-even-better-errors@^2.3.0: +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== @@ -6282,25 +4372,20 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json-stringify-nice@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67" + integrity sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw== -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^1.0.1: version "1.0.1" @@ -6309,25 +4394,6 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -6340,27 +4406,17 @@ jsonfile@^6.0.1: jsonparse@^1.2.0, jsonparse@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -just-debounce@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf" - integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ== +just-diff-apply@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/just-diff-apply/-/just-diff-apply-5.3.1.tgz#30f40809ffed55ad76dccf73fa9b85a76964c867" + integrity sha512-dgFenZnMsc1xGNqgdtgnh7DK+Oy352CE3VZLbzcbQpsBs9iI2K3M0IRrdgREZ72eItTjbl0suRyvKRdVQa9GbA== -just-extend@^4.0.2: - version "4.2.1" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" - integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== +just-diff@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-5.0.3.tgz#4c9c514dec5526b25ab977590e3c39a0cf271554" + integrity sha512-a8p80xcpJ6sdurk5PxDKb4mav9MeKjA3zFKZpCWBIfvg8mznfnmb13MKZvlrwJ+Lhis0wM3uGAzE0ArhFHvIcg== jwa@^2.0.0: version "2.0.0" @@ -6395,49 +4451,18 @@ keytar@7.9.0: prebuild-install "^7.0.1" keyv@^4.0.0: - version "4.2.7" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.2.7.tgz#00b8994d46098e8eb8c933cb29aaaf18be5effea" - integrity sha512-HeOstD8SXvtWoQhMMBCelcUuZsiV7T7MwsADtOXT0KuwYP9nCxrSoMDeLXNDTLN3VFSuRp38JzoGbbTboq3QQw== + version "4.3.2" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.3.2.tgz#e839df676a0c7ee594c8835e7c1c83742558e5c2" + integrity sha512-kn8WmodVBe12lmHpA6W8OY7SNh6wVR+Z+wZESF4iF5FCazaVXGWOtnbnvX0tMQ1bO+/TmOD9LziuYMvrIIs0xw== dependencies: compress-brotli "^1.3.8" json-buffer "3.0.1" -kind-of@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" - integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0, kind-of@^5.0.2: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: +kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - koa-bodyparser@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.3.0.tgz#274c778555ff48fa221ee7f36a9fbdbace22759a" @@ -6498,66 +4523,29 @@ koa@^2.13.4: type-is "^1.6.16" vary "^1.1.2" -last-run@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" - integrity sha1-RblpQsF7HHnHchmCWbqUO+v4yls= - dependencies: - default-resolution "^2.0.0" - es6-weak-map "^2.0.1" - -lazystream@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" - integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== - dependencies: - readable-stream "^2.0.5" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -lead@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" - integrity sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI= - dependencies: - flush-write-stream "^1.0.2" - -lerna@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-4.0.0.tgz#b139d685d50ea0ca1be87713a7c2f44a5b678e9e" - integrity sha512-DD/i1znurfOmNJb0OBw66NmNqiM8kF6uIrzrJ0wGE3VNdzeOhz9ziWLYiRaZDGGwgbcjOo6eIfcx9O5Qynz+kg== - dependencies: - "@lerna/add" "4.0.0" - "@lerna/bootstrap" "4.0.0" - "@lerna/changed" "4.0.0" - "@lerna/clean" "4.0.0" - "@lerna/cli" "4.0.0" - "@lerna/create" "4.0.0" - "@lerna/diff" "4.0.0" - "@lerna/exec" "4.0.0" - "@lerna/import" "4.0.0" - "@lerna/info" "4.0.0" - "@lerna/init" "4.0.0" - "@lerna/link" "4.0.0" - "@lerna/list" "4.0.0" - "@lerna/publish" "4.0.0" - "@lerna/run" "4.0.0" - "@lerna/version" "4.0.0" +lerna@^5.1.8: + version "5.1.8" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-5.1.8.tgz#77b2f10882c3eaec256fa9a643a21957e6ca7ec2" + integrity sha512-KrpFx2l1x1X7wb9unqRU7OZTaNs5+67VQ1vxf8fIMgdtCAjEqkLxF/F3xLs+KBMws5PV19Q9YtPHn7SiwDl7iQ== + dependencies: + "@lerna/add" "5.1.8" + "@lerna/bootstrap" "5.1.8" + "@lerna/changed" "5.1.8" + "@lerna/clean" "5.1.8" + "@lerna/cli" "5.1.8" + "@lerna/create" "5.1.8" + "@lerna/diff" "5.1.8" + "@lerna/exec" "5.1.8" + "@lerna/import" "5.1.8" + "@lerna/info" "5.1.8" + "@lerna/init" "5.1.8" + "@lerna/link" "5.1.8" + "@lerna/list" "5.1.8" + "@lerna/publish" "5.1.8" + "@lerna/run" "5.1.8" + "@lerna/version" "5.1.8" import-local "^3.0.2" - npmlog "^4.1.2" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" + npmlog "^6.0.2" levn@^0.4.1: version "0.4.1" @@ -6588,26 +4576,12 @@ libnpmpublish@^4.0.0: semver "^7.1.3" ssri "^8.0.1" -libnpmsearch@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-4.0.1.tgz#bf6c96339aadb552c007373623322642a9078512" - integrity sha512-uSKYwVUNbI8ZOAiZIdfDL60F2MelnqVzLUdkLlAoQnK0CnlU8tsdyX+nRDCTPGqOHq0inh5DyCJKbyMxf6ibBA== - dependencies: - npm-registry-fetch "^12.0.1" - -liftoff@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" - integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== +libnpmsearch@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/libnpmsearch/-/libnpmsearch-5.0.3.tgz#ed502a4c2c70ea36723180455fae1357546b2184" + integrity sha512-Ofq76qKAPhxbiyzPf/5LPjJln26VTKwU9hIU0ACxQ6tNtBJ1CHmI7iITrdp7vNezhZc0FlkXwrIpqXjhBJZgLQ== dependencies: - extend "^3.0.0" - findup-sync "^3.0.0" - fined "^1.0.1" - flagged-respawn "^1.0.0" - is-plain-object "^2.0.4" - object.map "^1.0.0" - rechoir "^0.6.2" - resolve "^1.1.7" + npm-registry-fetch "^13.0.0" lines-and-columns@^1.1.6: version "1.2.4" @@ -6628,21 +4602,10 @@ listr2@^4.0.5: through "^2.3.8" wrap-ansi "^7.0.0" -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== dependencies: graceful-fs "^4.1.2" parse-json "^4.0.0" @@ -6662,19 +4625,11 @@ load-json-file@^6.2.0: locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== dependencies: p-locate "^2.0.0" path-exists "^3.0.0" -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -6689,216 +4644,44 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= - -lodash._basetostring@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" - integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= - -lodash._basevalues@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" - integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= - -lodash._reescape@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" - integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= - -lodash._reevaluate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" - integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - -lodash._root@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= - -lodash.assignin@^4.0.9: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" - integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= - -lodash.bind@^4.1.4: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" - integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= +locate-path@^7.1.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.1.1.tgz#8e1e5a75c7343770cef02ff93c4bf1f0aa666374" + integrity sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg== + dependencies: + p-locate "^6.0.0" lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.defaults@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - -lodash.escape@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" - integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= - dependencies: - lodash._root "^3.0.0" - -lodash.filter@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" - integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= - -lodash.flatten@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= - -lodash.foreach@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" - integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" - integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= + integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - -lodash.map@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" - integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= - -lodash.merge@^4.4.0, lodash.merge@^4.6.2: +lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.pick@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= - -lodash.reduce@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" - integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= - -lodash.reject@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" - integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= - -lodash.restparam@^3.0.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - -lodash.set@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" - integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= - -lodash.some@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= - -lodash.template@^3.0.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" - integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= - dependencies: - lodash._basecopy "^3.0.0" - lodash._basetostring "^3.0.0" - lodash._basevalues "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash._reinterpolate "^3.0.0" - lodash.escape "^3.0.0" - lodash.keys "^3.0.0" - lodash.restparam "^3.0.0" - lodash.templatesettings "^3.0.0" - -lodash.template@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" - integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" - integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.escape "^3.0.0" - -lodash.templatesettings@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" - integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== - dependencies: - lodash._reinterpolate "^3.0.0" - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= +lodash.set@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" + integrity sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg== -lodash@^4.0.0, lodash@^4.1.0, lodash@^4.15.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.7.0: +lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.1.0, log-symbols@^4.1.0: +log-symbols@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -6906,6 +4689,14 @@ log-symbols@4.1.0, log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +log-symbols@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-5.1.0.tgz#a20e3b9a5f53fac6aeb8e2bb22c07cf2c8f16d93" + integrity sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA== + dependencies: + chalk "^5.0.0" + is-unicode-supported "^1.1.0" + log-update@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" @@ -6916,13 +4707,6 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - loupe@^2.3.1: version "2.3.4" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" @@ -6935,6 +4719,11 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -6942,19 +4731,12 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.5.1, lru-cache@^7.7.1: - version "7.9.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.9.0.tgz#29c2a989b6c10f32ceccc66ff44059e1490af3e1" - integrity sha512-lkcNMUKqdJk96TuIXUidxaPuEg5sJo/+ZyVE2BDFnuZGzwXem7d8582eG8vbu4todLfT14snP6iHriCHXXi5Rw== - -lru-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" - integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= - dependencies: - es5-ext "~0.10.2" +lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: + version "7.12.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.12.0.tgz#be2649a992c8a9116efda5c487538dcf715f3476" + integrity sha512-OIP3DwzRZDfLg9B9VP/huWBlpvbkmbfiBy8xmsXp4RPmE4A3MhwNozc5ZJ3fWnSg8fDcdlE/neRTPG2ycEKliw== -make-dir@^2.0.0, make-dir@^2.1.0: +make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -6962,20 +4744,25 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.0, make-dir@^3.0.2: +make-dir@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" -make-fetch-happen@^10.0.1: - version "10.1.3" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.1.3.tgz#d7ecd4a22563b2c05b74735eda46569da26a46f6" - integrity sha512-s/UjmGjUHn9m52cctFhN2ITObbT+axoUhgeir8xGrOlPbKDyJsdhQzb8PGncPQQ28uduHybFJ6Iumy2OZnreXw== +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.6: + version "10.1.8" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.1.8.tgz#3b6e93dd8d8fdb76c0d7bf32e617f37c3108435a" + integrity sha512-0ASJbG12Au6+N5I84W+8FhGS6iM8MyzvZady+zaQAu+6IOaESFzCLLD0AR1sAFF3Jufi8bxm586ABN6hWd3k7g== dependencies: agentkeepalive "^4.2.1" - cacache "^16.0.2" + cacache "^16.1.0" http-cache-semantics "^4.1.0" http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" @@ -6988,7 +4775,7 @@ make-fetch-happen@^10.0.1: minipass-pipeline "^1.2.4" negotiator "^0.6.3" promise-retry "^2.0.1" - socks-proxy-agent "^6.1.1" + socks-proxy-agent "^7.0.0" ssri "^9.0.0" make-fetch-happen@^8.0.9: @@ -7034,68 +4821,20 @@ make-fetch-happen@^9.0.1, make-fetch-happen@^9.1.0: socks-proxy-agent "^6.0.0" ssri "^8.0.0" -make-iterator@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" - integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== - dependencies: - kind-of "^6.0.2" - -map-cache@^0.2.0, map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== map-obj@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -marked@0.3.19: - version "0.3.19" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790" - integrity sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg== - -matchdep@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" - integrity sha1-xvNINKDY28OzfCfui7yyfHd1WC4= - dependencies: - findup-sync "^2.0.0" - micromatch "^3.0.4" - resolve "^1.4.0" - stack-trace "0.0.10" - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -memoizee@0.4.X: - version "0.4.15" - resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" - integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== - dependencies: - d "^1.0.1" - es5-ext "^0.10.53" - es6-weak-map "^2.0.3" - event-emitter "^0.3.5" - is-promise "^2.2.2" - lru-queue "^0.1.0" - next-tick "^1.1.0" - timers-ext "^0.1.7" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== meow@^8.0.0: version "8.1.2" @@ -7127,28 +4866,9 @@ merge2@^1.3.0, merge2@^1.4.1: methods@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -7161,7 +4881,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -7188,14 +4908,14 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== dependencies: - brace-expansion "^1.1.7" + brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -7203,9 +4923,9 @@ minimatch@^3.0.4, minimatch@^3.1.2: brace-expansion "^1.1.7" minimatch@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + version "5.1.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" + integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== dependencies: brace-expansion "^2.0.1" @@ -7218,12 +4938,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -7235,7 +4950,7 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.0, minipass-fetch@^1.3.2, minipass-fetch@^1.4.1: +minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: version "1.4.1" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== @@ -7286,28 +5001,13 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" - integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== + version "3.3.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" + integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== dependencies: yallist "^4.0.0" -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -7316,14 +5016,6 @@ minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: minipass "^3.0.0" yallist "^4.0.0" -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" @@ -7338,7 +5030,7 @@ mkdirp-infer-owner@^2.0.0: infer-owner "^1.0.4" mkdirp "^1.0.3" -mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5: +mkdirp@^0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -7350,41 +5042,30 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mocha-jenkins-reporter@^0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/mocha-jenkins-reporter/-/mocha-jenkins-reporter-0.4.7.tgz#59505d59a9fdeb64ee8270f13d8ca6c48c1dfad7" - integrity sha512-ek05WBoGX9G5B29QmFw67H92ZcvZcp62RASaHWqiZOWjc/G2YlKBeu7t60J5wpaQP1rFS8T9S85ed/3iDdf/2A== - dependencies: - diff "4.0.1" - mkdirp "^0.5.4" - xml "^1.0.1" - -mocha@^9.2.0, mocha@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.2.tgz#d70db46bdb93ca57402c809333e5a84977a88fb9" - integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== +mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" + integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== dependencies: "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" chokidar "3.5.3" - debug "4.3.3" + debug "4.3.4" diff "5.0.0" escape-string-regexp "4.0.0" find-up "5.0.0" glob "7.2.0" - growl "1.10.5" he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" - minimatch "4.2.1" + minimatch "5.0.1" ms "2.1.3" - nanoid "3.3.1" + nanoid "3.3.3" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" + workerpool "6.2.1" yargs "16.2.0" yargs-parser "20.2.4" yargs-unparser "2.0.0" @@ -7397,7 +5078,7 @@ modify-values@^1.0.0: ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.2: version "2.1.2" @@ -7420,61 +5101,25 @@ multimatch@^5.0.0: arrify "^2.0.1" minimatch "^3.0.4" -multipipe@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" - integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= - dependencies: - duplexer2 "0.0.2" - mustache@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== -mute-stdout@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" - integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== - mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.12.1: - version "2.15.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" - integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== - -nanobuffer@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/nanobuffer/-/nanobuffer-1.1.7.tgz#d81b71411c1dc47af58c4c5f864cd2b0eb0bf404" - integrity sha512-LP1JYWQh4qFmpLaauE3mWuOjGJSxts+wnYeTlSb4zurdn8xIhJ906oyb7M7Ih6EiImaUskFdHfYx9gyijf1FLA== - dependencies: - source-map-support "^0.5.19" - -nanoid@3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" +nanobuffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/nanobuffer/-/nanobuffer-3.0.0.tgz#5c226649bc0afcce4e22d42c2a78e2b0d86ae278" + integrity sha512-+W0X6StjZK+tAEknYgvuxjXCO8F8RRcDvnkKkF3oSXEVEdIc91J6Lw7E06NI8Jzm1P5VKIziUs3vaoPuO1PJKw== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== napi-build-utils@^1.0.1: version "1.0.2" @@ -7484,7 +5129,7 @@ napi-build-utils@^1.0.1: natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@0.6.3, negotiator@^0.6.2, negotiator@^0.6.3: version "0.6.3" @@ -7496,31 +5141,10 @@ neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -next-tick@1, next-tick@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" - integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -nise@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.1.tgz#ac4237e0d785ecfcb83e20f389185975da5c31f3" - integrity sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A== - dependencies: - "@sinonjs/commons" "^1.8.3" - "@sinonjs/fake-timers" ">=5" - "@sinonjs/text-encoding" "^0.7.1" - just-extend "^4.0.2" - path-to-regexp "^1.7.0" - node-abi@^3.3.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.15.0.tgz#cd9ac8c58328129b49998cc6fa16aa5506152716" - integrity sha512-Ic6z/j6I9RLm4ov7npo1I48UQr2BEyFCqh6p7S1dhEx9jPO0GPGq/e2Rb7x7DroQrmiVMz/Bw1vJm9sPAl2nxA== + version "3.22.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.22.0.tgz#00b8250e86a0816576258227edbce7bbe0039362" + integrity sha512-u4uAs/4Zzmp/jjsD9cyFYDXeISfUWaAVWshPmDZOFOv4Xl4SbzTXm53I04C2uRueYJ+0t5PEtLH/owbn2Npf/w== dependencies: semver "^7.3.5" @@ -7536,48 +5160,31 @@ node-fetch@^2.6.1, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" -node-gyp@^5.0.2: - version "5.1.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" - integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.2" - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.1.2" - request "^2.88.0" - rimraf "^2.6.3" - semver "^5.7.1" - tar "^4.4.12" - which "^1.3.1" - -node-gyp@^7.1.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" - integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== +node-gyp@^8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== dependencies: env-paths "^2.2.0" glob "^7.1.4" - graceful-fs "^4.2.3" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" nopt "^5.0.0" - npmlog "^4.1.2" - request "^2.88.2" + npmlog "^6.0.0" rimraf "^3.0.2" - semver "^7.3.2" - tar "^6.0.2" + semver "^7.3.5" + tar "^6.1.2" which "^2.0.2" -node-gyp@^8.2.0: - version "8.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== +node-gyp@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.0.0.tgz#e1da2067427f3eb5bb56820cb62bc6b1e4bd2089" + integrity sha512-Ma6p4s+XCTPxCuAMrOA/IJRmVy16R8Sdhtwl4PrCr7IBlj4cPawF0vg/l7nOT1jPbuNS7lIRJpBSvVsXwEZuzw== dependencies: env-paths "^2.2.0" glob "^7.1.4" graceful-fs "^4.2.6" - make-fetch-happen "^9.1.0" + make-fetch-happen "^10.0.3" nopt "^5.0.0" npmlog "^6.0.0" rimraf "^3.0.2" @@ -7585,26 +5192,6 @@ node-gyp@^8.2.0: tar "^6.1.2" which "^2.0.2" -node-preload@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" - integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ== - dependencies: - process-on-spawn "^1.0.0" - -node-releases@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" - integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== - -nopt@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -7612,7 +5199,7 @@ nopt@^5.0.0: dependencies: abbrev "1" -normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: +normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -7632,12 +5219,15 @@ normalize-package-data@^3.0.0, normalize-package-data@^3.0.2: semver "^7.3.4" validate-npm-package-license "^3.0.1" -normalize-path@^2.0.1, normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= +normalize-package-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-4.0.0.tgz#1122d5359af21d4cd08718b92b058a658594177c" + integrity sha512-m+GL22VXJKkKbw62ZaBBjv8u6IE3UI4Mh5QakIqs3fWiKe0Xyi6L97hakwZK41/LD4R/2ly71Bayx0NLMwLA/g== dependencies: - remove-trailing-separator "^1.0.1" + hosted-git-info "^5.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -7649,47 +5239,26 @@ normalize-url@^6.0.1, normalize-url@^6.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -now-and-later@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" - integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== - dependencies: - once "^1.3.2" - -npm-bundled@^1.1.1: +npm-bundled@^1.1.1, npm-bundled@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== dependencies: npm-normalize-package-bin "^1.0.1" -npm-install-checks@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" - integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w== +npm-install-checks@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-5.0.0.tgz#5ff27d209a4e3542b8ac6b0c1db6063506248234" + integrity sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA== dependencies: semver "^7.1.1" -npm-lifecycle@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309" - integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g== - dependencies: - byline "^5.0.0" - graceful-fs "^4.1.15" - node-gyp "^5.0.2" - resolve-from "^4.0.0" - slide "^1.1.6" - uid-number "0.0.6" - umask "^1.1.0" - which "^1.3.1" - npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== -npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-package-arg@^8.1.2, npm-package-arg@^8.1.5: +npm-package-arg@^8.0.0, npm-package-arg@^8.1.0, npm-package-arg@^8.1.2, npm-package-arg@^8.1.5: version "8.1.5" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== @@ -7698,12 +5267,13 @@ npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-pack semver "^7.3.4" validate-npm-package-name "^3.0.0" -npm-package-arg@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.0.2.tgz#f3ef7b1b3b02e82564af2d5228b4c36567dcd389" - integrity sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g== +npm-package-arg@^9.0.0, npm-package-arg@^9.0.1, npm-package-arg@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz#a60e9f1e7c03e4e3e4e994ea87fff8b90b522987" + integrity sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw== dependencies: hosted-git-info "^5.0.0" + proc-log "^2.0.1" semver "^7.3.5" validate-npm-package-name "^4.0.0" @@ -7717,25 +5287,25 @@ npm-packlist@^2.1.4: npm-bundled "^1.1.1" npm-normalize-package-bin "^1.0.1" -npm-packlist@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-3.0.0.tgz#0370df5cfc2fcc8f79b8f42b37798dd9ee32c2a9" - integrity sha512-L/cbzmutAwII5glUcf2DBRNY/d0TFd4e/FnaZigJV6JD85RHZXJFGwCndjMWiiViiWSsWt3tiOLpI3ByTnIdFQ== +npm-packlist@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.1.tgz#79bcaf22a26b6c30aa4dd66b976d69cc286800e0" + integrity sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw== dependencies: - glob "^7.1.6" - ignore-walk "^4.0.1" - npm-bundled "^1.1.1" + glob "^8.0.1" + ignore-walk "^5.0.1" + npm-bundled "^1.1.2" npm-normalize-package-bin "^1.0.1" -npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148" - integrity sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA== +npm-pick-manifest@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz#76dda30a7cd6b99be822217a935c2f5eacdaca4c" + integrity sha512-IA8+tuv8KujbsbLQvselW2XQgmXWS47t3CB0ZrzsRZ82DbDfkcFunOaPm4X7qNuhMfq+FmV7hQT4iFVpHqV7mg== dependencies: - npm-install-checks "^4.0.0" + npm-install-checks "^5.0.0" npm-normalize-package-bin "^1.0.1" - npm-package-arg "^8.1.2" - semver "^7.3.4" + npm-package-arg "^9.0.0" + semver "^7.3.5" npm-registry-fetch@^11.0.0: version "11.0.0" @@ -7749,17 +5319,18 @@ npm-registry-fetch@^11.0.0: minizlib "^2.0.0" npm-package-arg "^8.0.0" -npm-registry-fetch@^12.0.0, npm-registry-fetch@^12.0.1: - version "12.0.2" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-12.0.2.tgz#ae583bb3c902a60dae43675b5e33b5b1f6159f1e" - integrity sha512-Df5QT3RaJnXYuOwtXBXS9BWs+tHH2olvkCLh6jcR/b/u3DvPMlp3J0TvvYwplPKxHMOwfg287PYih9QqaVFoKA== +npm-registry-fetch@^13.0.0, npm-registry-fetch@^13.0.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.1.1.tgz#26dc4b26d0a545886e807748032ba2aefaaae96b" + integrity sha512-5p8rwe6wQPLJ8dMqeTnA57Dp9Ox6GH9H60xkyJup07FmVlu3Mk7pf/kIIpl9gaN5bM8NM+UUx3emUWvDNTt39w== dependencies: - make-fetch-happen "^10.0.1" + make-fetch-happen "^10.0.6" minipass "^3.1.6" - minipass-fetch "^1.4.1" + minipass-fetch "^2.0.3" minipass-json-stream "^1.0.1" minizlib "^2.1.2" - npm-package-arg "^8.1.5" + npm-package-arg "^9.0.1" + proc-log "^2.0.0" npm-registry-fetch@^9.0.0: version "9.0.0" @@ -7782,17 +5353,7 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npmlog@^4.0.1, npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -npmlog@^6.0.0: +npmlog@^6.0.0, npmlog@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== @@ -7802,98 +5363,17 @@ npmlog@^6.0.0: gauge "^4.0.3" set-blocking "^2.0.0" -nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -"nwmatcher@>= 1.3.7 < 2.0.0": - version "1.4.4" - resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" - integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ== - -nyc@^15.1.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" - integrity sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A== - dependencies: - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - caching-transform "^4.0.0" - convert-source-map "^1.7.0" - decamelize "^1.2.0" - find-cache-dir "^3.2.0" - find-up "^4.1.0" - foreground-child "^2.0.0" - get-package-type "^0.1.0" - glob "^7.1.6" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-hook "^3.0.0" - istanbul-lib-instrument "^4.0.0" - istanbul-lib-processinfo "^2.0.2" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - make-dir "^3.0.0" - node-preload "^0.2.1" - p-map "^3.0.0" - process-on-spawn "^1.0.0" - resolve-from "^5.0.0" - rimraf "^3.0.0" - signal-exit "^3.0.2" - spawn-wrap "^2.0.0" - test-exclude "^6.0.0" - yargs "^15.0.2" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@4.X, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-assign@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" - integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - object-inspect@^1.12.0, object-inspect@^1.9.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" - integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.2: +object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== @@ -7903,48 +5383,6 @@ object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.defaults@^1.0.0, object.defaults@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" - integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= - dependencies: - array-each "^1.0.1" - array-slice "^1.0.0" - for-own "^1.0.0" - isobject "^3.0.0" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" - integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.map@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" - integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= - dependencies: - for-own "^1.0.0" - make-iterator "^1.0.0" - -object.pick@^1.2.0, object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.reduce@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" - integrity sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60= - dependencies: - for-own "^1.0.0" - make-iterator "^1.0.0" - object.values@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" @@ -7961,10 +5399,10 @@ on-finished@^2.3.0: dependencies: ee-first "1.1.1" -once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" @@ -7978,7 +5416,7 @@ onetime@^5.1.0, onetime@^5.1.2: only@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" - integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= + integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== open@^8.4.0: version "8.4.0" @@ -7989,18 +5427,6 @@ open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" -optionator@^0.8.1, optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -8013,62 +5439,35 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" +ora@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ora/-/ora-6.1.2.tgz#7b3c1356b42fd90fb1dad043d5dbe649388a0bf5" + integrity sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw== + dependencies: + bl "^5.0.0" + chalk "^5.0.0" + cli-cursor "^4.0.0" + cli-spinners "^2.6.1" + is-interactive "^2.0.0" + is-unicode-supported "^1.1.0" + log-symbols "^5.1.0" + strip-ansi "^7.0.1" wcwidth "^1.0.1" -ordered-read-streams@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" - integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= - dependencies: - readable-stream "^2.0.1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: +os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-limit@^1.1.0: version "1.3.0" @@ -8077,7 +5476,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -8091,20 +5490,20 @@ p-limit@^3.0.2: dependencies: yocto-queue "^0.1.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== dependencies: p-limit "^1.1.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -8119,18 +5518,18 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + p-map-series@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - p-map@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" @@ -8166,7 +5565,7 @@ p-timeout@^3.2.0: p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== p-try@^2.0.0: version "2.2.0" @@ -8180,65 +5579,32 @@ p-waterfall@^2.1.1: dependencies: p-reduce "^2.0.0" -package-hash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-4.0.0.tgz#3537f654665ec3cc38827387fc904c163c54f506" - integrity sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ== - dependencies: - graceful-fs "^4.1.15" - hasha "^5.0.0" - lodash.flattendeep "^4.4.0" - release-zalgo "^1.0.0" - -pacote@^11.2.6: - version "11.3.5" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.3.5.tgz#73cf1fc3772b533f575e39efa96c50be8c3dc9d2" - integrity sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg== - dependencies: - "@npmcli/git" "^2.1.0" - "@npmcli/installed-package-contents" "^1.0.6" - "@npmcli/promise-spawn" "^1.2.0" - "@npmcli/run-script" "^1.8.2" - cacache "^15.0.5" - chownr "^2.0.0" - fs-minipass "^2.1.0" - infer-owner "^1.0.4" - minipass "^3.1.3" - mkdirp "^1.0.3" - npm-package-arg "^8.0.1" - npm-packlist "^2.1.4" - npm-pick-manifest "^6.0.0" - npm-registry-fetch "^11.0.0" - promise-retry "^2.0.1" - read-package-json-fast "^2.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.1.0" - -pacote@^12.0.3: - version "12.0.3" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-12.0.3.tgz#b6f25868deb810e7e0ddf001be88da2bcaca57c7" - integrity sha512-CdYEl03JDrRO3x18uHjBYA9TyoW8gy+ThVcypcDkxPtKlw76e4ejhYB6i9lJ+/cebbjpqPW/CijjqxwDTts8Ow== +pacote@^13.0.3, pacote@^13.0.5, pacote@^13.4.1, pacote@^13.6.1: + version "13.6.1" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.6.1.tgz#ac6cbd9032b4c16e5c1e0c60138dfe44e4cc589d" + integrity sha512-L+2BI1ougAPsFjXRyBhcKmfT016NscRFLv6Pz5EiNf1CCFJFU0pSKKQwsZTyAQB+sTuUL4TyFyp6J1Ork3dOqw== dependencies: - "@npmcli/git" "^2.1.0" - "@npmcli/installed-package-contents" "^1.0.6" - "@npmcli/promise-spawn" "^1.2.0" - "@npmcli/run-script" "^2.0.0" - cacache "^15.0.5" + "@npmcli/git" "^3.0.0" + "@npmcli/installed-package-contents" "^1.0.7" + "@npmcli/promise-spawn" "^3.0.0" + "@npmcli/run-script" "^4.1.0" + cacache "^16.0.0" chownr "^2.0.0" fs-minipass "^2.1.0" infer-owner "^1.0.4" - minipass "^3.1.3" - mkdirp "^1.0.3" - npm-package-arg "^8.0.1" - npm-packlist "^3.0.0" - npm-pick-manifest "^6.0.0" - npm-registry-fetch "^12.0.0" + minipass "^3.1.6" + mkdirp "^1.0.4" + npm-package-arg "^9.0.0" + npm-packlist "^5.1.0" + npm-pick-manifest "^7.0.0" + npm-registry-fetch "^13.0.1" + proc-log "^2.0.0" promise-retry "^2.0.1" - read-package-json-fast "^2.0.1" + read-package-json "^5.0.0" + read-package-json-fast "^2.0.3" rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.1.0" + ssri "^9.0.0" + tar "^6.1.11" parent-module@^1.0.0: version "1.0.1" @@ -8247,26 +5613,19 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-filepath@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" - integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= - dependencies: - is-absolute "^1.0.0" - map-cache "^0.2.0" - path-root "^0.1.1" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= +parse-conflict-json@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/parse-conflict-json/-/parse-conflict-json-2.0.2.tgz#3d05bc8ffe07d39600dc6436c6aefe382033d323" + integrity sha512-jDbRGb00TAPFsKWCpZZOT93SxVP9nONOSgES3AevqRq/CHvavEBvKAjxX9p5Y5F0RZLxH9Ufd9+RwtCsa+lFDA== dependencies: - error-ex "^1.2.0" + json-parse-even-better-errors "^2.3.1" + just-diff "^5.0.1" + just-diff-apply "^5.2.0" parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== dependencies: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" @@ -8281,94 +5640,52 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-ms@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" - integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== - -parse-node-version@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" - integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - -parse-path@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.3.tgz#82d81ec3e071dcc4ab49aa9f2c9c0b8966bb22bf" - integrity sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA== - dependencies: - is-ssh "^1.3.0" - protocols "^1.4.0" - qs "^6.9.4" - query-string "^6.13.8" +parse-ms@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-3.0.0.tgz#3ea24a934913345fcc3656deda72df921da3a70e" + integrity sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw== -parse-url@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-6.0.0.tgz#f5dd262a7de9ec00914939220410b66cff09107d" - integrity sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw== +parse-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-5.0.0.tgz#f933152f3c6d34f4cf36cfc3d07b138ac113649d" + integrity sha512-qOpH55/+ZJ4jUu/oLO+ifUKjFPNZGfnPJtzvGzKN/4oLMil5m9OH4VpOj6++9/ytJcfks4kzH2hhi87GL/OU9A== dependencies: - is-ssh "^1.3.0" - normalize-url "^6.1.0" - parse-path "^4.0.0" - protocols "^1.4.0" + protocols "^2.0.0" -parse5@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" - integrity sha1-m387DeMr543CQBsXVzzK8Pb1nZQ= - -parse5@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" - integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== +parse-url@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-7.0.2.tgz#d21232417199b8d371c6aec0cedf1406fd6393f0" + integrity sha512-PqO4Z0eCiQ08Wj6QQmrmp5YTTxpYfONdOEamrtvK63AmzXpcavIVQubGHxOEwiIoDZFb8uDOoQFS0NCcjqIYQg== dependencies: - "@types/node" "*" + is-ssh "^1.4.0" + normalize-url "^6.1.0" + parse-path "^5.0.0" + protocols "^2.0.1" parseurl@^1.3.2: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" @@ -8380,39 +5697,11 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-root-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" - integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= - -path-root@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" - integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= - dependencies: - path-root-regex "^0.1.0" - -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - -path-to-regexp@^6.1.0: +path-to-regexp@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -8430,35 +5719,20 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.0.0, pify@^2.3.0: +pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== pify@^4.0.1: version "4.0.1" @@ -8470,94 +5744,29 @@ pify@^5.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pirates@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-dir@^4.1.0, pkg-dir@^4.2.0: +pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" -pkg-dir@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" - integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== - dependencies: - find-up "^5.0.0" - -plugin-error@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" - integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= - dependencies: - ansi-cyan "^0.1.1" - ansi-red "^0.1.1" - arr-diff "^1.0.1" - arr-union "^2.0.1" - extend-shallow "^1.1.2" - -plugin-error@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" - integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== - dependencies: - ansi-colors "^1.0.1" - arr-diff "^4.0.0" - arr-union "^3.1.0" - extend-shallow "^3.0.2" - -plur@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/plur/-/plur-3.1.1.tgz#60267967866a8d811504fe58f2faaba237546a5b" - integrity sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w== +pkg-dir@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-6.0.1.tgz#8ec964cecaef98a2bdb9c164733f90a5bcd2352d" + integrity sha512-C9R+PTCKGA32HG0n5I4JMYkdLL58ZpayVuncQHQrGeKa8o26A4o2x0u6BKekHG+Au0jv5ZW7Xfq1Cj6lm9Ag4w== dependencies: - irregular-plurals "^2.0.0" + find-up "^6.1.0" pluralize@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss@^7.0.16: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - prebuild-install@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.0.tgz#991b6ac16c81591ba40a6d5de93fb33673ac1370" - integrity sha512-CNcMgI1xBypOyGqjp3wOc8AAo1nMhZS3Cwd3iHIxOdAUbb+YxdNuM4Z5iIrZ8RLvOsf3F3bl7b7xGq6DjQoNYA== + version "7.1.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== dependencies: detect-libc "^2.0.0" expand-template "^2.0.3" @@ -8566,7 +5775,6 @@ prebuild-install@^7.0.1: mkdirp-classic "^0.5.3" napi-build-utils "^1.0.1" node-abi "^3.3.0" - npmlog "^4.0.1" pump "^3.0.0" rc "^1.2.7" simple-get "^4.0.0" @@ -8578,56 +5786,42 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -pretty-bytes@^5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" - integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== - -pretty-hrtime@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= +pretty-bytes@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.0.0.tgz#928be2ad1f51a2e336add8ba764739f9776a8140" + integrity sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg== -pretty-log@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/pretty-log/-/pretty-log-0.1.0.tgz#54b449dd42186168c555e975af75709378f486f1" - integrity sha1-VLRJ3UIYYWjFVel1r3Vwk3j0hvE= +pretty-ms@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-8.0.0.tgz#a35563b2a02df01e595538f86d7de54ca23194a3" + integrity sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q== dependencies: - colors "^0.6.2" + parse-ms "^3.0.0" -pretty-ms@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-7.0.1.tgz#7d903eaab281f7d8e03c66f867e239dc32fb73e8" - integrity sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q== - dependencies: - parse-ms "^2.1.0" +proc-log@^2.0.0, proc-log@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-2.0.1.tgz#8f3f69a1f608de27878f91f5c688b225391cb685" + integrity sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw== -process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: +process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process-on-spawn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93" - integrity sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg== - dependencies: - fromentries "^1.2.0" +promise-all-reject-late@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2" + integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw== -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +promise-call-limit@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.1.tgz#4bdee03aeb85674385ca934da7114e9bcd3c6e24" + integrity sha512-3+hgaa19jzCGLuSCbieeRsu5C2joKfYn8pY6JAuXFRVfF4IO+L7UPpFWNTeWT9pM7uhskvbPPd/oEOktCn317Q== promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== promise-limit@^2.7.0: version "2.7.0" @@ -8645,32 +5839,19 @@ promise-retry@^2.0.1: promzard@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= + integrity sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw== dependencies: read "1" proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - -protocols@^1.1.0, protocols@^1.4.0: - version "1.4.8" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" - integrity sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg== + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -pump@^2.0.0: +protocols@^2.0.0, protocols@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" + integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== pump@^3.0.0: version "3.0.0" @@ -8680,15 +5861,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pumpify@^1.3.5: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -8697,30 +5869,15 @@ punycode@^2.1.0, punycode@^2.1.1: q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== -qs@^6.5.2, qs@^6.9.4: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== +qs@^6.5.2: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - -query-string@^6.13.8: - version "6.14.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" - integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== - dependencies: - decode-uri-component "^0.2.0" - filter-obj "^1.1.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -8736,10 +5893,10 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -ramda@^0.27.1: - version "0.27.2" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.2.tgz#84463226f7f36dc33592f6f4ed6374c48306c3f1" - integrity sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA== +rambda@^7.1.0: + version "7.1.4" + resolved "https://registry.yarnpkg.com/rambda/-/rambda-7.1.4.tgz#7faa9665a54c5d81773975532a942b3113bb4a56" + integrity sha512-bPK8sSiVHIC7CqdWga8R+hRi5hfc4hK6S01lZW4KrLwSNryQoKaCOJA9GNiF20J7Nbe1vejRfR37/ASQXFL5EA== randombytes@^2.1.0: version "2.1.0" @@ -8758,7 +5915,7 @@ raw-body@^2.3.3: iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.2.7, rc@^1.2.8: +rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -8773,7 +5930,12 @@ read-cmd-shim@^2.0.0: resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz#4a50a71d6f0965364938e9038476f7eede3928d9" integrity sha512-HJpV9bQpkl6KwjxlJcBoqu9Ba0PQg8TqSNIOrulGt54a0uup0HtevreFHzYzkm0lpnleRdNBzXznKrgxglEHQw== -read-package-json-fast@^2.0.1: +read-cmd-shim@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-3.0.0.tgz#62b8c638225c61e6cc607f8f4b779f3b8238f155" + integrity sha512-KQDVjGqhZk92PPNRj9ZEXEuqg8bUobSKRw+q0YQ3TKI5xkce7bUJobL4Z/OtiEbAAv70yEpYIXp4iQ9L8oPVog== + +read-package-json-fast@^2.0.2, read-package-json-fast@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== @@ -8781,16 +5943,6 @@ read-package-json-fast@^2.0.1: json-parse-even-better-errors "^2.3.0" npm-normalize-package-bin "^1.0.1" -read-package-json@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" - integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== - dependencies: - glob "^7.1.1" - json-parse-even-better-errors "^2.3.0" - normalize-package-data "^2.0.0" - npm-normalize-package-bin "^1.0.0" - read-package-json@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-3.0.1.tgz#c7108f0b9390257b08c21e3004d2404c806744b9" @@ -8811,27 +5963,20 @@ read-package-json@^4.1.1: normalize-package-data "^3.0.0" npm-normalize-package-bin "^1.0.0" -read-package-tree@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636" - integrity sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw== - dependencies: - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - util-promisify "^2.1.0" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= +read-package-json@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-5.0.1.tgz#1ed685d95ce258954596b13e2e0e76c7d0ab4c26" + integrity sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg== dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" + glob "^8.0.1" + json-parse-even-better-errors "^2.3.1" + normalize-package-data "^4.0.0" + npm-normalize-package-bin "^1.0.1" read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== dependencies: find-up "^2.0.0" read-pkg "^3.0.0" @@ -8845,19 +5990,10 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== dependencies: load-json-file "^4.0.0" normalize-package-data "^2.3.2" @@ -8876,21 +6012,11 @@ read-pkg@^5.2.0: read@1, read@~1.0.1: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ== dependencies: mute-stream "~0.0.4" -readable-stream@1.1: - version "1.1.13" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" - integrity sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: +readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -8899,7 +6025,7 @@ readable-stream@1.1: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -8912,17 +6038,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readdir-scoped-modules@^1.0.0: +readdir-scoped-modules@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== @@ -8932,15 +6048,6 @@ readdir-scoped-modules@^1.0.0: graceful-fs "^4.1.2" once "^1.3.0" -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -8948,13 +6055,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -8963,25 +6063,12 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - regexp-tree@~0.1.1: version "0.1.24" resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.24.tgz#3d6fa238450a4d66e5bc9c4c14bb720e2196829d" integrity sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw== -regexp.prototype.flags@^1.4.1: +regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== @@ -8990,142 +6077,24 @@ regexp.prototype.flags@^1.4.1: define-properties "^1.1.3" functions-have-names "^1.2.2" -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpp@^3.0.0, regexpp@^3.1.0: +regexpp@^3.0.0, regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -registry-auth-token@4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" - integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== - dependencies: - rc "^1.2.8" - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= - dependencies: - es6-error "^4.0.1" - -remove-bom-buffer@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" - integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== - dependencies: - is-buffer "^1.1.5" - is-utf8 "^0.2.1" - -remove-bom-stream@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" - integrity sha1-BfGlk/FuQuH7kOv1nejlaVJflSM= - dependencies: - remove-bom-buffer "^3.0.0" - safe-buffer "^5.1.0" - through2 "^2.0.3" - -remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -repeating@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac" - integrity sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw= - dependencies: - is-finite "^1.0.0" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= +registry-auth-token@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.1.tgz#5e6cd106e6c251135a046650c58476fc03e92833" + integrity sha512-UfxVOj8seK1yaIOiieV4FIP01vfBDLsY0H9sQzi9EbbUdJiuuBjJgLa1DpImXMNPnVkBD4eVxTEXcrZA6kfpJA== dependencies: - is-finite "^1.0.0" - -replace-ext@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" - integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= - -replace-ext@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" - integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== - -replace-homedir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" - integrity sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw= - dependencies: - homedir-polyfill "^1.0.1" - is-absolute "^1.0.0" - remove-trailing-separator "^1.1.0" - -request@^2.55.0, request@^2.88.0, request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" + "@pnpm/npm-conf" "^1.0.4" require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== -resolve-alpn@^1.0.0: +resolve-alpn@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== @@ -9137,14 +6106,6 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" -resolve-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -9155,24 +6116,12 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-options@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" - integrity sha1-MrueOcBtZzONyTeMDW1gdFZq0TE= - dependencies: - value-or-function "^3.0.0" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.4.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== dependencies: - is-core-module "^2.8.1" + is-core-module "^2.9.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -9191,15 +6140,18 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +restore-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" + integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== reusify@^1.0.4: version "1.0.4" @@ -9211,20 +6163,6 @@ rfdc@^1.3.0: resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -9251,14 +6189,14 @@ rxjs@^6.6.0: dependencies: tslib "^1.9.0" -rxjs@^7.5.5: +rxjs@^7.0.0, rxjs@^7.5.5: version "7.5.5" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== dependencies: tslib "^2.1.0" -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -9268,13 +6206,6 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - safe-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2" @@ -9282,46 +6213,34 @@ safe-regex@^2.1.1: dependencies: regexp-tree "~0.1.1" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@^1.1.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver-greatest-satisfied-range@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" - integrity sha1-E+jCZYq5aRywzXEJMkAoDTb3els= - dependencies: - sver-compat "^1.5.0" - -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: +semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" -serialize-error@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67" - integrity sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ== +serialize-error@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-11.0.0.tgz#0129f2b07b19b09bc7a5f2d850ffe9cd2d561582" + integrity sha512-YKrURWDqcT3VGX/s/pCwaWtpfJEEaEw5Y4gAnQDku92b/HjVj4r4UhA5QrMVMFotymK2wIWs5xthny5SMFu7Vw== dependencies: - type-fest "^0.20.2" + type-fest "^2.12.2" serialize-javascript@6.0.0: version "6.0.0" @@ -9330,25 +6249,15 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -set-cookie-parser@^2.4.8: - version "2.4.8" - resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz#d0da0ed388bc8f24e706a391f9c9e252a13c58b2" - integrity sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg== - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" +set-cookie-parser@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.5.0.tgz#96b59525e1362c94335c3c761100bb6e8f2da4b0" + integrity sha512-cHMAtSXilfyBePduZEBVPTCftTQWz6ehWJD5YNUg4mqvRosrrjKbo4WS8JkB0/RxonMoohHm7cOGH60mDkRQ9w== setprototypeof@1.2.0: version "1.2.0" @@ -9362,13 +6271,6 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -9376,16 +6278,16 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shell-quote@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -9395,7 +6297,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -9414,37 +6316,11 @@ simple-get@^4.0.0: once "^1.3.1" simple-concat "^1.0.0" -sinon-chai@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783" - integrity sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g== - -sinon@^11.1.2: - version "11.1.2" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-11.1.2.tgz#9e78850c747241d5c59d1614d8f9cbe8840e8674" - integrity sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw== - dependencies: - "@sinonjs/commons" "^1.8.3" - "@sinonjs/fake-timers" "^7.1.2" - "@sinonjs/samsam" "^6.0.2" - diff "^5.0.0" - nise "^5.1.0" - supports-color "^7.2.0" - 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" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - slice-ansi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" @@ -9463,56 +6339,20 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -slide@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= - smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -snooplogg@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/snooplogg/-/snooplogg-3.0.2.tgz#86f38bd06254c90c91e3df565face959e16b976e" - integrity sha512-WIeAbTRd64HEtkdoqwK8i9A+anSp1FZXai31fxBzcW8ESvg9wsBuD8+XPVNpX4i6ASUqH73NvXOUVeXzEb0Bcg== +snooplogg@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/snooplogg/-/snooplogg-5.0.0.tgz#978d2c14feb7c642ae008b6e0fd5f2d6a3da748c" + integrity sha512-CCuUxnTqxFvgjVNqn2utTzHqBeUmphqb+rRFE9b3vm6K8e9Eiy/HbLMnIVIVTZafw730YQOLVWwI/kbNDbJwPg== dependencies: - bryt "^1.0.2" - chalk "^4.1.0" - nanobuffer "^1.1.7" - source-map-support "^0.5.19" - supports-color "^8.1.0" + bryt-lite "^2.0.0" + chalk "^5.0.0" + nanobuffer "^3.0.0" + supports-color "^9.2.1" socks-proxy-agent@^5.0.0: version "5.0.1" @@ -9523,10 +6363,19 @@ socks-proxy-agent@^5.0.0: debug "4" socks "^2.3.3" -socks-proxy-agent@^6.0.0, socks-proxy-agent@^6.1.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz#f6b5229cc0cbd6f2f202d9695f09d871e951c85e" - integrity sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ== +socks-proxy-agent@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz#2687a31f9d7185e38d530bef1944fe1f1496d6ce" + integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== dependencies: agent-base "^6.0.2" debug "^4.3.3" @@ -9543,7 +6392,7 @@ socks@^2.3.3, socks@^2.6.2: sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== dependencies: is-plain-obj "^1.0.0" @@ -9554,26 +6403,7 @@ sort-keys@^4.0.0: dependencies: is-plain-obj "^2.0.0" -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-resolve@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" - integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - -source-map-support@^0.5.16, source-map-support@^0.5.19, source-map-support@^0.5.21: +source-map-support@^0.5.21, source-map-support@^0.5.6: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -9581,37 +6411,15 @@ source-map-support@^0.5.16, source-map-support@^0.5.19, source-map-support@^0.5. buffer-from "^1.0.0" source-map "^0.6.0" -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sparkles@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" - integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== - -spawn-wrap@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-2.0.0.tgz#103685b8b8f9b79771318827aa78650a610d457e" - integrity sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg== - dependencies: - foreground-child "^2.0.0" - is-windows "^1.0.2" - make-dir "^3.0.0" - rimraf "^3.0.0" - signal-exit "^3.0.2" - which "^2.0.1" +spawn-command@^0.0.2-1: + version "0.0.2-1" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== spdx-correct@^3.0.0: version "3.1.1" @@ -9639,18 +6447,6 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - split2@^3.0.0: version "3.2.2" resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" @@ -9665,26 +6461,6 @@ split@^1.0.0: dependencies: through "2" -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" @@ -9692,25 +6468,12 @@ ssri@^8.0.0, ssri@^8.0.1: dependencies: minipass "^3.1.1" -ssri@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.0.tgz#70ad90e339eb910f1a7ff1dcf4afc268326c4547" - integrity sha512-Y1Z6J8UYnexKFN1R/hxUaYoY2LVdKEzziPmVAFKiKX8fiwvCJTVzn/xYE9TEWod5OVyNfIHHuVfIEuBClL/uJQ== - dependencies: - minipass "^3.1.1" - -stack-trace@0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" + minipass "^3.1.1" statuses@2.0.1: version "2.0.1" @@ -9720,33 +6483,9 @@ statuses@2.0.1: "statuses@>= 1.5.0 < 2", statuses@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-exhaust@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" - integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -9755,14 +6494,14 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" string.prototype.trimend@^1.0.5: version "1.0.5" @@ -9789,11 +6528,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -9801,29 +6535,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-object@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -9831,22 +6542,17 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-bom-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" - integrity sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI= - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= +strip-ansi@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== dependencies: - is-utf8 "^0.2.0" + ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-bom@^4.0.0: version "4.0.0" @@ -9865,7 +6571,7 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@3.1.1, strip-json-comments@^3.0.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -9873,7 +6579,7 @@ strip-json-comments@3.1.1, strip-json-comments@^3.0.1, strip-json-comments@^3.1. strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== strong-log-transformer@^2.1.0: version "2.1.0" @@ -9891,11 +6597,6 @@ supports-color@8.1.1, supports-color@^8.1.0: dependencies: has-flag "^4.0.0" -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -9903,62 +6604,23 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0, supports-color@^7.2.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@^9.2.1: + version "9.2.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.2.tgz#502acaf82f2b7ee78eb7c83dcac0f89694e5a7bb" + integrity sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA== + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -sver-compat@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" - integrity sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg= - dependencies: - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - -"symbol-tree@>= 3.1.0 < 4.0.0": - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -table@^6.0.9: - version "6.8.0" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" - integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - -taffydb@2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.7.2.tgz#7bf8106a5c1a48251b3e3bc0a0e1732489fd0dc8" - integrity sha1-e/gQalwaSCUbPjvAoOFzJIn9Dcg= - -taffydb@2.7.3: - version "2.7.3" - resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.7.3.tgz#2ad37169629498fca5bc84243096d3cde0ec3a34" - integrity sha1-KtNxaWKUmPylvIQkMJbTzeDsOjQ= - tar-fs@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" @@ -9980,19 +6642,6 @@ tar-stream@^2.1.4, tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -tar@^4.4.12: - version "4.4.19" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - tar@^6.0.2, tar@^6.1.0, tar@^6.1.11, tar@^6.1.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" @@ -10008,18 +6657,7 @@ tar@^6.0.2, tar@^6.1.0, tar@^6.1.11, tar@^6.1.2: temp-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= - -temp-write@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-4.0.0.tgz#cd2e0825fc826ae72d201dc26eef3bf7e6fc9320" - integrity sha512-HIeWmj77uOOHb0QX7siN3OtwV3CTntquin6TNVg6SHOqCP3hYKmox90eeFOGaY1MqJ9WYDDjkyZrW6qS5AWpbw== - dependencies: - graceful-fs "^4.1.15" - is-stream "^2.0.0" - make-dir "^3.0.0" - temp-dir "^1.0.0" - uuid "^3.3.2" + integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== test-exclude@^6.0.0: version "6.0.0" @@ -10038,17 +6676,9 @@ text-extensions@^1.0.0: text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -through2-filter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" - integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== - dependencies: - through2 "~2.0.0" - xtend "~4.0.0" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: +through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -10056,14 +6686,6 @@ through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" -through2@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" - integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== - dependencies: - inherits "^2.0.4" - readable-stream "2 || 3" - through2@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" @@ -10074,27 +6696,7 @@ through2@^4.0.0: through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -tildify@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" - integrity sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo= - dependencies: - os-homedir "^1.0.0" - -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= - -timers-ext@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" - integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== - dependencies: - es5-ext "~0.10.46" - next-tick "1" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== tmp@^0.0.33: version "0.0.33" @@ -10110,39 +6712,6 @@ tmp@^0.2.1: dependencies: rimraf "^3.0.0" -to-absolute-glob@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" - integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= - dependencies: - is-absolute "^1.0.0" - is-negated-glob "^1.0.0" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - 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" @@ -10150,36 +6719,11 @@ to-regex-range@^5.0.1: 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" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -to-through@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" - integrity sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY= - dependencies: - through2 "^2.0.3" - toidentifier@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@^2.2.0, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" @@ -10187,22 +6731,69 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" -tr46@~0.0.1, tr46@~0.0.3: +tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +treeverse@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/treeverse/-/treeverse-2.0.0.tgz#036dcef04bc3fd79a9b79a68d4da03e882d8a9ca" + integrity sha512-N5gJCkLu1aXccpOTtqV6ddSEi6ZmGkh3hjmbu1IjcavJK4qyOVQmi0myQKM7z5jVGmD68SJoliaVrMmVObhj6A== trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= +ts-mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" + integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== + dependencies: + ts-node "7.0.1" + optionalDependencies: + tsconfig-paths "^3.5.0" -tsconfig-paths@^3.14.1: +ts-node@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + +ts-node@^10.8.2: + version "10.8.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.8.2.tgz#3185b75228cef116bf82ffe8762594f54b2a23f2" + integrity sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +tsconfig-paths@^3.14.1, tsconfig-paths@^3.5.0: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== @@ -10212,7 +6803,7 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^1.9.0: +tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -10227,17 +6818,109 @@ tsscmp@1.0.6: resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== dependencies: safe-buffer "^5.0.1" -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +turbo-android-arm64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-android-arm64/-/turbo-android-arm64-1.3.1.tgz#dae9bd087d6a17409fbd10ed82489a1ff39cbcc8" + integrity sha512-JcnZh9tLbZDpKaXaao/s/k4qXt3TbNEc1xEYYXurVWnqiMueGeS7QAtThVB85ZSqzj7djk+ngSrZabPy5RG25Q== + +turbo-darwin-64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.3.1.tgz#efe64b9589f6a0f475b5123538b487d29e00d242" + integrity sha512-TIGDradVFoGck86VIuM38KaDeNxdKaP2ti93UpQeFw26ZhPIeTAa6wUgnz4DQP6bjIvQmXlYJ16ETZb4tFYygg== + +turbo-darwin-arm64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.3.1.tgz#94a361e4e73ad02995303cf6c3d8cb03e85fcae4" + integrity sha512-aLBq8KiMMmop7uKBkvDt/y+eER2UzxZyUzh1KWcZ7DZB5tFZnknEUyf2qggY2vd2WcDVfQ1EUjZ0MFxhhVaVzA== + +turbo-freebsd-64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-freebsd-64/-/turbo-freebsd-64-1.3.1.tgz#64b8fc1b9f2ad9b76b532ffdcce267b2934ecb86" + integrity sha512-BOr/ifmxjlBeuDkDQLUJtzqzXQ2zPHHcI14U9Ys+z4Mza1uzQn/oSJqQvU5RuyRBVai7noMrpPS7QuKtDz0Cyg== + +turbo-freebsd-arm64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-freebsd-arm64/-/turbo-freebsd-arm64-1.3.1.tgz#b798af9b8898210058ca2752eadb711369f9ecea" + integrity sha512-bHPZjK4xnGLz6/oxl5XmWhdYOdtBMSadrGhptWSZ0wBGNn/gQzDTeZAkQeqhh25AD0eM1hzDe8QUz8GlS43lrA== + +turbo-linux-32@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-linux-32/-/turbo-linux-32-1.3.1.tgz#9eecada1c13f6391a7c6267349a0486987144093" + integrity sha512-c5okimusfvivu9wS8MKSr+rXpQAV+M4TyR9JX+spIK8B1I7AjfECAqiK2D5WFWO1bQ33bUAuxXOEpUuLpgEm+g== + +turbo-linux-64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.3.1.tgz#eaf195b90a80f238561ab11fbde17c07af481c57" + integrity sha512-O0pNX+N5gbmRcyZT+jsCPUNCN3DpIZHqNN35j7MT5nr0IkZa83CGbZnrEc+7Qws//jFJ26EngqD/JyRB2E8nwQ== + +turbo-linux-arm64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.3.1.tgz#ff9dc17c352c5f59440cb55cff59cb8b23db9d1b" + integrity sha512-D6+1MeS/x+/VCCooHPU4NIpB8qI/eW70eMRA79bqTPaxxluP0g2CaxXgucco05P51YtNsSxeVcH7X76iadON6Q== + +turbo-linux-arm@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-linux-arm/-/turbo-linux-arm-1.3.1.tgz#6be53e62a60a3c6f3ab33585f0442eb7441ecf3a" + integrity sha512-f+r6JIwv/7ylxxJtgVi8cVw+6oNoD/r1IMTU6ejH8bfyMZZko4kkNwH9VYribQ44KDkJEgzdltnzFG5f6Hz10g== + +turbo-linux-mips64le@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-linux-mips64le/-/turbo-linux-mips64le-1.3.1.tgz#ceddf8c8e222e66d05f7a68a71f66a2a3a0272a3" + integrity sha512-yL64jgwVCziOpBcdpMxIsczkgwwOvmaqKObFKWyCNlk/LOl5NKODLwXEaryLaALtpwUAoS4ltMSI64gKqmLrOA== + +turbo-linux-ppc64le@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-linux-ppc64le/-/turbo-linux-ppc64le-1.3.1.tgz#aa5658f6d19775e06b9fd136491dceab93ecffb2" + integrity sha512-tjnM+8RosykS1lBpOPLDXGOz/Po2h796ty17uBd7IFslWPOI16a/akFOFoLH8PCiGGJMe3CYgRhEKn4sPWNxFA== + +turbo-windows-32@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-windows-32/-/turbo-windows-32-1.3.1.tgz#e6e570bb381d9a4f78ea6e72102ab9bf493a3ad2" + integrity sha512-Snnv+TVigulqwK6guHKndMlrLw88NXj8BtHRGrEksPR0QkyuHlwLf+tHYB4HmvpUl4W9lnXQf4hsljWP64BEdw== + +turbo-windows-64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.3.1.tgz#f891097331125c935cdaa160cc80c4cfc3e61b0e" + integrity sha512-gLeohHG07yIhON1Pp0YNE00i/yzip2GFhkA6HdJaK95uE5bKULpqxuO414hOS/WzGwrGVXBKCImfe24XXh5T+Q== + +turbo-windows-arm64@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.3.1.tgz#5abe1743b93e272641018cef213b21ac6c984f04" + integrity sha512-0MWcHLvYgs/qdcoTFZ55nu8HhrpeiwXEMw9cbNfgqTlzy3OsrAsovYEJFyQ8KSxeploiD+QJlCdvhxx+5C0tlA== + +turbo@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.3.1.tgz#8091f3c8b654addaac84f9452476204a879b32ea" + integrity sha512-DXckoGKlZgvTn/PrHpBI/57aeXR7tfyPf2dK+4LmBczt24ELA3o6eYHeA7KzfpSYhB2LE9qveYFQ6mJ1OzGjjg== + optionalDependencies: + turbo-android-arm64 "1.3.1" + turbo-darwin-64 "1.3.1" + turbo-darwin-arm64 "1.3.1" + turbo-freebsd-64 "1.3.1" + turbo-freebsd-arm64 "1.3.1" + turbo-linux-32 "1.3.1" + turbo-linux-64 "1.3.1" + turbo-linux-arm "1.3.1" + turbo-linux-arm64 "1.3.1" + turbo-linux-mips64le "1.3.1" + turbo-linux-ppc64le "1.3.1" + turbo-windows-32 "1.3.1" + turbo-windows-64 "1.3.1" + turbo-windows-arm64 "1.3.1" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -10246,14 +6929,7 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: +type-detect@^4.0.0, type-detect@^4.0.5: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -10283,11 +6959,16 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== -type-fest@^0.8.0, type-fest@^0.8.1: +type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^2.12.2, type-fest@^2.13.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.16.0.tgz#1250fbd64dafaf4c8e405e393ef3fb16d9651db2" + integrity sha512-qpaThT2HQkFb83gMOrdKVsfCN7LKxP26Yq+smPzY1FqoHRjqmjqHXA7n5Gkxi8efirtbeEUxzfEdePthQWCuHw== + type-is@^1.6.16: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -10296,16 +6977,6 @@ type-is@^1.6.16: media-typer "0.3.0" mime-types "~2.1.24" -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" - integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -10316,22 +6987,17 @@ typedarray-to-buffer@^3.1.5: typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -uglify-js@^3.1.4: - version "3.15.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.5.tgz#2b10f9e0bfb3f5c15a8e8404393b6361eaeb33b3" - integrity sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ== - -uid-number@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= +typescript@^4.7.4: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== -umask@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" - integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= +uglify-js@^3.1.4: + version "3.16.2" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.2.tgz#0481e1dbeed343ad1c2ddf3c6d42e89b7a6d4def" + integrity sha512-AaQNokTNgExWrkEYA24BTNMSjyqEXPSfhqoS0AxmHkCJ4U+Dyy5AvbGV/sqxuxficEfGGoX3zWw9R7QpLFfEsg== unbox-primitive@^1.0.2: version "1.0.2" @@ -10343,42 +7009,6 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -unc-path-regex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" - integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= - -undertaker-registry@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" - integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA= - -undertaker@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.3.0.tgz#363a6e541f27954d5791d6fa3c1d321666f86d18" - integrity sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg== - dependencies: - arr-flatten "^1.0.1" - arr-map "^2.0.0" - bach "^1.0.0" - collection-map "^1.0.0" - es6-weak-map "^2.0.1" - fast-levenshtein "^1.0.0" - last-run "^1.1.0" - object.defaults "^1.0.0" - object.reduce "^1.0.0" - undertaker-registry "^1.0.0" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -10393,24 +7023,11 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -unique-stream@^2.0.2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" - integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== - dependencies: - json-stable-stringify-without-jsonify "^1.0.1" - through2-filter "^3.0.0" - universal-user-agent@^6.0.0: version "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.0: - 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" @@ -10419,20 +7036,7 @@ universalify@^2.0.0: unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== upath@^2.0.1: version "2.0.1" @@ -10446,29 +7050,12 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util-promisify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53" - integrity sha1-PCI2R2xNMsX/PEcAKt18E7moKlM= - dependencies: - object.getownpropertydescriptors "^2.0.3" - -uuid@^3.3.2, uuid@^3.3.3: +uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== @@ -10478,17 +7065,24 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -v8flags@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" - integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== +v8-to-istanbul@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== dependencies: - homedir-polyfill "^1.0.1" + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" @@ -10501,7 +7095,7 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: validate-npm-package-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== dependencies: builtins "^1.0.3" @@ -10512,122 +7106,37 @@ validate-npm-package-name@^4.0.0: dependencies: builtins "^5.0.0" -value-or-function@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" - integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= - vary@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vinyl-fs@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" - integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== - dependencies: - fs-mkdirp-stream "^1.0.0" - glob-stream "^6.1.0" - graceful-fs "^4.0.0" - is-valid-glob "^1.0.0" - lazystream "^1.0.0" - lead "^1.0.0" - object.assign "^4.0.4" - pumpify "^1.3.5" - readable-stream "^2.3.3" - remove-bom-buffer "^3.0.0" - remove-bom-stream "^1.2.0" - resolve-options "^1.1.0" - through2 "^2.0.0" - to-through "^2.0.0" - value-or-function "^3.0.0" - vinyl "^2.0.0" - vinyl-sourcemap "^1.1.0" - -vinyl-sourcemap@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" - integrity sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY= - dependencies: - append-buffer "^1.0.2" - convert-source-map "^1.5.0" - graceful-fs "^4.1.6" - normalize-path "^2.1.1" - now-and-later "^2.0.0" - remove-bom-buffer "^3.0.0" - vinyl "^2.0.0" - -vinyl-sourcemaps-apply@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" - integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU= - dependencies: - source-map "^0.5.1" - -vinyl@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" - integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - -vinyl@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" - integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" +walk-up-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e" + integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg== wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== dependencies: defaults "^1.0.3" -webidl-conversions@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-2.0.1.tgz#3bf8258f7d318c7443c36f2e169402a1a6703506" - integrity sha1-O/glj30xjHRDw28uFpQCoaZwNQY= - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== webidl-conversions@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== -whatwg-url-compat@~0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz#00898111af689bb097541cd5a45ca6c8798445bf" - integrity sha1-AImBEa9om7CXVBzVpFymyHmERb8= - dependencies: - tr46 "~0.0.1" - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" @@ -10652,45 +7161,28 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2, which@^2.0.1, which@^2.0.2: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -which@^1.2.14, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0, wide-align@^1.1.5: +wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: string-width "^1.0.2 || 2 || 3 || 4" -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== +widest-line@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" + integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig== dependencies: - string-width "^4.0.0" + string-width "^5.0.1" -word-wrap@^1.2.3, word-wrap@~1.2.3: +word-wrap@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -10698,20 +7190,12 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: wordwrap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== wrap-ansi@^6.2.0: version "6.2.0" @@ -10731,10 +7215,19 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.0.1.tgz#2101e861777fec527d0ea90c57c6b03aac56a5b3" + integrity sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^2.4.2: version "2.4.3" @@ -10755,6 +7248,14 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write-file-atomic@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f" + integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + write-json-file@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" @@ -10788,53 +7289,16 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@^7.5.7: - version "7.5.7" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" - integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== - -"xml-name-validator@>= 2.0.1 < 3.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" - integrity sha1-TYuPHszTQZqjYgYb7O9RXh5VljU= - -xml@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= - -xtend@~4.0.0, xtend@~4.0.1: +xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -y18n@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" - integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.0, yallist@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" @@ -10850,26 +7314,15 @@ yargs-parser@20.2.4: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== -yargs-parser@^18.1.2: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^20.2.2, yargs-parser@^20.2.3: +yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" - integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA== - dependencies: - camelcase "^3.0.0" - object.assign "^4.1.0" +yargs-parser@^21.0.0: + version "21.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" + integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== yargs-unparser@2.0.0: version "2.0.0" @@ -10894,48 +7347,40 @@ yargs@16.2.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^15.0.2: - version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" - integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== +yargs@^17.3.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - -yargs@^7.1.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" - integrity sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA== - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" ylru@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.3.2.tgz#0de48017473275a4cbdfc83a1eaf67c01af8a785" integrity sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA== +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== + 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== + +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==