From c6d25368f075cc29eea37d7282040fea272a4605 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 2 Jan 2024 13:39:51 -0500 Subject: [PATCH 01/93] Make change to assume dest folder. Delete 2 old tests that looked for old behavior, add 2 more tests that look for new behavior --- src/RokuDeploy.spec.ts | 52 ++++++++++++++++++++++++------------------ src/RokuDeploy.ts | 4 +++- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index c090fd4..9aaff30 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3062,28 +3062,6 @@ describe('index', () => { }]); }); - it('works for other globs without dest', async () => { - expect(await getFilePaths([{ - src: `components/screen1/*creen1.brs` - }])).to.eql([{ - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`screen1.brs` - }]); - }); - - it('skips directory folder names for other globs without dest', async () => { - expect(await getFilePaths([{ - //straight wildcard matches folder names too - src: `components/*` - }])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`component1.xml` - }]); - }); - it('applies negated patterns', async () => { writeFiles(rootDir, [ 'components/component1.brs', @@ -3281,6 +3259,36 @@ describe('index', () => { await fsExtra.remove(s`${thisRootDir}/../`); } }); + + it('maintains original file path', async () => { + fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); + expect( + await rokuDeploy.getFilePaths([ + 'components/CustomButton.brs' + ], rootDir) + ).to.eql([{ + src: s`${rootDir}/components/CustomButton.brs`, + dest: s`components/CustomButton.brs` + }]); + }); + + it('correctly assumes file path if not given', async () => { + fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); + expect( + await rokuDeploy.getFilePaths([ + { src: 'components/*' } + ], rootDir) + ).to.eql([{ + src: s`${rootDir}/components/CustomButton.brs`, + dest: s`components/CustomButton.brs` + }, { + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }]); + }); }); describe('computeFileDestPath', () => { diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 37762ce..f3cd8d3 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -329,7 +329,9 @@ export class RokuDeploy { //`pattern` is some other glob magic } else { const fileNameAndExtension = path.basename(srcPath); - result = util.standardizePath(`${entry.dest ?? ''}/${fileNameAndExtension}`); + const foundFilePath = util.standardizePath(`${entry.dest ?? ''}/${fileNameAndExtension}`); + const assumedFilePath = util.stringReplaceInsensitive(srcPath, rootDir, ''); + result = entry.dest ? foundFilePath : assumedFilePath; } result = util.standardizePath( From 2ba8ecae845401c533bb79006373dc7dc32cf8f0 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 2 Jan 2024 14:30:01 -0500 Subject: [PATCH 02/93] Sort files --- src/RokuDeploy.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 9aaff30..76d751a 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3275,18 +3275,18 @@ describe('index', () => { it('correctly assumes file path if not given', async () => { fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); expect( - await rokuDeploy.getFilePaths([ + (await rokuDeploy.getFilePaths([ { src: 'components/*' } - ], rootDir) + ], rootDir)).sort((a, b) => a.src.localeCompare(b.src)) ).to.eql([{ - src: s`${rootDir}/components/CustomButton.brs`, - dest: s`components/CustomButton.brs` - }, { src: s`${rootDir}/components/component1.brs`, dest: s`components/component1.brs` }, { src: s`${rootDir}/components/component1.xml`, dest: s`components/component1.xml` + }, { + src: s`${rootDir}/components/CustomButton.brs`, + dest: s`components/CustomButton.brs` }]); }); }); From cc92e04ca11b2815b4d8b0cb5be8c273b3734e5b Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 16 Jan 2024 10:48:26 -0500 Subject: [PATCH 03/93] Update src/RokuDeploy.ts Co-authored-by: Bronley Plumb --- src/RokuDeploy.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index f3cd8d3..d6d0fc8 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -329,9 +329,11 @@ export class RokuDeploy { //`pattern` is some other glob magic } else { const fileNameAndExtension = path.basename(srcPath); - const foundFilePath = util.standardizePath(`${entry.dest ?? ''}/${fileNameAndExtension}`); - const assumedFilePath = util.stringReplaceInsensitive(srcPath, rootDir, ''); - result = entry.dest ? foundFilePath : assumedFilePath; + if (entry.dest) { + result = util.standardizePath(`${entry.dest ?? ''}/${fileNameAndExtension}`); + } else { + result = util.stringReplaceInsensitive(srcPath, rootDir, ''); + } } result = util.standardizePath( From 9bbd579ffa13777f8f36ecba0d80b7c040a2049f Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 17 Jan 2024 13:30:18 -0500 Subject: [PATCH 04/93] Removed redundant entry.dest is null situation --- src/RokuDeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index d6d0fc8..e7a0462 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -330,7 +330,7 @@ export class RokuDeploy { } else { const fileNameAndExtension = path.basename(srcPath); if (entry.dest) { - result = util.standardizePath(`${entry.dest ?? ''}/${fileNameAndExtension}`); + result = util.standardizePath(`${entry.dest}/${fileNameAndExtension}`); } else { result = util.stringReplaceInsensitive(srcPath, rootDir, ''); } From 460cbf673b37f344825a34dc9d70f8f9eae57a9f Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Fri, 19 Jan 2024 15:02:47 -0500 Subject: [PATCH 05/93] Added a few commands, not all are working correctly --- src/RokuDeploy.ts | 2 +- src/cli.ts | 173 ++++++++++++++++++++++++++++++++++++++++++++-- src/index.ts | 2 + tsconfig.json | 2 +- 4 files changed, 172 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/cli.ts diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index f3cd8d3..c7ed29d 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -957,7 +957,7 @@ export class RokuDeploy { * Centralizes getting output zip file path based on passed in options * @param options */ - public getOutputZipFilePath(options: GetOutputZipFilePathOptions) { + public getOutputZipFilePath(options?: GetOutputZipFilePathOptions) { options = this.getOptions(options) as any; let zipFileName = options.outFile; diff --git a/src/cli.ts b/src/cli.ts old mode 100644 new mode 100755 index 063f5fd..5675926 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,7 +1,170 @@ #!/usr/bin/env node -import { deploy } from './index'; -deploy().then((...args) => { - console.log(...args); -}, (...args) => { - console.error(...args); +import * as yargs from 'yargs'; +import { stagingDir } from './testUtils.spec'; +import { prepublishToStaging, zipPackage, createPackage, publish, getOutputZipFilePath, getOutputPkgFilePath, getDeviceInfo, getDevId, zipFolder } from './index'; +const outDir = './out'; + +new Promise((resolve, reject) => { + // TODO: is this necessary?vv + // eslint-disable-next-line + yargs + .command('prepublishToStaging', 'Copies all of the referenced files to the staging folder', (builder) => { + return builder + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: true }) + .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: true }); + }, (args: any) => { + console.log('prepublishToStaging'); + prepublishToStaging({ + files: [ + 'manifest' + ], + stagingDir: args.stagingDir, + rootDir: args.rootDir + }).then(() => { + console.error('SUCCESS'); + }, (error) => { + console.error('ERROR', error, '\n', args); + }); + // TODO: Should we have defaults for these^^ + // TODO: This doesn't work + }) + + .command('zipPackage', 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { + return builder + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', default: outDir, demandOption: false }); + }, (args: any) => { + console.log('zipPackage'); + zipPackage({ + stagingDir: stagingDir, + outDir: args.outDir + }).then(() => { + console.error('SUCCESS'); + }, (error) => { + console.error('ERROR', error, '\n', args); + }); + // TODO: Missing manifest file + }) + + .command('createPackage', 'Create a zip folder containing all of the specified roku project files', (builder) => { + return builder + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) + .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', default: outDir, demandOption: false }); + }, (args: any) => { + console.log('createPackage'); + createPackage({ + files: [ + 'manifest' + ], + stagingDir: '.tmp/dist', + outDir: args.outDir, + rootDir: './src' + }).then(() => { + console.error('SUCCESS'); + }, (error) => { + console.error('ERROR', error, '\n', args); + }); + // TODO: Missing manifest file + }) + + .command('publish', 'Publish a pre-existing packaged zip file to a remote Roku', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: true }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: true }) + .option('outDir', { type: 'string', description: 'The output directory', default: outDir, demandOption: false }) + .option('outFile', { type: 'string', description: 'The output file', default: 'roku-deploy', demandOption: false }); + }, (args: any) => { + console.log('publish'); + publish({ + host: args.host, + password: args.password, + outDir: args.outDir, + outFile: args.outFile + }).then(() => { + console.error('SUCCESS'); + }, (error) => { + console.error('ERROR', error, '\n', args); + }); + // TODO: Times out + }) + + // TODO: + // convertToSquashfs + // rekeyDevice + // signExistingPackage + // retrieveSignedPackage + // deploy + // deleteInstalledChannel + // takeScreenshot + // deployAndSignPackage - TODO: does the same thing as deploy but also signs package...is it necessary? + + .command('getOutputZipFilePath', 'Centralizes getting output zip file path based on passed in options', (builder) => { + // EXAMPLE: npx roku-deploy getOutputZipFilePath + return builder; + }, (args: any) => { + console.log('getOutputZipFilePath'); + console.log(getOutputZipFilePath({})); + }) + + .command('getOutputPkgFilePath', 'Centralizes getting output pkg file path based on passed in options', (builder) => { + // EXAMPLE: npx roku-deploy getOutputPkgFilePath + return builder; + }, (args: any) => { + console.log('getOutputPkgFilePath'); + let result = getOutputPkgFilePath({}); + console.log(result); + }) + + .command('getDeviceInfo', 'Get the `device-info` response from a Roku device', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: true }); + }, (args: any) => { + console.log('getDeviceInfo'); + let result = getDeviceInfo({ + host: args.host + }).then(() => { + console.error('SUCCESS', result); + }, (error) => { + console.error('ERROR', error, '\n', args); + }); + // TODO: returns pending promise? + }) + + .command('getDevId', 'Get Dev ID', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: true }); + }, (args: any) => { + console.log('getDevId'); + let result = getDevId({ + host: args.host + }).then(() => { + console.error('SUCCESS', result); + }, (error) => { + console.error('ERROR', error, '\n', args); + }); + // TODO: returns pending promise? + }) + + .command('zipFolder', 'Given a path to a folder, zip up that folder and all of its contents', (builder) => { + // EXAMPLE: npx roku-deploy zipFolder --srcFolder ./src --zipFilePath ./output.zip + return builder + .option('srcFolder', { type: 'string', description: 'The folder that should be zipped', demandOption: true }) + .option('zipFilePath', { type: 'string', description: 'The path to the zip that will be created. Must be .zip file name', demandOption: true }); + }, (args: any) => { + console.log('zipFolder'); + zipFolder( + args.srcFolder, + args.zipFilePath + ).then(() => { + console.error('SUCCESS'); + }, (error) => { + console.error('ERROR', error, '\n', args); + }); + }) + + .argv; +}).catch((e) => { + console.error(e); + process.exit(1); }); diff --git a/src/index.ts b/src/index.ts index dff33ac..d68b4d5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,6 +31,7 @@ let retrieveSignedPackage = RokuDeploy.prototype.retrieveSignedPackage.bind(roku let signExistingPackage = RokuDeploy.prototype.signExistingPackage.bind(rokuDeploy); let stringifyManifest = RokuDeploy.prototype.stringifyManifest.bind(rokuDeploy); let takeScreenshot = RokuDeploy.prototype.takeScreenshot.bind(rokuDeploy); +let getDevId = RokuDeploy.prototype.getDevId.bind(rokuDeploy); let zipFolder = RokuDeploy.prototype.zipFolder.bind(rokuDeploy); let zipPackage = RokuDeploy.prototype.zipPackage.bind(rokuDeploy); @@ -56,6 +57,7 @@ export { signExistingPackage, stringifyManifest, takeScreenshot, + getDevId, zipFolder, zipPackage }; diff --git a/tsconfig.json b/tsconfig.json index 381ba26..5d1cd50 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,7 @@ "include": [ "src/**/*.ts", "device.spec.ts" - ], +, "src/cli.ts" ], "ts-node": { "transpileOnly": true } From 6db962aceaf19ea48d46a7f12d4478bdb170c48a Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 31 Jan 2024 13:37:39 -0500 Subject: [PATCH 06/93] Move commands to their own file --- src/commands/ConvertToSquashfsCommand.ts | 10 ++++++++++ src/commands/CreatePackageCommand.ts | 11 +++++++++++ src/commands/DeleteInstalledChannelCommand.ts | 10 ++++++++++ src/commands/DeployCommand.ts | 11 +++++++++++ src/commands/PrepublishCommand.ts | 10 ++++++++++ src/commands/PublishCommand.ts | 12 ++++++++++++ src/commands/RekeyDeviceCommand.ts | 14 ++++++++++++++ src/commands/RetrieveSignedPackageCommand.ts | 11 +++++++++++ src/commands/SignExistingPackageCommand.ts | 12 ++++++++++++ src/commands/TakeScreenshotCommand.ts | 10 ++++++++++ src/commands/ZipPackageCommand.ts | 10 ++++++++++ 11 files changed, 121 insertions(+) create mode 100644 src/commands/ConvertToSquashfsCommand.ts create mode 100644 src/commands/CreatePackageCommand.ts create mode 100644 src/commands/DeleteInstalledChannelCommand.ts create mode 100644 src/commands/DeployCommand.ts create mode 100644 src/commands/PrepublishCommand.ts create mode 100644 src/commands/PublishCommand.ts create mode 100644 src/commands/RekeyDeviceCommand.ts create mode 100644 src/commands/RetrieveSignedPackageCommand.ts create mode 100644 src/commands/SignExistingPackageCommand.ts create mode 100644 src/commands/TakeScreenshotCommand.ts create mode 100644 src/commands/ZipPackageCommand.ts diff --git a/src/commands/ConvertToSquashfsCommand.ts b/src/commands/ConvertToSquashfsCommand.ts new file mode 100644 index 0000000..b1e1e7b --- /dev/null +++ b/src/commands/ConvertToSquashfsCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class ConvertToSquashfsCommand { + async run(args) { + await rokuDeploy.convertToSquashfs({ + host: args.host, + password: args.password + }); + } +} diff --git a/src/commands/CreatePackageCommand.ts b/src/commands/CreatePackageCommand.ts new file mode 100644 index 0000000..f4b4718 --- /dev/null +++ b/src/commands/CreatePackageCommand.ts @@ -0,0 +1,11 @@ +import { rokuDeploy } from '../index'; + +export class CreatePackageCommand { + async run(args) { + await rokuDeploy.createPackage({ + stagingDir: args.stagingDir, + outDir: args.outDir, + rootDir: args.rootDir + }); + } +} diff --git a/src/commands/DeleteInstalledChannelCommand.ts b/src/commands/DeleteInstalledChannelCommand.ts new file mode 100644 index 0000000..1ec9c29 --- /dev/null +++ b/src/commands/DeleteInstalledChannelCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class DeleteInstalledChannelCommand { + async run(args) { + await rokuDeploy.deleteInstalledChannel({ + host: args.host, + password: args.password + }); + } +} diff --git a/src/commands/DeployCommand.ts b/src/commands/DeployCommand.ts new file mode 100644 index 0000000..5947deb --- /dev/null +++ b/src/commands/DeployCommand.ts @@ -0,0 +1,11 @@ +import { rokuDeploy } from '../index'; + +export class DeployCommand { + async run(args) { + await rokuDeploy.deploy({ + host: args.host, + password: args.password, + rootDir: args.rootDir + }); + } +} diff --git a/src/commands/PrepublishCommand.ts b/src/commands/PrepublishCommand.ts new file mode 100644 index 0000000..2ca65cc --- /dev/null +++ b/src/commands/PrepublishCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class PrepublishCommand { + async run(args) { + await rokuDeploy.prepublishToStaging({ + stagingDir: args.stagingDir, + rootDir: args.rootDir + }); + } +} diff --git a/src/commands/PublishCommand.ts b/src/commands/PublishCommand.ts new file mode 100644 index 0000000..91554fa --- /dev/null +++ b/src/commands/PublishCommand.ts @@ -0,0 +1,12 @@ +import { rokuDeploy } from '../index'; + +export class PublishCommand { + async run(args) { + await rokuDeploy.publish({ + host: args.host, + password: args.password, + outDir: args.outDir, + outFile: args.outFile + }); + } +} \ No newline at end of file diff --git a/src/commands/RekeyDeviceCommand.ts b/src/commands/RekeyDeviceCommand.ts new file mode 100644 index 0000000..7098772 --- /dev/null +++ b/src/commands/RekeyDeviceCommand.ts @@ -0,0 +1,14 @@ +import { rokuDeploy } from '../index'; + +export class RekeyDeviceCommand { + async run(args) { + await rokuDeploy.rekeyDevice({ + host: args.host, + password: args.password, + rekeySignedPackage: args.rekeySignedPackage, + signingPassword: args.signingPassword, + rootDir: args.rootDir, + devId: args.devId + }); + } +} diff --git a/src/commands/RetrieveSignedPackageCommand.ts b/src/commands/RetrieveSignedPackageCommand.ts new file mode 100644 index 0000000..cfecba6 --- /dev/null +++ b/src/commands/RetrieveSignedPackageCommand.ts @@ -0,0 +1,11 @@ +import { rokuDeploy } from '../index'; + +export class RetrieveSignedPackageCommand { + async run(args) { + await rokuDeploy.retrieveSignedPackage('path_to_pkg', { + host: args.host, + password: args.password, + outFile: args.outFile + }); + } +} diff --git a/src/commands/SignExistingPackageCommand.ts b/src/commands/SignExistingPackageCommand.ts new file mode 100644 index 0000000..2d5733f --- /dev/null +++ b/src/commands/SignExistingPackageCommand.ts @@ -0,0 +1,12 @@ +import { rokuDeploy } from '../index'; + +export class SignExistingPackageCommand { + async run(args) { + await rokuDeploy.signExistingPackage({ + host: args.host, + password: args.password, + signingPassword: args.signingPassword, + stagingDir: args.stagingDir + }); + } +} diff --git a/src/commands/TakeScreenshotCommand.ts b/src/commands/TakeScreenshotCommand.ts new file mode 100644 index 0000000..ac5b7bc --- /dev/null +++ b/src/commands/TakeScreenshotCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class TakeScreenshotCommand { + async run(args) { + await rokuDeploy.takeScreenshot({ + host: args.host, + password: args.password + }); + } +} diff --git a/src/commands/ZipPackageCommand.ts b/src/commands/ZipPackageCommand.ts new file mode 100644 index 0000000..7ef1f09 --- /dev/null +++ b/src/commands/ZipPackageCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class ZipPackageCommand { + async run(args) { + await rokuDeploy.zipPackage({ + stagingDir: args.stagingDir, + outDir: args.outDir + }); + } +} From 20eb21f133ea9f5f307a08efa089340f6c93b14b Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 1 Feb 2024 00:30:59 -0500 Subject: [PATCH 07/93] More command files --- src/commands/GetDevIdCommand.ts | 9 +++++++++ src/commands/GetDeviceInfoCommand.ts | 9 +++++++++ src/commands/GetOutputPkgFilePathCommand.ts | 10 ++++++++++ src/commands/GetOutputZipFilePathCommand.ts | 10 ++++++++++ src/commands/ZipFolderCommand.ts | 10 ++++++++++ 5 files changed, 48 insertions(+) create mode 100644 src/commands/GetDevIdCommand.ts create mode 100644 src/commands/GetDeviceInfoCommand.ts create mode 100644 src/commands/GetOutputPkgFilePathCommand.ts create mode 100644 src/commands/GetOutputZipFilePathCommand.ts create mode 100644 src/commands/ZipFolderCommand.ts diff --git a/src/commands/GetDevIdCommand.ts b/src/commands/GetDevIdCommand.ts new file mode 100644 index 0000000..72ccde8 --- /dev/null +++ b/src/commands/GetDevIdCommand.ts @@ -0,0 +1,9 @@ +import { rokuDeploy } from '../index'; + +export class GetDevIdCommand { + async run(args) { + await rokuDeploy.getDevId({ + host: args.host + }); + } +} diff --git a/src/commands/GetDeviceInfoCommand.ts b/src/commands/GetDeviceInfoCommand.ts new file mode 100644 index 0000000..42e6580 --- /dev/null +++ b/src/commands/GetDeviceInfoCommand.ts @@ -0,0 +1,9 @@ +import { rokuDeploy } from '../index'; + +export class GetDeviceInfoCommand { + async run(args) { + await rokuDeploy.getDeviceInfo({ + host: args.host + }); + } +} diff --git a/src/commands/GetOutputPkgFilePathCommand.ts b/src/commands/GetOutputPkgFilePathCommand.ts new file mode 100644 index 0000000..cfa9450 --- /dev/null +++ b/src/commands/GetOutputPkgFilePathCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class GetOutputPkgFilePathCommand { + run(args) { + rokuDeploy.getOutputPkgFilePath({ + outFile: args.outFile, + outDir: args.outDir + }); + } +} diff --git a/src/commands/GetOutputZipFilePathCommand.ts b/src/commands/GetOutputZipFilePathCommand.ts new file mode 100644 index 0000000..a8f697f --- /dev/null +++ b/src/commands/GetOutputZipFilePathCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class GetOutputZipFilePathCommand { + run(args) { + rokuDeploy.getOutputZipFilePath({ + outFile: args.outFile, + outDir: args.outDir + }); + } +} diff --git a/src/commands/ZipFolderCommand.ts b/src/commands/ZipFolderCommand.ts new file mode 100644 index 0000000..edf9078 --- /dev/null +++ b/src/commands/ZipFolderCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class ZipFolderCommand { + async run(args) { + await rokuDeploy.zipFolder( + args.srcFolder, + args.zipFilePath + ); + } +} From 4e4b66a9a5ec1977c06e1fe85df7698650b4d8aa Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 1 Feb 2024 18:59:39 -0500 Subject: [PATCH 08/93] Change commands to help with tests --- src/commands/GetDeviceInfoCommand.ts | 3 ++- src/commands/GetOutputPkgFilePathCommand.ts | 3 ++- src/commands/GetOutputZipFilePathCommand.ts | 3 ++- src/commands/RetrieveSignedPackageCommand.ts | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/commands/GetDeviceInfoCommand.ts b/src/commands/GetDeviceInfoCommand.ts index 42e6580..0670849 100644 --- a/src/commands/GetDeviceInfoCommand.ts +++ b/src/commands/GetDeviceInfoCommand.ts @@ -2,8 +2,9 @@ import { rokuDeploy } from '../index'; export class GetDeviceInfoCommand { async run(args) { - await rokuDeploy.getDeviceInfo({ + const outputPath = await rokuDeploy.getDeviceInfo({ host: args.host }); + console.log(JSON.stringify(outputPath)); } } diff --git a/src/commands/GetOutputPkgFilePathCommand.ts b/src/commands/GetOutputPkgFilePathCommand.ts index cfa9450..78fff13 100644 --- a/src/commands/GetOutputPkgFilePathCommand.ts +++ b/src/commands/GetOutputPkgFilePathCommand.ts @@ -2,9 +2,10 @@ import { rokuDeploy } from '../index'; export class GetOutputPkgFilePathCommand { run(args) { - rokuDeploy.getOutputPkgFilePath({ + const outputPath = rokuDeploy.getOutputPkgFilePath({ outFile: args.outFile, outDir: args.outDir }); + console.log(outputPath); } } diff --git a/src/commands/GetOutputZipFilePathCommand.ts b/src/commands/GetOutputZipFilePathCommand.ts index a8f697f..5525057 100644 --- a/src/commands/GetOutputZipFilePathCommand.ts +++ b/src/commands/GetOutputZipFilePathCommand.ts @@ -2,9 +2,10 @@ import { rokuDeploy } from '../index'; export class GetOutputZipFilePathCommand { run(args) { - rokuDeploy.getOutputZipFilePath({ + const outputPath = rokuDeploy.getOutputZipFilePath({ outFile: args.outFile, outDir: args.outDir }); + console.log(outputPath); } } diff --git a/src/commands/RetrieveSignedPackageCommand.ts b/src/commands/RetrieveSignedPackageCommand.ts index cfecba6..411dfd9 100644 --- a/src/commands/RetrieveSignedPackageCommand.ts +++ b/src/commands/RetrieveSignedPackageCommand.ts @@ -2,7 +2,7 @@ import { rokuDeploy } from '../index'; export class RetrieveSignedPackageCommand { async run(args) { - await rokuDeploy.retrieveSignedPackage('path_to_pkg', { + await rokuDeploy.retrieveSignedPackage(args.pathToPkg, { host: args.host, password: args.password, outFile: args.outFile From 2b809e6886ad0c720eb9a2f81de63a1ff67b87d2 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 1 Feb 2024 19:00:49 -0500 Subject: [PATCH 09/93] Add testing suite for all cli (2 tests are not working) --- src/cli.spec.ts | 324 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 src/cli.spec.ts diff --git a/src/cli.spec.ts b/src/cli.spec.ts new file mode 100644 index 0000000..7bddc32 --- /dev/null +++ b/src/cli.spec.ts @@ -0,0 +1,324 @@ +import * as childProcess from 'child_process'; +import { cwd, expectPathExists, rootDir, stagingDir, tempDir, outDir } from './testUtils.spec'; +import * as fsExtra from 'fs-extra'; +import { expect } from 'chai'; +import * as path from 'path'; +import { createSandbox } from 'sinon'; +import { rokuDeploy } from './index'; +import { PublishCommand } from './commands/PublishCommand'; +import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; +import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; +import { SignExistingPackageCommand } from './commands/SignExistingPackageCommand'; +import { DeployCommand } from './commands/DeployCommand'; +import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannelCommand'; +import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; +import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; +import { GetDevIdCommand } from './commands/GetDevIdCommand'; +import { RetrieveSignedPackageCommand } from './commands/RetrieveSignedPackageCommand'; + +const sinon = createSandbox(); + +function execSync(command: string) { + const output = childProcess.execSync(command, { cwd: tempDir }); + process.stdout.write(output); + return output; + // return childProcess.execSync(command, { stdio: 'inherit', cwd: tempDir }); +} +describe('cli', () => { + before(function build() { + this.timeout(20000); + execSync('npm run build'); + }); + beforeEach(() => { + fsExtra.emptyDirSync(tempDir); + //most tests depend on a manifest file existing, so write an empty one + fsExtra.outputFileSync(`${rootDir}/manifest`, ''); + }); + afterEach(() => { + fsExtra.removeSync(tempDir); + }); + + it('Successfully runs prepublishToStaging', () => { + //make the files + // fsExtra.outputFileSync(`${rootDir}/manifest`, ''); + fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); + + expect(() => { + execSync(`node ${cwd}/dist/cli.js prepublishToStaging --stagingDir ${stagingDir} --rootDir ${rootDir}`); + }).to.not.throw(); + }); + + it('Successfully copies rootDir folder to staging folder', () => { + fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); + + execSync(`node ${cwd}/dist/cli.js prepublishToStaging --rootDir ${rootDir} --stagingDir ${stagingDir}`); + + expectPathExists(`${stagingDir}/source/main.brs`); + }); + + it('Successfully uses zipPackage to create .zip', () => { + fsExtra.outputFileSync(`${stagingDir}/manifest`, ''); + + execSync(`node ${cwd}/dist/cli.js zipPackage --stagingDir ${stagingDir} --outDir ${outDir}`); + expectPathExists(`${outDir}/roku-deploy.zip`); + }); + + it('Successfully uses createPackage to create .pkg', () => { + execSync(`node ${cwd}/dist/cli.js createPackage --stagingDir ${stagingDir} --rootDir ${rootDir} --outDir ${outDir}`); + expectPathExists(`${outDir}/roku-deploy.zip`); + }); + + it('Publish passes proper options', async () => { + const stub = sinon.stub(rokuDeploy, 'publish').callsFake(async () => { + return Promise.resolve({ + message: 'Publish successful', + results: {} + }); + }); + + const command = new PublishCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536', + outDir: outDir, + outFile: 'rokudeploy-outfile' + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4', + password: '5536', + outDir: outDir, + outFile: 'rokudeploy-outfile' + }); + }); + + it('Converts to squashfs', async () => { + const stub = sinon.stub(rokuDeploy, 'convertToSquashfs').callsFake(async () => { + return Promise.resolve(); + }); + + const command = new ConvertToSquashfsCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536' + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4', + password: '5536' + }); + }); + + it('Rekeys a device', async () => { + const stub = sinon.stub(rokuDeploy, 'rekeyDevice').callsFake(async () => { + return Promise.resolve(); + }); + + const command = new RekeyDeviceCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536', + rekeySignedPackage: `${tempDir}/testSignedPackage.pkg`, + signingPassword: '12345', + rootDir: rootDir, + devId: 'abcde' + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4', + password: '5536', + rekeySignedPackage: `${tempDir}/testSignedPackage.pkg`, + signingPassword: '12345', + rootDir: rootDir, + devId: 'abcde' + }); + }); + + it('Signs an existing package', async () => { + const stub = sinon.stub(rokuDeploy, 'signExistingPackage').callsFake(async () => { + return Promise.resolve(''); + }); + + const command = new SignExistingPackageCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536', + signingPassword: undefined, + stagingDir: stagingDir + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4', + password: '5536', + signingPassword: undefined, + stagingDir: stagingDir + }); + }); + + it('Retrieves a signed package', async () => { + const stub = sinon.stub(rokuDeploy, 'retrieveSignedPackage').callsFake(async () => { + return Promise.resolve(''); + }); + + const command = new RetrieveSignedPackageCommand(); + await command.run({ + pathToPkg: 'path_to_pkg', + host: '1.2.3.4', + password: '5536', + outFile: 'roku-deploy-test' + }); + console.log(stub.getCall(0).args[0]); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + pathToPkg: 'path_to_pkg', + host: '1.2.3.4', + password: '5536', + outFile: 'roku-deploy-test' + });//TODO: fix! + }); + + it('Deploys a package', async () => { + const stub = sinon.stub(rokuDeploy, 'deploy').callsFake(async () => { + return Promise.resolve({ + message: 'Convert successful', + results: {} + }); + }); + + const command = new DeployCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536', + rootDir: rootDir + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4', + password: '5536', + rootDir: rootDir + }); + }); + + it('Deletes an installed channel', async () => { + const stub = sinon.stub(rokuDeploy, 'deleteInstalledChannel').callsFake(async () => { + return Promise.resolve({ response: {}, body: {} }); + }); + + const command = new DeleteInstalledChannelCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536' + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4', + password: '5536' + }); + }); + + it('Takes a screenshot', async () => { + const stub = sinon.stub(rokuDeploy, 'takeScreenshot').callsFake(async () => { + return Promise.resolve(''); + }); + + const command = new TakeScreenshotCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536' + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4', + password: '5536' + }); + }); + + it('Gets output zip file path', () => { + let zipFilePath = execSync(`node ${cwd}/dist/cli.js getOutputZipFilePath --outFile "roku-deploy" --outDir ${outDir}`).toString(); + + expect(zipFilePath.trim()).to.equal(path.join(path.resolve(outDir), 'roku-deploy.zip')); + }); + + it('Gets output pkg file path', () => { + let pkgFilePath = execSync(`node ${cwd}/dist/cli.js getOutputPkgFilePath --outFile "roku-deploy" --outDir ${outDir}`).toString(); + + expect(pkgFilePath.trim()).to.equal(path.join(path.resolve(outDir), 'roku-deploy.pkg')); + }); + + it('Device info arguments are correct', async () => { + const stub = sinon.stub(rokuDeploy, 'getDeviceInfo').callsFake(async () => { + return Promise.resolve({ + response: {}, + body: {} + }); + }); + + const command = new GetDeviceInfoCommand(); + await command.run({ + host: '1.2.3.4' + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4' + }); + }); + + it('Prints device info to console', async () => { + let consoleOutput = ''; + sinon.stub(console, 'log').callsFake((...args) => { + consoleOutput += args.join(' ') + '\n'; //TODO: I don't think this is accurately adding a new line + }); + sinon.stub(rokuDeploy, 'getDeviceInfo').returns(Promise.resolve({ + 'device-id': '1234', + 'serial-number': 'abcd' + })); + await new GetDeviceInfoCommand().run({ + host: '1.2.3.4' + }); + expect(consoleOutput.trim()).to.eql( + '{"device-id":"1234","serial-number":"abcd"}' + ); + }); //TODO: This passes when it is it.only, but fails in the larger test suite? + + it('Gets dev id', async () => { + const stub = sinon.stub(rokuDeploy, 'getDevId').callsFake(async () => { + return Promise.resolve(''); + }); + + const command = new GetDevIdCommand(); + await command.run({ + host: '1.2.3.4', + password: '5536' + }); + + expect( + stub.getCall(0).args[0] + ).to.eql({ + host: '1.2.3.4' + }); + }); + + it('Zips a folder', () => { + execSync(`node ${cwd}/dist/cli.js zipFolder --srcFolder ${rootDir} --zipFilePath "roku-deploy.zip"`); + + expectPathExists(`${tempDir}/roku-deploy.zip`); + }); +}); From 13f2ca4f6c011b51569d45158cf4ceb50b43fefb Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 1 Feb 2024 19:02:02 -0500 Subject: [PATCH 10/93] Updated cli file after adding in commands and tests --- src/cli.ts | 326 ++++++++++++++++++++++++++--------------------------- 1 file changed, 158 insertions(+), 168 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 5675926..002551f 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,170 +1,160 @@ #!/usr/bin/env node import * as yargs from 'yargs'; -import { stagingDir } from './testUtils.spec'; -import { prepublishToStaging, zipPackage, createPackage, publish, getOutputZipFilePath, getOutputPkgFilePath, getDeviceInfo, getDevId, zipFolder } from './index'; -const outDir = './out'; - -new Promise((resolve, reject) => { - // TODO: is this necessary?vv - // eslint-disable-next-line - yargs - .command('prepublishToStaging', 'Copies all of the referenced files to the staging folder', (builder) => { - return builder - .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: true }) - .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: true }); - }, (args: any) => { - console.log('prepublishToStaging'); - prepublishToStaging({ - files: [ - 'manifest' - ], - stagingDir: args.stagingDir, - rootDir: args.rootDir - }).then(() => { - console.error('SUCCESS'); - }, (error) => { - console.error('ERROR', error, '\n', args); - }); - // TODO: Should we have defaults for these^^ - // TODO: This doesn't work - }) - - .command('zipPackage', 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { - return builder - .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', default: outDir, demandOption: false }); - }, (args: any) => { - console.log('zipPackage'); - zipPackage({ - stagingDir: stagingDir, - outDir: args.outDir - }).then(() => { - console.error('SUCCESS'); - }, (error) => { - console.error('ERROR', error, '\n', args); - }); - // TODO: Missing manifest file - }) - - .command('createPackage', 'Create a zip folder containing all of the specified roku project files', (builder) => { - return builder - .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) - .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', default: outDir, demandOption: false }); - }, (args: any) => { - console.log('createPackage'); - createPackage({ - files: [ - 'manifest' - ], - stagingDir: '.tmp/dist', - outDir: args.outDir, - rootDir: './src' - }).then(() => { - console.error('SUCCESS'); - }, (error) => { - console.error('ERROR', error, '\n', args); - }); - // TODO: Missing manifest file - }) - - .command('publish', 'Publish a pre-existing packaged zip file to a remote Roku', (builder) => { - return builder - .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: true }) - .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: true }) - .option('outDir', { type: 'string', description: 'The output directory', default: outDir, demandOption: false }) - .option('outFile', { type: 'string', description: 'The output file', default: 'roku-deploy', demandOption: false }); - }, (args: any) => { - console.log('publish'); - publish({ - host: args.host, - password: args.password, - outDir: args.outDir, - outFile: args.outFile - }).then(() => { - console.error('SUCCESS'); - }, (error) => { - console.error('ERROR', error, '\n', args); - }); - // TODO: Times out - }) - - // TODO: - // convertToSquashfs - // rekeyDevice - // signExistingPackage - // retrieveSignedPackage - // deploy - // deleteInstalledChannel - // takeScreenshot - // deployAndSignPackage - TODO: does the same thing as deploy but also signs package...is it necessary? - - .command('getOutputZipFilePath', 'Centralizes getting output zip file path based on passed in options', (builder) => { - // EXAMPLE: npx roku-deploy getOutputZipFilePath - return builder; - }, (args: any) => { - console.log('getOutputZipFilePath'); - console.log(getOutputZipFilePath({})); - }) - - .command('getOutputPkgFilePath', 'Centralizes getting output pkg file path based on passed in options', (builder) => { - // EXAMPLE: npx roku-deploy getOutputPkgFilePath - return builder; - }, (args: any) => { - console.log('getOutputPkgFilePath'); - let result = getOutputPkgFilePath({}); - console.log(result); - }) - - .command('getDeviceInfo', 'Get the `device-info` response from a Roku device', (builder) => { - return builder - .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: true }); - }, (args: any) => { - console.log('getDeviceInfo'); - let result = getDeviceInfo({ - host: args.host - }).then(() => { - console.error('SUCCESS', result); - }, (error) => { - console.error('ERROR', error, '\n', args); - }); - // TODO: returns pending promise? - }) - - .command('getDevId', 'Get Dev ID', (builder) => { - return builder - .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: true }); - }, (args: any) => { - console.log('getDevId'); - let result = getDevId({ - host: args.host - }).then(() => { - console.error('SUCCESS', result); - }, (error) => { - console.error('ERROR', error, '\n', args); - }); - // TODO: returns pending promise? - }) - - .command('zipFolder', 'Given a path to a folder, zip up that folder and all of its contents', (builder) => { - // EXAMPLE: npx roku-deploy zipFolder --srcFolder ./src --zipFilePath ./output.zip - return builder - .option('srcFolder', { type: 'string', description: 'The folder that should be zipped', demandOption: true }) - .option('zipFilePath', { type: 'string', description: 'The path to the zip that will be created. Must be .zip file name', demandOption: true }); - }, (args: any) => { - console.log('zipFolder'); - zipFolder( - args.srcFolder, - args.zipFilePath - ).then(() => { - console.error('SUCCESS'); - }, (error) => { - console.error('ERROR', error, '\n', args); - }); - }) - - .argv; -}).catch((e) => { - console.error(e); - process.exit(1); -}); +import { PrepublishCommand } from './commands/PrepublishCommand'; +import { ZipPackageCommand } from './commands/ZipPackageCommand'; +import { CreatePackageCommand } from './commands/CreatePackageCommand'; +import { PublishCommand } from './commands/PublishCommand'; +import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; +import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; +import { SignExistingPackageCommand } from './commands/SignExistingPackageCommand'; +import { RetrieveSignedPackageCommand } from './commands/RetrieveSignedPackageCommand'; +import { DeployCommand } from './commands/DeployCommand'; +import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannelCommand'; +import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; +import { GetOutputZipFilePathCommand } from './commands/GetOutputZipFilePathCommand'; +import { GetOutputPkgFilePathCommand } from './commands/GetOutputPkgFilePathCommand'; +import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; +import { GetDevIdCommand } from './commands/GetDevIdCommand'; +import { ZipFolderCommand } from './commands/ZipFolderCommand'; + +void yargs + .command('prepublishToStaging', 'Copies all of the referenced files to the staging folder', (builder) => { + return builder + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) + .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }); + }, (args: any) => { + return new PrepublishCommand().run(args); + }) + + .command('zipPackage', 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { + return builder + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); + }, (args: any) => { + return new ZipPackageCommand().run(args); + }) + + .command('createPackage', 'Create a zip folder containing all of the specified roku project files', (builder) => { + return builder + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) + .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); + }, (args: any) => { + return new CreatePackageCommand().run(args); + }) + + .command('publish', 'Publish a pre-existing packaged zip file to a remote Roku', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }); + }, (args: any) => { + return new PublishCommand().run(args); + }) + + .command('convertToSquashfs', 'Convert a pre-existing packaged zip file to a squashfs file', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); + }, (args: any) => { + return new ConvertToSquashfsCommand().run(args); + }) + + .command('rekeyDevice', 'Rekey a device', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('rekeySignedPackage', { type: 'string', description: 'The signed package to be used for rekeying', demandOption: false }) + .option('signingPassword', { type: 'string', description: 'The password of the signing key', demandOption: false }) + .option('rootDir', { type: 'string', description: 'The root directory', demandOption: false }) + .option('devId', { type: 'string', description: 'The dev ID', demandOption: false }); + }, (args: any) => { + return new RekeyDeviceCommand().run(args); + }) + + .command('signExistingPackage', 'Sign a package', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('signingPassword', { type: 'string', description: 'The password of the signing key', demandOption: false }) + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }); + }, (args: any) => { + return new SignExistingPackageCommand().run(args); + }) + + .command('retrieveSignedPackage', 'Retrieve a signed package', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }); + }, (args: any) => { + return new RetrieveSignedPackageCommand().run(args); + }) + + .command('deploy', 'Deploy a pre-existing packaged zip file to a remote Roku', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('rootDir', { type: 'string', description: 'The root directory', demandOption: false }); + }, (args: any) => { + return new DeployCommand().run(args); + }) + + .command('deleteInstalledChannel', 'Delete an installed channel', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); + }, (args: any) => { + return new DeleteInstalledChannelCommand().run(args); + }) + + .command('takeScreenshot', 'Take a screenshot', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); + }, (args: any) => { + return new TakeScreenshotCommand().run(args); + }) + + .command('getOutputZipFilePath', 'Centralizes getting output zip file path based on passed in options', (builder) => { + return builder + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); + return builder; + }, (args: any) => { + return new GetOutputZipFilePathCommand().run(args); + }) + + .command('getOutputPkgFilePath', 'Centralizes getting output pkg file path based on passed in options', (builder) => { + return builder + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); + }, (args: any) => { + return new GetOutputPkgFilePathCommand().run(args); + }) + + .command('getDeviceInfo', 'Get the `device-info` response from a Roku device', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }); + }, (args: any) => { + return new GetDeviceInfoCommand().run(args); + }) + + .command('getDevId', 'Get Dev ID', (builder) => { + return builder + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }); + }, (args: any) => { + return new GetDevIdCommand().run(args); + }) + + .command('zipFolder', 'Given a path to a folder, zip up that folder and all of its contents', (builder) => { + return builder + .option('srcFolder', { type: 'string', description: 'The folder that should be zipped', demandOption: false }) + .option('zipFilePath', { type: 'string', description: 'The path to the zip that will be created. Must be .zip file name', demandOption: false }); + }, (args: any) => { + console.log('args', args); + return new ZipFolderCommand().run(args); + }) + + .argv; From 2d134412f4a7a8119a383f8b5990e41c7dae6159 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Fri, 2 Feb 2024 12:05:09 -0500 Subject: [PATCH 11/93] Fixed a few test cases --- src/cli.spec.ts | 31 +++++++++++++++++----------- src/commands/GetDeviceInfoCommand.ts | 4 ++-- src/util.ts | 14 +++++++++++++ 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 7bddc32..4cf25f3 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -22,7 +22,6 @@ function execSync(command: string) { const output = childProcess.execSync(command, { cwd: tempDir }); process.stdout.write(output); return output; - // return childProcess.execSync(command, { stdio: 'inherit', cwd: tempDir }); } describe('cli', () => { before(function build() { @@ -33,14 +32,15 @@ describe('cli', () => { fsExtra.emptyDirSync(tempDir); //most tests depend on a manifest file existing, so write an empty one fsExtra.outputFileSync(`${rootDir}/manifest`, ''); + sinon.restore(); }); afterEach(() => { fsExtra.removeSync(tempDir); + sinon.restore(); }); it('Successfully runs prepublishToStaging', () => { //make the files - // fsExtra.outputFileSync(`${rootDir}/manifest`, ''); fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); expect(() => { @@ -175,16 +175,14 @@ describe('cli', () => { password: '5536', outFile: 'roku-deploy-test' }); - console.log(stub.getCall(0).args[0]); expect( - stub.getCall(0).args[0] - ).to.eql({ - pathToPkg: 'path_to_pkg', + stub.getCall(0).args + ).to.eql(['path_to_pkg', { host: '1.2.3.4', password: '5536', outFile: 'roku-deploy-test' - });//TODO: fix! + }]); }); it('Deploys a package', async () => { @@ -284,7 +282,7 @@ describe('cli', () => { it('Prints device info to console', async () => { let consoleOutput = ''; sinon.stub(console, 'log').callsFake((...args) => { - consoleOutput += args.join(' ') + '\n'; //TODO: I don't think this is accurately adding a new line + consoleOutput += args.join(' ') + '\n'; }); sinon.stub(rokuDeploy, 'getDeviceInfo').returns(Promise.resolve({ 'device-id': '1234', @@ -293,10 +291,19 @@ describe('cli', () => { await new GetDeviceInfoCommand().run({ host: '1.2.3.4' }); - expect(consoleOutput.trim()).to.eql( - '{"device-id":"1234","serial-number":"abcd"}' - ); - }); //TODO: This passes when it is it.only, but fails in the larger test suite? + + // const consoleOutputObject: Record = { + // 'device-id': '1234', + // 'serial-number': 'abcd' + // }; + + expect(consoleOutput).to.eql([ + 'Name Value ', + '---------------------------', + 'device-id 1234 ', + 'serial-number abcd \n' + ].join('\n')); + }); it('Gets dev id', async () => { const stub = sinon.stub(rokuDeploy, 'getDevId').callsFake(async () => { diff --git a/src/commands/GetDeviceInfoCommand.ts b/src/commands/GetDeviceInfoCommand.ts index 0670849..33f01f5 100644 --- a/src/commands/GetDeviceInfoCommand.ts +++ b/src/commands/GetDeviceInfoCommand.ts @@ -1,10 +1,10 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, toTable } from '../index'; export class GetDeviceInfoCommand { async run(args) { const outputPath = await rokuDeploy.getDeviceInfo({ host: args.host }); - console.log(JSON.stringify(outputPath)); + console.log(toTable(outputPath)); } } diff --git a/src/util.ts b/src/util.ts index cb90917..19eed65 100644 --- a/src/util.ts +++ b/src/util.ts @@ -255,3 +255,17 @@ export function standardizePathPosix(stringParts, ...expressions: any[]) { result.join('') ); } + +export function toTable(deviceInfo: Record) { + const margin = 5; + const keyWidth = Math.max(...Object.keys(deviceInfo).map(x => x.length)) + margin; + const valueWidth = Math.max(...Object.values(deviceInfo).map(x => (x ?? '')?.toString().length)) + margin; + let table = []; + table.push('Name'.padEnd(keyWidth, ' ') + 'Value'.padEnd(keyWidth, ' ')); + table.push('-'.repeat(keyWidth + valueWidth)); + for (const [key, value] of Object.entries(deviceInfo)) { + table.push(key.padEnd(keyWidth, ' ') + value?.toString().padEnd(keyWidth, ' ')); + } + + return table.join('\n'); +} //TODO: Create a test for this function From 09a275f9fedac4276b61919c259583cf8542d6b6 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Fri, 2 Feb 2024 12:08:24 -0500 Subject: [PATCH 12/93] Change name and input of table helper --- src/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.ts b/src/util.ts index 19eed65..a1e22c0 100644 --- a/src/util.ts +++ b/src/util.ts @@ -256,7 +256,7 @@ export function standardizePathPosix(stringParts, ...expressions: any[]) { ); } -export function toTable(deviceInfo: Record) { +export function printObjectToTable(deviceInfo: Record) { const margin = 5; const keyWidth = Math.max(...Object.keys(deviceInfo).map(x => x.length)) + margin; const valueWidth = Math.max(...Object.values(deviceInfo).map(x => (x ?? '')?.toString().length)) + margin; From e34ac976485170bf8c53b5b8a161d47ad0a926f2 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Fri, 2 Feb 2024 15:30:37 -0500 Subject: [PATCH 13/93] Totally broken code, but have the right names --- src/RokuDeploy.spec.ts | 114 ++-- src/RokuDeploy.ts | 556 +++++------------- src/cli.ts | 51 +- src/commands/DeleteInstalledChannelCommand.ts | 2 +- src/commands/PrepublishCommand.ts | 2 +- src/commands/PublishCommand.ts | 4 +- src/commands/SignExistingPackageCommand.ts | 2 +- src/commands/TakeScreenshotCommand.ts | 2 +- src/commands/ZipPackageCommand.ts | 2 +- src/index.ts | 12 +- src/util.ts | 240 ++++++++ 11 files changed, 508 insertions(+), 479 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 76d751a..53e76b2 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -31,6 +31,10 @@ describe('index', () => { beforeEach(() => { rokuDeploy = new RokuDeploy(); + + + rokuDeploy.convertToSquashfs + options = rokuDeploy.getOptions({ rootDir: rootDir, outDir: outDir, @@ -673,7 +677,7 @@ describe('index', () => { let err; try { fsExtra.ensureDirSync(options.stagingDir); - await rokuDeploy.zipPackage({ + await rokuDeploy.zip({ stagingDir: s`${tempDir}/path/to/nowhere`, outDir: outDir }); @@ -686,7 +690,7 @@ describe('index', () => { it('should throw error when manifest is missing and stagingDir does not exist', async () => { let err; try { - await rokuDeploy.zipPackage({ + await rokuDeploy.zip({ stagingDir: s`${tempDir}/path/to/nowhere`, outDir: outDir }); @@ -782,7 +786,7 @@ describe('index', () => { }); it('should retain the staging directory when told to', async () => { - let stagingDirValue = await rokuDeploy.prepublishToStaging({ + let stagingDirValue = await rokuDeploy.stage({ files: [ 'manifest' ], @@ -790,7 +794,7 @@ describe('index', () => { rootDir: rootDir }); expectPathExists(stagingDirValue); - await rokuDeploy.zipPackage({ + await rokuDeploy.zip({ stagingDir: stagingDir, retainStagingDir: true, outDir: outDir @@ -971,7 +975,7 @@ describe('index', () => { //the file should exist expect(fsExtra.pathExistsSync(zipPath)).to.be.true; - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -987,7 +991,7 @@ describe('index', () => { //the file should exist expect(fsExtra.pathExistsSync(zipPath)).to.be.true; - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1018,7 +1022,7 @@ describe('index', () => { //the file should exist expect(fsExtra.pathExistsSync(zipPath)).to.be.true; - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1032,7 +1036,7 @@ describe('index', () => { it('fails when the zip file is missing', async () => { await expectThrowsAsync(async () => { - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1046,7 +1050,7 @@ describe('index', () => { it('fails when no host is provided', () => { expectPathNotExists('rokudeploy.json'); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: undefined, password: 'password', outDir: outDir, @@ -1072,7 +1076,7 @@ describe('index', () => { }); try { - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1091,7 +1095,7 @@ describe('index', () => { Shell.create('Roku.Message').trigger('Set message type', 'error').trigger('Set message content', 'Install Failure: Compilation Failed').trigger('Render', node); `); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1110,7 +1114,7 @@ describe('index', () => { Shell.create('Roku.Message').trigger('Set message type', 'error').trigger('Set message content', 'Install Failure: Compilation Failed').trigger('Render', node); `); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1127,7 +1131,7 @@ describe('index', () => { let body = 'Install Failure: Compilation Failed.'; mockDoPostRequest(body); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1144,7 +1148,7 @@ describe('index', () => { it('rejects when response contains invalid password status code', () => { mockDoPostRequest('', 401); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1161,7 +1165,7 @@ describe('index', () => { it('handles successful deploy', () => { mockDoPostRequest(); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1177,7 +1181,7 @@ describe('index', () => { it('handles successful deploy with remoteDebug', () => { const stub = mockDoPostRequest(); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1195,7 +1199,7 @@ describe('index', () => { it('handles successful deploy with remotedebug_connect_early', () => { const stub = mockDoPostRequest(); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1215,7 +1219,7 @@ describe('index', () => { let body = 'Identical to previous version -- not replacing.'; mockDoPostRequest(body); - return rokuDeploy.publish({ + return rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1233,7 +1237,7 @@ describe('index', () => { mockDoPostRequest(body, 123); try { - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1251,7 +1255,7 @@ describe('index', () => { mockDoPostRequest('', 401); try { - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1269,7 +1273,7 @@ describe('index', () => { mockDoPostRequest(null); try { - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: '1.2.3.4', password: 'password', outDir: outDir, @@ -1517,7 +1521,7 @@ describe('index', () => { it('should return our error if signingPassword is not supplied', async () => { await expectThrowsAsync(async () => { - await rokuDeploy.signExistingPackage({ + await rokuDeploy.signPackage({ host: '1.2.3.4', password: 'password', signingPassword: undefined, @@ -1534,7 +1538,7 @@ describe('index', () => { process.nextTick(callback, error); return {} as any; }); - await rokuDeploy.signExistingPackage({ + await rokuDeploy.signPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1550,7 +1554,7 @@ describe('index', () => { it('should return our error if it received invalid data', async () => { try { mockDoPostRequest(null); - await rokuDeploy.signExistingPackage({ + await rokuDeploy.signPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1571,7 +1575,7 @@ describe('index', () => { mockDoPostRequest(body); await expectThrowsAsync( - rokuDeploy.signExistingPackage({ + rokuDeploy.signPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1587,7 +1591,7 @@ describe('index', () => { node.appendChild(pkgDiv);`; mockDoPostRequest(body); - let pkgPath = await rokuDeploy.signExistingPackage({ + let pkgPath = await rokuDeploy.signPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1599,7 +1603,7 @@ describe('index', () => { it('should return our fallback error if neither error or package link was detected', async () => { mockDoPostRequest(); await expectThrowsAsync( - rokuDeploy.signExistingPackage({ + rokuDeploy.signPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1612,7 +1616,7 @@ describe('index', () => { describe('prepublishToStaging', () => { it('should use outDir for staging folder', async () => { - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest' ], @@ -1622,7 +1626,7 @@ describe('index', () => { }); it('should support overriding the staging folder', async () => { - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: ['manifest'], stagingDir: `${tempDir}/custom-out-dir`, rootDir: rootDir @@ -1635,7 +1639,7 @@ describe('index', () => { 'manifest', 'source/main.brs' ]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', 'source/main.brs' @@ -1652,7 +1656,7 @@ describe('index', () => { 'manifest', 'source/main.brs' ]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', { @@ -1671,7 +1675,7 @@ describe('index', () => { 'manifest', 'source/main.brs' ]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ { src: 'manifest', @@ -1698,7 +1702,7 @@ describe('index', () => { 'manifest', 'source/main.brs' ]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ { src: 'manifest', @@ -1719,7 +1723,7 @@ describe('index', () => { writeFiles(rootDir, [ 'manifest' ]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ { src: sp`${rootDir}/manifest`, @@ -1743,7 +1747,7 @@ describe('index', () => { 'components/scenes/home/home.brs' ]); console.log('before'); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', 'components/!(scenes)/**/*' @@ -1763,7 +1767,7 @@ describe('index', () => { 'components/Loader/Loader.brs', 'components/scenes/Home/Home.brs' ]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', 'source', @@ -1780,7 +1784,7 @@ describe('index', () => { it('throws on invalid entries', async () => { try { - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', {} @@ -1797,7 +1801,7 @@ describe('index', () => { it('retains subfolder structure when referencing a folder', async () => { fsExtra.outputFileSync(`${rootDir}/flavors/shared/resources/images/fhd/image.jpg`, ''); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', { @@ -1817,7 +1821,7 @@ describe('index', () => { 'flavors/shared/resources/images/fhd/image.jpg', 'resources/image.jpg' ]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', { @@ -1919,7 +1923,7 @@ describe('index', () => { dest: s`renamed_test.md` }]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ rootDir: rootDir, stagingDir: stagingDir, files: [ @@ -1971,7 +1975,7 @@ describe('index', () => { dest: s`source/main.brs` }]); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ files: [ 'manifest', 'source/**/*' @@ -2004,7 +2008,7 @@ describe('index', () => { fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ rootDir: rootDir, stagingDir: stagingDir, files: [ @@ -2038,7 +2042,7 @@ describe('index', () => { fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); await expectThrowsAsync( - rokuDeploy.prepublishToStaging({ + rokuDeploy.stage({ rootDir: rootDir, stagingDir: stagingDir, files: [ @@ -2250,7 +2254,7 @@ describe('index', () => { it('attempts to delete any installed dev channel on the device', async () => { mockDoPostRequest(); - let result = await rokuDeploy.deleteInstalledChannel({ + let result = await rokuDeploy.deleteDevChannel({ host: '1.2.3.4', password: 'password' }); @@ -2301,19 +2305,19 @@ describe('index', () => { `); mockDoPostRequest(body); - await expectThrowsAsync(rokuDeploy.takeScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); }); it('throws when there is no response body', async () => { // missing body mockDoPostRequest(null); - await expectThrowsAsync(rokuDeploy.takeScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); }); it('throws when there is an empty response body', async () => { // empty body mockDoPostRequest(); - await expectThrowsAsync(rokuDeploy.takeScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); }); it('throws when there is an error downloading the image from device', async () => { @@ -2334,7 +2338,7 @@ describe('index', () => { }; mockDoPostRequest(body); - await expectThrowsAsync(rokuDeploy.takeScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); }); it('handles the device returning a png', async () => { @@ -2355,7 +2359,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.takeScreenshot({ host: options.host, password: options.password }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password }); expect(result).not.to.be.undefined; expect(path.extname(result)).to.equal('.png'); expect(fsExtra.existsSync(result)); @@ -2379,7 +2383,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.takeScreenshot({ host: options.host, password: options.password }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password }); expect(result).not.to.be.undefined; expect(path.extname(result)).to.equal('.jpg'); expect(fsExtra.existsSync(result)); @@ -2403,7 +2407,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.takeScreenshot({ host: options.host, password: options.password, outDir: `${tempDir}/myScreenShots` }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outDir: `${tempDir}/myScreenShots` }); expect(result).not.to.be.undefined; expect(util.standardizePath(`${tempDir}/myScreenShots`)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(result)); @@ -2427,7 +2431,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.takeScreenshot({ host: options.host, password: options.password, outDir: tempDir, outFile: 'my' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outDir: tempDir, outFile: 'my' }); expect(result).not.to.be.undefined; expect(util.standardizePath(tempDir)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(path.join(tempDir, 'my.png'))); @@ -2451,7 +2455,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.takeScreenshot({ host: options.host, password: options.password, outDir: tempDir, outFile: 'my.jpg' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outDir: tempDir, outFile: 'my.jpg' }); expect(result).not.to.be.undefined; expect(util.standardizePath(tempDir)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(path.join(tempDir, 'my.jpg.png'))); @@ -2475,7 +2479,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.takeScreenshot({ host: options.host, password: options.password }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password }); expect(result).not.to.be.undefined; expect(fsExtra.existsSync(result)); }); @@ -2498,7 +2502,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.takeScreenshot({ host: options.host, password: options.password, outFile: 'myFile' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outFile: 'myFile' }); expect(result).not.to.be.undefined; expect(path.basename(result)).to.equal('myFile.jpg'); expect(fsExtra.existsSync(result)); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 4438f21..28e1059 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -26,86 +26,56 @@ export class RokuDeploy { } private logger: Logger; - //store the import on the class to make testing easier - public fsExtra = _fsExtra; - - public screenshotDir = path.join(tempDir, '/roku-deploy/screenshots/'); + //this should just + // public screenshotDir = path.join(tempDir, '/roku-deploy/screenshots/'); /** * Copies all of the referenced files to the staging folder * @param options */ - public async prepublishToStaging(options: PrepublishToStagingOptions) { + public async stage(options: StageOptions) { options = this.getOptions(options) as any; //clean the staging directory - await this.fsExtra.remove(options.stagingDir); + await fsExtra.remove(options.stagingDir); //make sure the staging folder exists - await this.fsExtra.ensureDir(options.stagingDir); - await this.copyToStaging(options.files, options.stagingDir, options.rootDir); - return options.stagingDir; - } - - /** - * Given an array of `FilesType`, normalize them each into a `StandardizedFileEntry`. - * Each entry in the array or inner `src` array will be extracted out into its own object. - * This makes it easier to reason about later on in the process. - * @param files - */ - public normalizeFilesArray(files: FileEntry[]) { - const result: Array = []; - - for (let i = 0; i < files.length; i++) { - let entry = files[i]; - //skip falsey and blank entries - if (!entry) { - continue; - - //string entries - } else if (typeof entry === 'string') { - result.push(entry); - - //objects with src: (string | string[]) - } else if ('src' in entry) { - //validate dest - if (entry.dest !== undefined && entry.dest !== null && typeof entry.dest !== 'string') { - throw new Error(`Invalid type for "dest" at index ${i} of files array`); - } + await fsExtra.ensureDir(options.stagingDir); + // await this.copyToStaging(options.files, options.stagingDir, options.rootDir); - //objects with src: string - if (typeof entry.src === 'string') { - result.push({ - src: entry.src, - dest: util.standardizePath(entry.dest) - }); - - //objects with src:string[] - } else if ('src' in entry && Array.isArray(entry.src)) { - //create a distinct entry for each item in the src array - for (let srcEntry of entry.src) { - result.push({ - src: srcEntry, - dest: util.standardizePath(entry.dest) - }); - } - } else { - throw new Error(`Invalid type for "src" at index ${i} of files array`); - } - } else { - throw new Error(`Invalid entry at index ${i} in files array`); - } + if (!stagingPath) { + throw new Error('stagingPath is required'); + } + if (!await fsExtra.pathExists(rootDir)) { + throw new Error(`rootDir does not exist at "${rootDir}"`); } - return result; + let fileObjects = await this.getFilePaths(options.files, rootDir); + //copy all of the files + await Promise.all(fileObjects.map(async (fileObject) => { + let destFilePath = util.standardizePath(`${stagingPath}/${fileObject.dest}`); + + //make sure the containing folder exists + await this.fsExtra.ensureDir(path.dirname(destFilePath)); + + //sometimes the copyfile action fails due to race conditions (normally to poorly constructed src;dest; objects with duplicate files in them + await util.tryRepeatAsync(async () => { + //copy the src item using the filesystem + await this.fsExtra.copy(fileObject.src, destFilePath, { + //copy the actual files that symlinks point to, not the symlinks themselves + dereference: true + }); + }, 10); + })); + return options.stagingDir; } /** * Given an already-populated staging folder, create a zip archive of it and copy it to the output folder * @param options */ - public async zipPackage(options: ZipPackageOptions) { + public async zip(options: ZipPackageOptions) { options = this.getOptions(options) as any; //make sure the output folder exists @@ -119,260 +89,44 @@ export class RokuDeploy { } //create a zip of the staging folder - await this.zipFolder(options.stagingDir, zipFilePath); - - //delete the staging folder unless told to retain it. - if (options.retainStagingDir !== true) { - await this.fsExtra.remove(options.stagingDir); - } - } - - /** - * Create a zip folder containing all of the specified roku project files. - * @param options - */ - public async createPackage(options: CreatePackageOptions, beforeZipCallback?: (info: BeforeZipCallbackInfo) => Promise | void) { - options = this.getOptions(options) as any; - - await this.prepublishToStaging(options); - - let manifestPath = util.standardizePath(`${options.stagingDir}/manifest`); - let parsedManifest = await this.parseManifest(manifestPath); - - if (options.incrementBuildNumber) { - let timestamp = dateformat(new Date(), 'yymmddHHMM'); - parsedManifest.build_version = timestamp; //eslint-disable-line camelcase - await this.fsExtra.writeFile(manifestPath, this.stringifyManifest(parsedManifest)); - } - - if (beforeZipCallback) { - let info: BeforeZipCallbackInfo = { - manifestData: parsedManifest, - stagingFolderPath: options.stagingDir, - stagingDir: options.stagingDir - }; - - await Promise.resolve(beforeZipCallback(info)); - } - await this.zipPackage(options); + await this.__makeZip(options.stagingDir, zipFilePath); } /** - * Given a root directory, normalize it to a full path. - * Fall back to cwd if not specified - * @param rootDir - */ - public normalizeRootDir(rootDir: string) { - if (!rootDir || (typeof rootDir === 'string' && rootDir.trim().length === 0)) { - return process.cwd(); - } else { - return path.resolve(rootDir); - } - } - - /** - * Get all file paths for the specified options - * @param files - * @param rootFolderPath - the absolute path to the root dir where relative files entries are relative to - */ - public async getFilePaths(files: FileEntry[], rootDir: string): Promise { - //if the rootDir isn't absolute, convert it to absolute using the standard options flow - if (path.isAbsolute(rootDir) === false) { - rootDir = this.getOptions({ rootDir: rootDir }).rootDir; - } - const entries = this.normalizeFilesArray(files); - const srcPathsByIndex = await util.globAllByIndex( - entries.map(x => { - return typeof x === 'string' ? x : x.src; - }), - rootDir - ); - - /** - * Result indexed by the dest path - */ - let result = new Map(); - - //compute `dest` path for every file - for (let i = 0; i < srcPathsByIndex.length; i++) { - const srcPaths = srcPathsByIndex[i]; - const entry = entries[i]; - if (srcPaths) { - for (let srcPath of srcPaths) { - srcPath = util.standardizePath(srcPath); - - const dest = this.computeFileDestPath(srcPath, entry, rootDir); - //the last file with this `dest` will win, so just replace any existing entry with this one. - result.set(dest, { - src: srcPath, - dest: dest - }); - } - } - } - return [...result.values()]; - } - - /** - * Given a full path to a file, determine its dest path - * @param srcPath the absolute path to the file. This MUST be a file path, and it is not verified to exist on the filesystem - * @param files the files array - * @param rootDir the absolute path to the root dir - * @param skipMatch - skip running the minimatch process (i.e. assume the file is a match - * @returns the RELATIVE path to the dest location for the file. + * Given a path to a folder, zip up that folder and all of its contents + * @param srcFolder the folder that should be zipped + * @param zipFilePath the path to the zip that will be created + * @param preZipCallback a function to call right before every file gets added to the zip + * @param files a files array used to filter the files from `srcFolder` */ - public getDestPath(srcPathAbsolute: string, files: FileEntry[], rootDir: string, skipMatch = false) { - srcPathAbsolute = util.standardizePath(srcPathAbsolute); - rootDir = rootDir.replace(/\\+/g, '/'); - const entries = this.normalizeFilesArray(files); - - function makeGlobAbsolute(pattern: string) { - return path.resolve( - path.posix.join( - rootDir, - //remove leading exclamation point if pattern is negated - pattern - //coerce all slashes to forward - ) - ).replace(/\\/g, '/'); - } - - let result: string; + private async __makeZip(srcFolder: string, zipFilePath: string, preFileZipCallback?: (file: StandardizedFileEntry, data: Buffer) => Buffer, files: FileEntry[] = ['**/*']) { + const filePaths = await util.getFilePaths(files, srcFolder); - //add the file into every matching cache bucket - for (let entry of entries) { - const pattern = (typeof entry === 'string' ? entry : entry.src); - //filter previous paths - if (pattern.startsWith('!')) { - const keepFile = picomatch('!' + makeGlobAbsolute(pattern.replace(/^!/, ''))); - if (!keepFile(srcPathAbsolute)) { - result = undefined; - } - } else { - const keepFile = picomatch(makeGlobAbsolute(pattern)); - if (keepFile(srcPathAbsolute)) { - try { - result = this.computeFileDestPath( - srcPathAbsolute, - entry, - util.standardizePath(rootDir) - ); - } catch { - //ignore errors...the file just has no dest path - } + const zip = new JSZip(); + // Allows us to wait until all are done before we build the zip + const promises = []; + for (const file of filePaths) { + const promise = this.fsExtra.readFile(file.src).then((data) => { + if (preFileZipCallback) { + data = preFileZipCallback(file, data); } - } - } - return result; - } - /** - * Compute the `dest` path. This accounts for magic globstars in the pattern, - * as well as relative paths based on the dest. This is only used internally. - * @param src an absolute, normalized path for a file - * @param dest the `dest` entry for this file. If omitted, files will derive their paths relative to rootDir. - * @param pattern the glob pattern originally used to find this file - * @param rootDir absolute normalized path to the rootDir - */ - private computeFileDestPath(srcPath: string, entry: string | StandardizedFileEntry, rootDir: string) { - let result: string; - let globstarIdx: number; - //files under rootDir with no specified dest - if (typeof entry === 'string') { - if (util.isParentOfPath(rootDir, srcPath, false)) { - //files that are actually relative to rootDir - result = util.stringReplaceInsensitive(srcPath, rootDir, ''); - } else { - // result = util.stringReplaceInsensitive(srcPath, rootDir, ''); - throw new Error('Cannot reference a file outside of rootDir when using a top-level string. Please use a src;des; object instead'); - } - - //non-glob-pattern explicit file reference - } else if (!isGlob(entry.src.replace(/\\/g, '/'), { strict: false })) { - let isEntrySrcAbsolute = path.isAbsolute(entry.src); - let entrySrcPathAbsolute = isEntrySrcAbsolute ? entry.src : util.standardizePath(`${rootDir}/${entry.src}`); - - let isSrcChildOfRootDir = util.isParentOfPath(rootDir, entrySrcPathAbsolute, false); - - let fileNameAndExtension = path.basename(entrySrcPathAbsolute); - - //no dest - if (entry.dest === null || entry.dest === undefined) { - //no dest, absolute path or file outside of rootDir - if (isEntrySrcAbsolute || isSrcChildOfRootDir === false) { - //copy file to root of staging folder - result = fileNameAndExtension; + const ext = path.extname(file.dest).toLowerCase(); + let compression = 'DEFLATE'; - //no dest, relative path, lives INSIDE rootDir - } else { - //copy relative file structure to root of staging folder - let srcPathRelative = util.stringReplaceInsensitive(entrySrcPathAbsolute, rootDir, ''); - result = srcPathRelative; + if (ext === '.jpg' || ext === '.png' || ext === '.jpeg') { + compression = 'STORE'; } - - //assume entry.dest is the relative path to the folder AND file if applicable - } else if (entry.dest === '') { - result = fileNameAndExtension; - } else { - result = entry.dest; - } - //has a globstar - } else if ((globstarIdx = entry.src.indexOf('**')) > -1) { - const rootGlobstarPath = path.resolve(rootDir, entry.src.substring(0, globstarIdx)) + path.sep; - const srcPathRelative = util.stringReplaceInsensitive(srcPath, rootGlobstarPath, ''); - if (entry.dest) { - result = `${entry.dest}/${srcPathRelative}`; - } else { - result = srcPathRelative; - } - - //`pattern` is some other glob magic - } else { - const fileNameAndExtension = path.basename(srcPath); - if (entry.dest) { - result = util.standardizePath(`${entry.dest}/${fileNameAndExtension}`); - } else { - result = util.stringReplaceInsensitive(srcPath, rootDir, ''); - } - } - - result = util.standardizePath( - //remove leading slashes - result.replace(/^[\/\\]+/, '') - ); - return result; - } - - /** - * Copy all of the files to the staging directory - * @param fileGlobs - * @param stagingPath - */ - private async copyToStaging(files: FileEntry[], stagingPath: string, rootDir: string) { - if (!stagingPath) { - throw new Error('stagingPath is required'); - } - if (!await this.fsExtra.pathExists(rootDir)) { - throw new Error(`rootDir does not exist at "${rootDir}"`); - } - - let fileObjects = await this.getFilePaths(files, rootDir); - //copy all of the files - await Promise.all(fileObjects.map(async (fileObject) => { - let destFilePath = util.standardizePath(`${stagingPath}/${fileObject.dest}`); - - //make sure the containing folder exists - await this.fsExtra.ensureDir(path.dirname(destFilePath)); - - //sometimes the copyfile action fails due to race conditions (normally to poorly constructed src;dest; objects with duplicate files in them - await util.tryRepeatAsync(async () => { - //copy the src item using the filesystem - await this.fsExtra.copy(fileObject.src, destFilePath, { - //copy the actual files that symlinks point to, not the symlinks themselves - dereference: true + zip.file(file.dest.replace(/[\\/]/g, '/'), data, { + compression: compression }); - }, 10); - })); + }); + promises.push(promise); + } + await Promise.all(promises); + // level 2 compression seems to be the best balance between speed and file size. Speed matters more since most will be calling squashfs afterwards. + const content = await zip.generateAsync({ type: 'nodebuffer', compressionOptions: { level: 2 } }); + return this.fsExtra.writeFile(zipFilePath, content); } private generateBaseRequestOptions(requestPath: string, options: BaseRequestOptions, formData = {} as T): requestType.OptionsWithUrl { @@ -392,6 +146,37 @@ export class RokuDeploy { return baseRequestOptions; } + public async keypress(options: { key: string }) { + return this.sendKeyEvent({ + ...options, + action: 'keypress' + }); + } + + public async keyup(options: any) { + return this.sendKeyEvent({ + ...options, + action: 'keyup' + }); + } + + public async keydown(options: any) { + return this.sendKeyEvent({ + ...options, + action: 'keydown' + }); + } + + public async sendText(options: any) { + const chars = options.text.split(''); + for (const char of chars) { + await this.keypress({ + ...options, + key: `lit_${char}` + }); + } + } + /** * Simulate pressing the home button on the remote for this roku. * This makes the roku return to the home screen @@ -399,7 +184,7 @@ export class RokuDeploy { * @param port - the port that should be used for the request. defaults to 8060 * @param timeout - request timeout duration in milliseconds. defaults to 150000 */ - public async pressHomeButton(host, port?: number, timeout?: number) { + private async sendKeyEvent(options: { host: string; port?: string; key: 'home' | 'left' | 'all.the.others'; action: 'keypress' | 'keyup' | 'keydown'; timeout?: number }) { let options = this.getOptions(); port = port ? port : options.remotePort; timeout = timeout ? timeout : options.timeout; @@ -410,11 +195,18 @@ export class RokuDeploy { }, false); } + public async closeChannel(options: CloseAppOptions) { + //TODO + + //if supports ecp close-app, then do that (twice so it kills instant resume) + //else, send home press + } + /** * Publish a pre-existing packaged zip file to a remote Roku. * @param options */ - public async publish(options: PublishOptions): Promise<{ message: string; results: any }> { + public async sideload(options: PublishOptions): Promise<{ message: string; results: any }> { options = this.getOptions(options) as any; if (!options.host) { throw new errors.MissingRequiredOptionError('must specify the host for the Roku device'); @@ -423,6 +215,15 @@ export class RokuDeploy { await this.fsExtra.ensureDir(options.outDir); let zipFilePath = this.getOutputZipFilePath(options as any); + + if (options.deleteInstalledChannel) { + try { + await this.deleteDevChannel(options); + } catch (e) { + // note we don't report the error; as we don't actually care that we could not deploy - it's just useless noise to log it. + } + } + let readStream: _fsExtra.ReadStream; try { if ((await this.fsExtra.pathExists(zipFilePath)) === false) { @@ -496,7 +297,7 @@ export class RokuDeploy { } /** - * Converts existing loaded package to squashfs for faster loading packages + * Converts the currently sideloaded dev app to squashfs for faster loading packages * @param options */ public async convertToSquashfs(options: ConvertToSquashfsOptions) { @@ -572,7 +373,7 @@ export class RokuDeploy { * Sign a pre-existing package using Roku and return path to retrieve it * @param options */ - public async signExistingPackage(options: SignExistingPackageOptions): Promise { + public async createSignedPackage(options: SignExistingPackageOptions): Promise { options = this.getOptions(options) as any; if (!options.signingPassword) { throw new errors.MissingRequiredOptionError('Must supply signingPassword'); @@ -581,6 +382,11 @@ export class RokuDeploy { let parsedManifest = await this.parseManifest(manifestPath); let appName = parsedManifest.title + '/' + parsedManifest.major_version + '.' + parsedManifest.minor_version; + //prevent devId mismatch (if devId is specified) + if (options.devId && options.devId !== await this.getDevId()) { + throw new Error('devId mismatch. nope, not gonna sign'); + } + let requestOptions = this.generateBaseRequestOptions('plugin_package', options as any, { mysubmit: 'Package', pkg_time: (new Date()).getTime(), //eslint-disable-line camelcase @@ -597,25 +403,17 @@ export class RokuDeploy { let pkgSearchMatches = //.exec(results.body); if (pkgSearchMatches) { - return pkgSearchMatches[1]; + const url = pkgSearchMatches[1]; + options = this.getOptions(options) as any; + let requestOptions2 = this.generateBaseRequestOptions(url, options); + + let pkgFilePath = this.getOutputPkgFilePath(options as any); + return this.getToFile(requestOptions2, pkgFilePath); } throw new errors.UnknownDeviceResponseError('Unknown error signing package', results); } - /** - * Sign a pre-existing package using Roku and return path to retrieve it - * @param pkgPath - * @param options - */ - public async retrieveSignedPackage(pkgPath: string, options: RetrieveSignedPackageOptions): Promise { - options = this.getOptions(options) as any; - let requestOptions = this.generateBaseRequestOptions(pkgPath, options); - - let pkgFilePath = this.getOutputPkgFilePath(options as any); - return this.getToFile(requestOptions, pkgFilePath); - } - /** * Centralized function for handling POST http requests * @param params @@ -757,29 +555,11 @@ export class RokuDeploy { return result; } - /** - * Create a zip of the project, and then publish to the target Roku device - * @param options - */ - public async deploy(options?: DeployOptions, beforeZipCallback?: (info: BeforeZipCallbackInfo) => void) { - options = this.getOptions(options) as any; - await this.createPackage(options, beforeZipCallback); - if (options.deleteInstalledChannel) { - try { - await this.deleteInstalledChannel(options); - } catch (e) { - // note we don't report the error; as we don't actually care that we could not deploy - it's just useless noise to log it. - } - } - let result = await this.publish(options as any); - return result; - } - /** * Deletes any installed dev channel on the target Roku device * @param options */ - public async deleteInstalledChannel(options?: DeleteInstalledChannelOptions) { + public async deleteDevChannel(options?: DeleteInstalledChannelOptions) { options = this.getOptions(options) as any; let deleteOptions = this.generateBaseRequestOptions('plugin_install', options as any); @@ -793,7 +573,7 @@ export class RokuDeploy { /** * Gets a screenshot from the device. A side-loaded channel must be running or an error will be thrown. */ - public async takeScreenshot(options: TakeScreenshotOptions) { + public async captureScreenshot(options: TakeScreenshotOptions) { options.outDir = options.outDir ?? this.screenshotDir; options.outFile = options.outFile ?? `screenshot-${dayjs().format('YYYY-MM-DD-HH.mm.ss.SSS')}`; let saveFilePath: string; @@ -857,33 +637,11 @@ export class RokuDeploy { }); } - /** - * executes sames steps as deploy and signs the package and stores it in the out folder - * @param options - */ - public async deployAndSignPackage(options?: DeployAndSignPackageOptions, beforeZipCallback?: (info: BeforeZipCallbackInfo) => void): Promise { - options = this.getOptions(options) as any; - let retainStagingDirInitialValue = options.retainStagingDir; - options.retainStagingDir = true; - await this.deploy(options as any, beforeZipCallback); - - if (options.convertToSquashfs) { - await this.convertToSquashfs(options as any); - } - - let remotePkgPath = await this.signExistingPackage(options as any); - let localPkgFilePath = await this.retrieveSignedPackage(remotePkgPath, options as any); - if (retainStagingDirInitialValue !== true) { - await this.fsExtra.remove(options.stagingDir); - } - return localPkgFilePath; - } - /** * Get an options with all overridden vaues, and then defaults for missing values * @param options */ - public getOptions(options: RokuDeployOptions = {}) { + private __getOptions(options: RokuDeployOptions = {}) { let fileOptions: RokuDeployOptions = {}; const fileNames = ['rokudeploy.json', 'bsconfig.json']; if (options.project) { @@ -959,7 +717,7 @@ export class RokuDeploy { * Centralizes getting output zip file path based on passed in options * @param options */ - public getOutputZipFilePath(options?: GetOutputZipFilePathOptions) { + private getOutputZipFilePath(options?: GetOutputZipFilePathOptions) { options = this.getOptions(options) as any; let zipFileName = options.outFile; @@ -976,7 +734,7 @@ export class RokuDeploy { * Centralizes getting output pkg file path based on passed in options * @param options */ - public getOutputPkgFilePath(options?: GetOutputPkgFilePathOptions) { + private getOutputPkgFilePath(options?: GetOutputPkgFilePathOptions) { options = this.getOptions(options) as any; let pkgFileName = options.outFile; @@ -1045,7 +803,7 @@ export class RokuDeploy { * decoding HtmlEntities, etc. * @param deviceInfo */ - public normalizeDeviceInfoFieldValue(value: any) { + private normalizeDeviceInfoFieldValue(value: any) { let num: number; // convert 'true' and 'false' string values to boolean if (value === 'true') { @@ -1059,12 +817,20 @@ export class RokuDeploy { } } + /** + * TODO we might delete this one. let chris think about it. ;) + * @param options + * @returns + */ public async getDevId(options?: GetDevIdOptions) { const deviceInfo = await this.getDeviceInfo(options); return deviceInfo['keyed-developer-id']; } - public async parseManifest(manifestPath: string): Promise { + /** + * TODO move these manifest functions to a util somewhere + */ + private async parseManifest(manifestPath: string): Promise { if (!await this.fsExtra.pathExists(manifestPath)) { throw new Error(manifestPath + ' does not exist'); } @@ -1073,7 +839,10 @@ export class RokuDeploy { return this.parseManifestFromString(manifestContents); } - public parseManifestFromString(manifestContents: string): ManifestData { + /** + * TODO move these manifest functions to a util somewhere + */ + private parseManifestFromString(manifestContents: string): ManifestData { let manifestLines = manifestContents.split('\n'); let manifestData: ManifestData = {}; manifestData.keyIndexes = {}; @@ -1090,6 +859,9 @@ export class RokuDeploy { return manifestData; } + /** + * TODO move these manifest functions to a util somewhere + */ public stringifyManifest(manifestData: ManifestData): string { let output = []; @@ -1113,43 +885,6 @@ export class RokuDeploy { return output.join('\n'); } - - /** - * Given a path to a folder, zip up that folder and all of its contents - * @param srcFolder the folder that should be zipped - * @param zipFilePath the path to the zip that will be created - * @param preZipCallback a function to call right before every file gets added to the zip - * @param files a files array used to filter the files from `srcFolder` - */ - public async zipFolder(srcFolder: string, zipFilePath: string, preFileZipCallback?: (file: StandardizedFileEntry, data: Buffer) => Buffer, files: FileEntry[] = ['**/*']) { - const filePaths = await this.getFilePaths(files, srcFolder); - - const zip = new JSZip(); - // Allows us to wait until all are done before we build the zip - const promises = []; - for (const file of filePaths) { - const promise = this.fsExtra.readFile(file.src).then((data) => { - if (preFileZipCallback) { - data = preFileZipCallback(file, data); - } - - const ext = path.extname(file.dest).toLowerCase(); - let compression = 'DEFLATE'; - - if (ext === '.jpg' || ext === '.png' || ext === '.jpeg') { - compression = 'STORE'; - } - zip.file(file.dest.replace(/[\\/]/g, '/'), data, { - compression: compression - }); - }); - promises.push(promise); - } - await Promise.all(promises); - // level 2 compression seems to be the best balance between speed and file size. Speed matters more since most will be calling squashfs afterwards. - const content = await zip.generateAsync({ type: 'nodebuffer', compressionOptions: { level: 2 } }); - return this.fsExtra.writeFile(zipFilePath, content); - } } export interface ManifestData { @@ -1253,7 +988,7 @@ export interface GetDeviceInfoOptions { enhance?: boolean; } -export interface PrepublishToStagingOptions { +export interface StageOptions { rootDir?: string; files?: FileEntry[]; stagingDir?: string; @@ -1262,7 +997,6 @@ export interface PrepublishToStagingOptions { export interface ZipPackageOptions { stagingDir?: string; - retainStagingDir?: boolean; outDir?: string; } @@ -1313,6 +1047,10 @@ export interface SignExistingPackageOptions { password: string; signingPassword: string; stagingDir?: string; + /** + * If specified, signing will fail if the device's devId is different than this value + */ + devId?: string; } export interface RetrieveSignedPackageOptions { diff --git a/src/cli.ts b/src/cli.ts index 002551f..d54fcbc 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -18,7 +18,52 @@ import { GetDevIdCommand } from './commands/GetDevIdCommand'; import { ZipFolderCommand } from './commands/ZipFolderCommand'; void yargs - .command('prepublishToStaging', 'Copies all of the referenced files to the staging folder', (builder) => { + + //not exposed + // .command('stage') + // .command('zip') + // .command('closeChannel') + // .command('sideload') + // .command('convertToSquashfs') //alias: squash + // .command('rekeyDevice') //alias: rekey + // .command('createSignedPackage') //alias: sign + // .command('deleteDevChannel') // alias: rmdev deldev + + .command('keypress') + .command('keyup') + .command('keydown') + .command('text') //alias: sendText + .command('screenshot') // alias: captureScreenshot + .command('deviceinfo') // alias: getDeviceInfo + .command('devid') // alias: getDevId + + //bundle + .command('stage|zip') + + //deploy + .command('stage|zip|delete|close|sideload') + + //package + .command('close|rekey|stage|zip|delete|close|sideload|squash|sign') + + //exec + .command('magic') + + + + + + + + + + + + + + + + .command('stage', 'Copies all of the referenced files to the staging folder', (builder) => { return builder .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }); @@ -26,7 +71,7 @@ void yargs return new PrepublishCommand().run(args); }) - .command('zipPackage', 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { + .command('zip', 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { return builder .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); @@ -34,6 +79,8 @@ void yargs return new ZipPackageCommand().run(args); }) + + .command('createPackage', 'Create a zip folder containing all of the specified roku project files', (builder) => { return builder .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) diff --git a/src/commands/DeleteInstalledChannelCommand.ts b/src/commands/DeleteInstalledChannelCommand.ts index 1ec9c29..b6cfebc 100644 --- a/src/commands/DeleteInstalledChannelCommand.ts +++ b/src/commands/DeleteInstalledChannelCommand.ts @@ -2,7 +2,7 @@ import { rokuDeploy } from '../index'; export class DeleteInstalledChannelCommand { async run(args) { - await rokuDeploy.deleteInstalledChannel({ + await rokuDeploy.deleteDevChannel({ host: args.host, password: args.password }); diff --git a/src/commands/PrepublishCommand.ts b/src/commands/PrepublishCommand.ts index 2ca65cc..48152ed 100644 --- a/src/commands/PrepublishCommand.ts +++ b/src/commands/PrepublishCommand.ts @@ -2,7 +2,7 @@ import { rokuDeploy } from '../index'; export class PrepublishCommand { async run(args) { - await rokuDeploy.prepublishToStaging({ + await rokuDeploy.stage({ stagingDir: args.stagingDir, rootDir: args.rootDir }); diff --git a/src/commands/PublishCommand.ts b/src/commands/PublishCommand.ts index 91554fa..7338471 100644 --- a/src/commands/PublishCommand.ts +++ b/src/commands/PublishCommand.ts @@ -2,11 +2,11 @@ import { rokuDeploy } from '../index'; export class PublishCommand { async run(args) { - await rokuDeploy.publish({ + await rokuDeploy.sideload({ host: args.host, password: args.password, outDir: args.outDir, outFile: args.outFile }); } -} \ No newline at end of file +} diff --git a/src/commands/SignExistingPackageCommand.ts b/src/commands/SignExistingPackageCommand.ts index 2d5733f..3b1175e 100644 --- a/src/commands/SignExistingPackageCommand.ts +++ b/src/commands/SignExistingPackageCommand.ts @@ -2,7 +2,7 @@ import { rokuDeploy } from '../index'; export class SignExistingPackageCommand { async run(args) { - await rokuDeploy.signExistingPackage({ + await rokuDeploy.signPackage({ host: args.host, password: args.password, signingPassword: args.signingPassword, diff --git a/src/commands/TakeScreenshotCommand.ts b/src/commands/TakeScreenshotCommand.ts index ac5b7bc..2d9f358 100644 --- a/src/commands/TakeScreenshotCommand.ts +++ b/src/commands/TakeScreenshotCommand.ts @@ -2,7 +2,7 @@ import { rokuDeploy } from '../index'; export class TakeScreenshotCommand { async run(args) { - await rokuDeploy.takeScreenshot({ + await rokuDeploy.captureScreenshot({ host: args.host, password: args.password }); diff --git a/src/commands/ZipPackageCommand.ts b/src/commands/ZipPackageCommand.ts index 7ef1f09..4cd0ebf 100644 --- a/src/commands/ZipPackageCommand.ts +++ b/src/commands/ZipPackageCommand.ts @@ -2,7 +2,7 @@ import { rokuDeploy } from '../index'; export class ZipPackageCommand { async run(args) { - await rokuDeploy.zipPackage({ + await rokuDeploy.zip({ stagingDir: args.stagingDir, outDir: args.outDir }); diff --git a/src/index.ts b/src/index.ts index d68b4d5..cb6007a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,7 +11,7 @@ export * from './DeviceInfo'; export const rokuDeploy = new RokuDeploy(); let createPackage = RokuDeploy.prototype.createPackage.bind(rokuDeploy); -let deleteInstalledChannel = RokuDeploy.prototype.deleteInstalledChannel.bind(rokuDeploy); +let deleteInstalledChannel = RokuDeploy.prototype.deleteDevChannel.bind(rokuDeploy); let deploy = RokuDeploy.prototype.deploy.bind(rokuDeploy); let deployAndSignPackage = RokuDeploy.prototype.deployAndSignPackage.bind(rokuDeploy); let getDestPath = RokuDeploy.prototype.getDestPath.bind(rokuDeploy); @@ -23,17 +23,17 @@ let getOutputZipFilePath = RokuDeploy.prototype.getOutputZipFilePath.bind(rokuDe let normalizeFilesArray = RokuDeploy.prototype.normalizeFilesArray.bind(rokuDeploy); let normalizeRootDir = RokuDeploy.prototype.normalizeRootDir.bind(rokuDeploy); let parseManifest = RokuDeploy.prototype.parseManifest.bind(rokuDeploy); -let prepublishToStaging = RokuDeploy.prototype.prepublishToStaging.bind(rokuDeploy); +let prepublishToStaging = RokuDeploy.prototype.stage.bind(rokuDeploy); let pressHomeButton = RokuDeploy.prototype.pressHomeButton.bind(rokuDeploy); -let publish = RokuDeploy.prototype.publish.bind(rokuDeploy); +let publish = RokuDeploy.prototype.sideload.bind(rokuDeploy); let rekeyDevice = RokuDeploy.prototype.rekeyDevice.bind(rokuDeploy); let retrieveSignedPackage = RokuDeploy.prototype.retrieveSignedPackage.bind(rokuDeploy); -let signExistingPackage = RokuDeploy.prototype.signExistingPackage.bind(rokuDeploy); +let signExistingPackage = RokuDeploy.prototype.signPackage.bind(rokuDeploy); let stringifyManifest = RokuDeploy.prototype.stringifyManifest.bind(rokuDeploy); -let takeScreenshot = RokuDeploy.prototype.takeScreenshot.bind(rokuDeploy); +let takeScreenshot = RokuDeploy.prototype.captureScreenshot.bind(rokuDeploy); let getDevId = RokuDeploy.prototype.getDevId.bind(rokuDeploy); let zipFolder = RokuDeploy.prototype.zipFolder.bind(rokuDeploy); -let zipPackage = RokuDeploy.prototype.zipPackage.bind(rokuDeploy); +let zipPackage = RokuDeploy.prototype.zip.bind(rokuDeploy); export { createPackage, diff --git a/src/util.ts b/src/util.ts index a1e22c0..f5a92f8 100644 --- a/src/util.ts +++ b/src/util.ts @@ -225,6 +225,246 @@ export class Util { }); } + /** + * Given an array of `FilesType`, normalize them each into a `StandardizedFileEntry`. + * Each entry in the array or inner `src` array will be extracted out into its own object. + * This makes it easier to reason about later on in the process. + * @param files + */ + public normalizeFilesArray(files: FileEntry[]) { + const result: Array = []; + + for (let i = 0; i < files.length; i++) { + let entry = files[i]; + //skip falsey and blank entries + if (!entry) { + continue; + + //string entries + } else if (typeof entry === 'string') { + result.push(entry); + + //objects with src: (string | string[]) + } else if ('src' in entry) { + //validate dest + if (entry.dest !== undefined && entry.dest !== null && typeof entry.dest !== 'string') { + throw new Error(`Invalid type for "dest" at index ${i} of files array`); + } + + //objects with src: string + if (typeof entry.src === 'string') { + result.push({ + src: entry.src, + dest: util.standardizePath(entry.dest) + }); + + //objects with src:string[] + } else if ('src' in entry && Array.isArray(entry.src)) { + //create a distinct entry for each item in the src array + for (let srcEntry of entry.src) { + result.push({ + src: srcEntry, + dest: util.standardizePath(entry.dest) + }); + } + } else { + throw new Error(`Invalid type for "src" at index ${i} of files array`); + } + } else { + throw new Error(`Invalid entry at index ${i} in files array`); + } + } + + return result; + } + + + /** + * Get all file paths for the specified options + * @param files + * @param rootFolderPath - the absolute path to the root dir where relative files entries are relative to + */ + public async getFilePaths(files: FileEntry[], rootDir: string): Promise { + //if the rootDir isn't absolute, convert it to absolute using the standard options flow + if (path.isAbsolute(rootDir) === false) { + rootDir = this.getOptions({ rootDir: rootDir }).rootDir; + } + const entries = this.normalizeFilesArray(files); + const srcPathsByIndex = await util.globAllByIndex( + entries.map(x => { + return typeof x === 'string' ? x : x.src; + }), + rootDir + ); + + /** + * Result indexed by the dest path + */ + let result = new Map(); + + //compute `dest` path for every file + for (let i = 0; i < srcPathsByIndex.length; i++) { + const srcPaths = srcPathsByIndex[i]; + const entry = entries[i]; + if (srcPaths) { + for (let srcPath of srcPaths) { + srcPath = util.standardizePath(srcPath); + + const dest = this.computeFileDestPath(srcPath, entry, rootDir); + //the last file with this `dest` will win, so just replace any existing entry with this one. + result.set(dest, { + src: srcPath, + dest: dest + }); + } + } + } + return [...result.values()]; + } + + /** + * Given a full path to a file, determine its dest path + * @param srcPath the absolute path to the file. This MUST be a file path, and it is not verified to exist on the filesystem + * @param files the files array + * @param rootDir the absolute path to the root dir + * @param skipMatch - skip running the minimatch process (i.e. assume the file is a match + * @returns the RELATIVE path to the dest location for the file. + */ + public getDestPath(srcPathAbsolute: string, files: FileEntry[], rootDir: string, skipMatch = false) { + srcPathAbsolute = util.standardizePath(srcPathAbsolute); + rootDir = rootDir.replace(/\\+/g, '/'); + const entries = util.normalizeFilesArray(files); + + function makeGlobAbsolute(pattern: string) { + return path.resolve( + path.posix.join( + rootDir, + //remove leading exclamation point if pattern is negated + pattern + //coerce all slashes to forward + ) + ).replace(/\\/g, '/'); + } + + let result: string; + + //add the file into every matching cache bucket + for (let entry of entries) { + const pattern = (typeof entry === 'string' ? entry : entry.src); + //filter previous paths + if (pattern.startsWith('!')) { + const keepFile = picomatch('!' + makeGlobAbsolute(pattern.replace(/^!/, ''))); + if (!keepFile(srcPathAbsolute)) { + result = undefined; + } + } else { + const keepFile = picomatch(makeGlobAbsolute(pattern)); + if (keepFile(srcPathAbsolute)) { + try { + result = this.computeFileDestPath( + srcPathAbsolute, + entry, + util.standardizePath(rootDir) + ); + } catch { + //ignore errors...the file just has no dest path + } + } + } + } + return result; + } + + /** + * Compute the `dest` path. This accounts for magic globstars in the pattern, + * as well as relative paths based on the dest. This is only used internally. + * @param src an absolute, normalized path for a file + * @param dest the `dest` entry for this file. If omitted, files will derive their paths relative to rootDir. + * @param pattern the glob pattern originally used to find this file + * @param rootDir absolute normalized path to the rootDir + */ + private computeFileDestPath(srcPath: string, entry: string | StandardizedFileEntry, rootDir: string) { + let result: string; + let globstarIdx: number; + //files under rootDir with no specified dest + if (typeof entry === 'string') { + if (util.isParentOfPath(rootDir, srcPath, false)) { + //files that are actually relative to rootDir + result = util.stringReplaceInsensitive(srcPath, rootDir, ''); + } else { + // result = util.stringReplaceInsensitive(srcPath, rootDir, ''); + throw new Error('Cannot reference a file outside of rootDir when using a top-level string. Please use a src;des; object instead'); + } + + //non-glob-pattern explicit file reference + } else if (!isGlob(entry.src.replace(/\\/g, '/'), { strict: false })) { + let isEntrySrcAbsolute = path.isAbsolute(entry.src); + let entrySrcPathAbsolute = isEntrySrcAbsolute ? entry.src : util.standardizePath(`${rootDir}/${entry.src}`); + + let isSrcChildOfRootDir = util.isParentOfPath(rootDir, entrySrcPathAbsolute, false); + + let fileNameAndExtension = path.basename(entrySrcPathAbsolute); + + //no dest + if (entry.dest === null || entry.dest === undefined) { + //no dest, absolute path or file outside of rootDir + if (isEntrySrcAbsolute || isSrcChildOfRootDir === false) { + //copy file to root of staging folder + result = fileNameAndExtension; + + //no dest, relative path, lives INSIDE rootDir + } else { + //copy relative file structure to root of staging folder + let srcPathRelative = util.stringReplaceInsensitive(entrySrcPathAbsolute, rootDir, ''); + result = srcPathRelative; + } + + //assume entry.dest is the relative path to the folder AND file if applicable + } else if (entry.dest === '') { + result = fileNameAndExtension; + } else { + result = entry.dest; + } + //has a globstar + } else if ((globstarIdx = entry.src.indexOf('**')) > -1) { + const rootGlobstarPath = path.resolve(rootDir, entry.src.substring(0, globstarIdx)) + path.sep; + const srcPathRelative = util.stringReplaceInsensitive(srcPath, rootGlobstarPath, ''); + if (entry.dest) { + result = `${entry.dest}/${srcPathRelative}`; + } else { + result = srcPathRelative; + } + + //`pattern` is some other glob magic + } else { + const fileNameAndExtension = path.basename(srcPath); + if (entry.dest) { + result = util.standardizePath(`${entry.dest}/${fileNameAndExtension}`); + } else { + result = util.stringReplaceInsensitive(srcPath, rootDir, ''); + } + } + + result = util.standardizePath( + //remove leading slashes + result.replace(/^[\/\\]+/, '') + ); + return result; + } + + /** + * Given a root directory, normalize it to a full path. + * Fall back to cwd if not specified + * @param rootDir + */ + public normalizeRootDir(rootDir: string) { + if (!rootDir || (typeof rootDir === 'string' && rootDir.trim().length === 0)) { + return process.cwd(); + } else { + return path.resolve(rootDir); + } + } + } export let util = new Util(); From 52b1bc06153f67c059cb07a41ed6aa1a0f53ed8f Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 6 Feb 2024 12:56:47 -0500 Subject: [PATCH 14/93] Changed name of toTable --- src/commands/GetDeviceInfoCommand.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/GetDeviceInfoCommand.ts b/src/commands/GetDeviceInfoCommand.ts index 33f01f5..9190cb5 100644 --- a/src/commands/GetDeviceInfoCommand.ts +++ b/src/commands/GetDeviceInfoCommand.ts @@ -1,10 +1,10 @@ -import { rokuDeploy, toTable } from '../index'; +import { rokuDeploy, printObjectToTable } from '../index'; export class GetDeviceInfoCommand { async run(args) { const outputPath = await rokuDeploy.getDeviceInfo({ host: args.host }); - console.log(toTable(outputPath)); + console.log(printObjectToTable(outputPath)); } } From f3a0c56f6cc37408923375f83eae1a07bcf5b83f Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 6 Feb 2024 13:31:48 -0500 Subject: [PATCH 15/93] Make test for objectToTable --- src/commands/GetDeviceInfoCommand.ts | 5 +++-- src/util.spec.ts | 20 ++++++++++++++++++++ src/util.ts | 28 ++++++++++++++-------------- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/commands/GetDeviceInfoCommand.ts b/src/commands/GetDeviceInfoCommand.ts index 9190cb5..af45e53 100644 --- a/src/commands/GetDeviceInfoCommand.ts +++ b/src/commands/GetDeviceInfoCommand.ts @@ -1,10 +1,11 @@ -import { rokuDeploy, printObjectToTable } from '../index'; +import { rokuDeploy } from '../index'; +import { util } from '../util'; export class GetDeviceInfoCommand { async run(args) { const outputPath = await rokuDeploy.getDeviceInfo({ host: args.host }); - console.log(printObjectToTable(outputPath)); + console.log(util.printObjectToTable(outputPath)); } } diff --git a/src/util.spec.ts b/src/util.spec.ts index b174570..70f26e1 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -296,4 +296,24 @@ describe('util', () => { expect(util.decodeHtmlEntities(''')).to.eql(`'`); }); }); + + describe('printObjectToTable', () => { + it('should print an object to a table', () => { + const deviceInfo = { + 'device-id': '1234', + 'serial-number': 'abcd' + }; + + const result = util.printObjectToTable(deviceInfo); + + const expectedOutput = [ + 'Name Value ', + '---------------------------', + 'device-id 1234 ', + 'serial-number abcd ' + ].join('\n'); + + expect(result).to.eql(expectedOutput); + }); + }); }); diff --git a/src/util.ts b/src/util.ts index a1e22c0..29e6c48 100644 --- a/src/util.ts +++ b/src/util.ts @@ -225,6 +225,20 @@ export class Util { }); } + public printObjectToTable(deviceInfo: Record) { + const margin = 5; + const keyWidth = Math.max(...Object.keys(deviceInfo).map(x => x.length)) + margin; + const valueWidth = Math.max(...Object.values(deviceInfo).map(x => (x ?? '')?.toString().length)) + margin; + let table = []; + table.push('Name'.padEnd(keyWidth, ' ') + 'Value'.padEnd(keyWidth, ' ')); + table.push('-'.repeat(keyWidth + valueWidth)); + for (const [key, value] of Object.entries(deviceInfo)) { + table.push(key.padEnd(keyWidth, ' ') + value?.toString().padEnd(keyWidth, ' ')); + } + + return table.join('\n'); + } + } export let util = new Util(); @@ -255,17 +269,3 @@ export function standardizePathPosix(stringParts, ...expressions: any[]) { result.join('') ); } - -export function printObjectToTable(deviceInfo: Record) { - const margin = 5; - const keyWidth = Math.max(...Object.keys(deviceInfo).map(x => x.length)) + margin; - const valueWidth = Math.max(...Object.values(deviceInfo).map(x => (x ?? '')?.toString().length)) + margin; - let table = []; - table.push('Name'.padEnd(keyWidth, ' ') + 'Value'.padEnd(keyWidth, ' ')); - table.push('-'.repeat(keyWidth + valueWidth)); - for (const [key, value] of Object.entries(deviceInfo)) { - table.push(key.padEnd(keyWidth, ' ') + value?.toString().padEnd(keyWidth, ' ')); - } - - return table.join('\n'); -} //TODO: Create a test for this function From b5f41ca07f388be604400913056400dc38d9148a Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 6 Feb 2024 13:36:05 -0500 Subject: [PATCH 16/93] add yargs to pacjage.json --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f4f6ecb..14527d2 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "parse-ms": "^2.1.0", "postman-request": "^2.88.1-postman.32", "temp-dir": "^2.0.0", - "xml2js": "^0.5.0" + "xml2js": "^0.5.0", + "yargs": "^17.7.2" }, "devDependencies": { "@types/chai": "^4.2.22", @@ -45,6 +46,7 @@ "@types/request": "^2.47.0", "@types/sinon": "^10.0.4", "@types/xml2js": "^0.4.5", + "@types/yargs": "^17.0.32", "@typescript-eslint/eslint-plugin": "5.1.0", "@typescript-eslint/parser": "5.1.0", "chai": "^4.3.4", From 4b959438a4d9d26ad8c60dd9a71a005c74e5bcbd Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 6 Feb 2024 13:38:23 -0500 Subject: [PATCH 17/93] add package-lock.json --- package-lock.json | 199 +++++++++++++++++++++++++++++++--------------- 1 file changed, 137 insertions(+), 62 deletions(-) diff --git a/package-lock.json b/package-lock.json index febb616..3695c96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,8 @@ "parse-ms": "^2.1.0", "postman-request": "^2.88.1-postman.32", "temp-dir": "^2.0.0", - "xml2js": "^0.5.0" + "xml2js": "^0.5.0", + "yargs": "^17.7.2" }, "bin": { "roku-deploy": "dist/cli.js" @@ -40,6 +41,7 @@ "@types/request": "^2.47.0", "@types/sinon": "^10.0.4", "@types/xml2js": "^0.4.5", + "@types/yargs": "^17.0.32", "@typescript-eslint/eslint-plugin": "5.1.0", "@typescript-eslint/parser": "5.1.0", "chai": "^4.3.4", @@ -804,6 +806,21 @@ "@types/node": "*" } }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz", @@ -1038,7 +1055,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -1399,14 +1415,16 @@ } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/color-convert": { @@ -1675,8 +1693,7 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/enquirer": { "version": "2.3.6", @@ -1700,7 +1717,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -2304,7 +2320,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -2572,7 +2587,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -3212,6 +3226,17 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3278,6 +3303,24 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -4057,7 +4100,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4363,7 +4405,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4377,7 +4418,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4700,7 +4740,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4717,7 +4756,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -4732,7 +4770,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -4743,8 +4780,7 @@ "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/wrappy": { "version": "1.0.2", @@ -4788,7 +4824,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -4800,21 +4835,20 @@ "dev": true }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { @@ -4874,6 +4908,14 @@ "node": ">=8" } }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -5509,6 +5551,21 @@ "@types/node": "*" } }, + "@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, "@typescript-eslint/eslint-plugin": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz", @@ -5647,8 +5704,7 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "3.2.1", @@ -5918,13 +5974,12 @@ "dev": true }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -6143,8 +6198,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "enquirer": { "version": "2.3.6", @@ -6164,8 +6218,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-string-regexp": { "version": "1.0.5", @@ -6605,8 +6658,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { "version": "2.0.0", @@ -6799,8 +6851,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-glob": { "version": "4.0.3", @@ -7291,6 +7342,17 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -7335,6 +7397,21 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } } } }, @@ -7932,8 +8009,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { "version": "2.0.0", @@ -8167,7 +8243,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -8178,7 +8253,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -8410,7 +8484,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8421,7 +8494,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -8430,7 +8502,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -8438,8 +8509,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" } } }, @@ -8478,8 +8548,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -8488,18 +8557,24 @@ "dev": true }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" + }, + "dependencies": { + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + } } }, "yargs-parser": { From b6c6223017bd260fc788ae0e1277e848c44d6e80 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 6 Feb 2024 13:40:05 -0500 Subject: [PATCH 18/93] add new line at eof --- src/commands/PublishCommand.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/PublishCommand.ts b/src/commands/PublishCommand.ts index 91554fa..39a66cc 100644 --- a/src/commands/PublishCommand.ts +++ b/src/commands/PublishCommand.ts @@ -9,4 +9,4 @@ export class PublishCommand { outFile: args.outFile }); } -} \ No newline at end of file +} From f15f29543051421d6aa51ecc4f8978020bd05c9c Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 6 Feb 2024 13:51:56 -0500 Subject: [PATCH 19/93] Add test for coverage, also remove an unncessary '?' --- src/util.spec.ts | 18 ++++++++++++++++++ src/util.ts | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/util.spec.ts b/src/util.spec.ts index 70f26e1..fd3d353 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -315,5 +315,23 @@ describe('util', () => { expect(result).to.eql(expectedOutput); }); + + it('should still print a table when a value is null', () => { + const deviceInfo = { + 'device-id': '1234', + 'serial-number': null + }; + + const result = util.printObjectToTable(deviceInfo); + + const expectedOutput = [ + 'Name Value ', + '---------------------------', + 'device-id 1234 ', + 'serial-number undefined' + ].join('\n'); + + expect(result).to.eql(expectedOutput); + }); }); }); diff --git a/src/util.ts b/src/util.ts index 29e6c48..c275c88 100644 --- a/src/util.ts +++ b/src/util.ts @@ -228,7 +228,7 @@ export class Util { public printObjectToTable(deviceInfo: Record) { const margin = 5; const keyWidth = Math.max(...Object.keys(deviceInfo).map(x => x.length)) + margin; - const valueWidth = Math.max(...Object.values(deviceInfo).map(x => (x ?? '')?.toString().length)) + margin; + const valueWidth = Math.max(...Object.values(deviceInfo).map(x => (x ?? '').toString().length)) + margin; let table = []; table.push('Name'.padEnd(keyWidth, ' ') + 'Value'.padEnd(keyWidth, ' ')); table.push('-'.repeat(keyWidth + valueWidth)); From 6941e86aad2a1ae4bb4733d931b72421db52754a Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Tue, 6 Feb 2024 15:17:09 -0500 Subject: [PATCH 20/93] tweaks --- src/cli.ts | 36 ++++++++++++++++++++---------------- src/commands/ExecCommand.ts | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 src/commands/ExecCommand.ts diff --git a/src/cli.ts b/src/cli.ts index d54fcbc..d601f12 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -38,28 +38,32 @@ void yargs .command('devid') // alias: getDevId //bundle - .command('stage|zip') + .command('bundle', ()=>{ + const command = new ExecCommand({ + actions: 'stage|zip' + }) + }) //deploy - .command('stage|zip|delete|close|sideload') + .command('deploy', ()=>{ + const command = new ExecCommand({ + actions: 'stage|zip|delete|close|sideload' + }) + }) //package - .command('close|rekey|stage|zip|delete|close|sideload|squash|sign') + .command('package', ()=>{ + const command = new ExecCommand({ + actions: 'close|rekey|stage|zip|delete|close|sideload|squash|sign' + }) + }) //exec - .command('magic') - - - - - - - - - - - - + .command('exec', ()=>{ + const command = new ExecCommand({ + actions: builder.args.actions + }) + }) diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts new file mode 100644 index 0000000..73dfd64 --- /dev/null +++ b/src/commands/ExecCommand.ts @@ -0,0 +1,15 @@ +export class ExecCommand { + constructor({actions: string }){ + this.actions = options.actions.split('|'); + } + + run() { + if(this.actions.includes('stage')){ + rokuDeploy.stage(); + } + + if(this.actions.includes('zip')){ + rokuDeploy.zip(); + } + } +} \ No newline at end of file From ea493425a9579a3746a37105e80d8d245e5e9248 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Tue, 6 Feb 2024 15:17:28 -0500 Subject: [PATCH 21/93] tweaks From 616ff23dc97ee532ccda616f109bc15d40eebae6 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Tue, 6 Feb 2024 15:24:19 -0500 Subject: [PATCH 22/93] get from json stuff --- src/commands/ExecCommand.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts index 73dfd64..a0405c7 100644 --- a/src/commands/ExecCommand.ts +++ b/src/commands/ExecCommand.ts @@ -1,9 +1,15 @@ export class ExecCommand { - constructor({actions: string }){ + constructor(options: {actions: string, configPath: string, ...rokuDeployOptions }){ this.actions = options.actions.split('|'); } run() { + //load options from json + const options = { + ...getFromJson(this.configPath ?? `${cwd}/rokudeploy.json`), + this.options + }; + if(this.actions.includes('stage')){ rokuDeploy.stage(); } From cacf4337e997ae1814904578212559c6637c2150 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 7 Feb 2024 12:45:37 -0500 Subject: [PATCH 23/93] Correct imports --- src/RokuDeploy.ts | 27 ++++++++++++--------------- src/util.ts | 4 ++++ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 28e1059..7401fa6 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -1,20 +1,17 @@ import * as path from 'path'; -import * as _fsExtra from 'fs-extra'; +import * as fsExtra from 'fs-extra'; //TODO: This was removed in Bronley commit. How to fix errors? +import type { WriteStream, ReadStream } from 'fs-extra'; import * as r from 'postman-request'; import type * as requestType from 'request'; const request = r as typeof requestType; import * as JSZip from 'jszip'; -import * as dateformat from 'dateformat'; import * as errors from './Errors'; -import * as isGlob from 'is-glob'; -import * as picomatch from 'picomatch'; import * as xml2js from 'xml2js'; import type { ParseError } from 'jsonc-parser'; import { parse as parseJsonc, printParseErrorCode } from 'jsonc-parser'; import { util } from './util'; import type { RokuDeployOptions, FileEntry } from './RokuDeployOptions'; import { Logger, LogLevel } from './Logger'; -import * as tempDir from 'temp-dir'; import * as dayjs from 'dayjs'; import * as lodash from 'lodash'; import type { DeviceInfo, DeviceInfoRaw } from './DeviceInfo'; @@ -224,7 +221,7 @@ export class RokuDeploy { } } - let readStream: _fsExtra.ReadStream; + let readStream: ReadStream; try { if ((await this.fsExtra.pathExists(zipFilePath)) === false) { throw new Error(`Cannot publish because file does not exist at '${zipFilePath}'`); @@ -337,12 +334,12 @@ export class RokuDeploy { let requestOptions = this.generateBaseRequestOptions('plugin_inspect', options as any, { mysubmit: 'Rekey', passwd: options.signingPassword, - archive: null as _fsExtra.ReadStream + archive: null as ReadStream }); let results: HttpResponse; try { - requestOptions.formData.archive = this.fsExtra.createReadStream(rekeySignedPackagePath); + requestOptions.formData.archive = fsExtra.createReadStream(rekeySignedPackagePath); results = await this.doPostRequest(requestOptions); } finally { //ensure the stream is closed @@ -603,10 +600,10 @@ export class RokuDeploy { } private async getToFile(requestParams: any, filePath: string) { - let writeStream: _fsExtra.WriteStream; - await this.fsExtra.ensureFile(filePath); + let writeStream: WriteStream; + await fsExtra.ensureFile(filePath); return new Promise((resolve, reject) => { - writeStream = this.fsExtra.createWriteStream(filePath, { + writeStream = fsExtra.createWriteStream(filePath, { flags: 'w' }); if (!writeStream) { @@ -649,8 +646,8 @@ export class RokuDeploy { } for (const fileName of fileNames) { - if (this.fsExtra.existsSync(fileName)) { - let configFileText = this.fsExtra.readFileSync(fileName).toString(); + if (fsExtra.existsSync(fileName)) { + let configFileText = fsExtra.readFileSync(fileName).toString(); let parseErrors = [] as ParseError[]; fileOptions = parseJsonc(configFileText, parseErrors, { allowEmptyContent: true, @@ -831,11 +828,11 @@ export class RokuDeploy { * TODO move these manifest functions to a util somewhere */ private async parseManifest(manifestPath: string): Promise { - if (!await this.fsExtra.pathExists(manifestPath)) { + if (!await fsExtra.pathExists(manifestPath)) { throw new Error(manifestPath + ' does not exist'); } - let manifestContents = await this.fsExtra.readFile(manifestPath, 'utf-8'); + let manifestContents = await fsExtra.readFile(manifestPath, 'utf-8'); return this.parseManifestFromString(manifestContents); } diff --git a/src/util.ts b/src/util.ts index f0a25a2..c1d648f 100644 --- a/src/util.ts +++ b/src/util.ts @@ -5,6 +5,10 @@ import * as dns from 'dns'; import * as micromatch from 'micromatch'; // eslint-disable-next-line @typescript-eslint/no-require-imports import fastGlob = require('fast-glob'); +import type { FileEntry } from './RokuDeployOptions'; +import type { StandardizedFileEntry } from './RokuDeploy'; +import * as isGlob from 'is-glob'; +import * as picomatch from 'picomatch'; export class Util { /** From cbd641779bf10ad16fd2cb7c605b85205a0fa6a0 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 7 Feb 2024 13:02:25 -0500 Subject: [PATCH 24/93] Last of the fsExtra changes --- src/RokuDeploy.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 7401fa6..0105fde 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -54,12 +54,12 @@ export class RokuDeploy { let destFilePath = util.standardizePath(`${stagingPath}/${fileObject.dest}`); //make sure the containing folder exists - await this.fsExtra.ensureDir(path.dirname(destFilePath)); + await fsExtra.ensureDir(path.dirname(destFilePath)); //sometimes the copyfile action fails due to race conditions (normally to poorly constructed src;dest; objects with duplicate files in them await util.tryRepeatAsync(async () => { //copy the src item using the filesystem - await this.fsExtra.copy(fileObject.src, destFilePath, { + await fsExtra.copy(fileObject.src, destFilePath, { //copy the actual files that symlinks point to, not the symlinks themselves dereference: true }); @@ -76,7 +76,7 @@ export class RokuDeploy { options = this.getOptions(options) as any; //make sure the output folder exists - await this.fsExtra.ensureDir(options.outDir); + await fsExtra.ensureDir(options.outDir); let zipFilePath = this.getOutputZipFilePath(options as any); @@ -103,7 +103,7 @@ export class RokuDeploy { // Allows us to wait until all are done before we build the zip const promises = []; for (const file of filePaths) { - const promise = this.fsExtra.readFile(file.src).then((data) => { + const promise = fsExtra.readFile(file.src).then((data) => { if (preFileZipCallback) { data = preFileZipCallback(file, data); } @@ -123,7 +123,7 @@ export class RokuDeploy { await Promise.all(promises); // level 2 compression seems to be the best balance between speed and file size. Speed matters more since most will be calling squashfs afterwards. const content = await zip.generateAsync({ type: 'nodebuffer', compressionOptions: { level: 2 } }); - return this.fsExtra.writeFile(zipFilePath, content); + return fsExtra.writeFile(zipFilePath, content); } private generateBaseRequestOptions(requestPath: string, options: BaseRequestOptions, formData = {} as T): requestType.OptionsWithUrl { @@ -209,7 +209,7 @@ export class RokuDeploy { throw new errors.MissingRequiredOptionError('must specify the host for the Roku device'); } //make sure the outDir exists - await this.fsExtra.ensureDir(options.outDir); + await fsExtra.ensureDir(options.outDir); let zipFilePath = this.getOutputZipFilePath(options as any); @@ -223,10 +223,10 @@ export class RokuDeploy { let readStream: ReadStream; try { - if ((await this.fsExtra.pathExists(zipFilePath)) === false) { + if ((await fsExtra.pathExists(zipFilePath)) === false) { throw new Error(`Cannot publish because file does not exist at '${zipFilePath}'`); } - readStream = this.fsExtra.createReadStream(zipFilePath); + readStream = fsExtra.createReadStream(zipFilePath); //wait for the stream to open (no harm in doing this, and it helps solve an issue in the tests) await new Promise((resolve) => { readStream.on('open', resolve); @@ -275,7 +275,7 @@ export class RokuDeploy { } finally { //delete the zip file only if configured to do so if (options.retainDeploymentArchive === false) { - await this.fsExtra.remove(zipFilePath); + await fsExtra.remove(zipFilePath); } //try to close the read stream to prevent files becoming locked try { From ebab568eb8a5dd3d50e837f9cd79a6869a40e29d Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 21 Feb 2024 14:19:59 -0500 Subject: [PATCH 25/93] Create a load from json util, clean up cli.ts file with fleshing out comments, delete unnecessary command/tests/options, partially fix exec command --- src/RokuDeploy.spec.ts | 176 --------------------------- src/RokuDeploy.ts | 39 +----- src/cli.ts | 122 ++++++++++--------- src/commands/CreatePackageCommand.ts | 11 -- src/commands/ExecCommand.ts | 71 +++++++++-- src/commands/TextCommand.ts | 8 ++ src/util.ts | 19 +++ 7 files changed, 153 insertions(+), 293 deletions(-) delete mode 100644 src/commands/CreatePackageCommand.ts create mode 100644 src/commands/TextCommand.ts diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 53e76b2..93da38c 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -703,182 +703,6 @@ describe('index', () => { }); - describe('createPackage', () => { - it('works with custom stagingDir', async () => { - await rokuDeploy.createPackage({ - files: [ - 'manifest' - ], - stagingDir: '.tmp/dist', - outDir: outDir, - rootDir: rootDir - }); - expectPathExists(rokuDeploy.getOutputZipFilePath({ outDir: outDir })); - }); - - it('should throw error when no files were found to copy', async () => { - await assertThrowsAsync(async () => { - await rokuDeploy.createPackage({ - files: [], - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir - }); - }); - }); - - it('should create package in proper directory', async () => { - await rokuDeploy.createPackage({ - files: [ - 'manifest' - ], - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir - }); - expectPathExists(rokuDeploy.getOutputZipFilePath({ outDir: outDir })); - }); - - it('should only include the specified files', async () => { - await rokuDeploy.createPackage({ - files: [ - 'manifest' - ], - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir - }); - const data = fsExtra.readFileSync(rokuDeploy.getOutputZipFilePath({ outDir: outDir })); - const zip = await JSZip.loadAsync(data); - - const files = ['manifest']; - for (const file of files) { - const zipFileContents = await zip.file(file.toString()).async('string'); - const sourcePath = path.join(options.rootDir, file); - const incomingContents = fsExtra.readFileSync(sourcePath, 'utf8'); - expect(zipFileContents).to.equal(incomingContents); - } - }); - - it('generates full package with defaults', async () => { - const filePaths = writeFiles(rootDir, [ - 'components/components/Loader/Loader.brs', - 'images/splash_hd.jpg', - 'source/main.brs', - 'manifest' - ]); - await rokuDeploy.createPackage({ - files: filePaths, - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir - }); - - const data = fsExtra.readFileSync(rokuDeploy.getOutputZipFilePath({ outDir: outDir })); - const zip = await JSZip.loadAsync(data); - - for (const file of filePaths) { - const zipFileContents = await zip.file(file.toString())?.async('string'); - const sourcePath = path.join(options.rootDir, file); - const incomingContents = fsExtra.readFileSync(sourcePath, 'utf8'); - expect(zipFileContents).to.equal(incomingContents); - } - }); - - it('should retain the staging directory when told to', async () => { - let stagingDirValue = await rokuDeploy.stage({ - files: [ - 'manifest' - ], - stagingDir: stagingDir, - rootDir: rootDir - }); - expectPathExists(stagingDirValue); - await rokuDeploy.zip({ - stagingDir: stagingDir, - retainStagingDir: true, - outDir: outDir - }); - expectPathExists(stagingDirValue); - }); - - it('should call our callback with correct information', async () => { - fsExtra.outputFileSync(`${rootDir}/manifest`, 'major_version=1'); - - let spy = sinon.spy((info: BeforeZipCallbackInfo) => { - expectPathExists(info.stagingDir); - expect(info.manifestData.major_version).to.equal('1'); - }); - - await rokuDeploy.createPackage({ - files: [ - 'manifest' - ], - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir - }, spy); - - if (spy.notCalled) { - assert.fail('Callback not called'); - } - }); - - it('should wait for promise returned by pre-zip callback', async () => { - fsExtra.outputFileSync(`${rootDir}/manifest`, ''); - let count = 0; - await rokuDeploy.createPackage({ - files: [ - 'manifest' - ], - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir - }, (info) => { - return Promise.resolve().then(() => { - count++; - }).then(() => { - count++; - }); - }); - expect(count).to.equal(2); - }); - - it('should increment the build number if requested', async () => { - fsExtra.outputFileSync(`${rootDir}/manifest`, `build_version=0`); - //make the zipping immediately resolve - sinon.stub(rokuDeploy, 'zipPackage').returns(Promise.resolve()); - let beforeZipInfo: BeforeZipCallbackInfo; - await rokuDeploy.createPackage({ - files: [ - 'manifest' - ], - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir, - incrementBuildNumber: true - }, (info) => { - beforeZipInfo = info; - }); - expect(beforeZipInfo.manifestData.build_version).to.not.equal('0'); - }); - - it('should not increment the build number if not requested', async () => { - fsExtra.outputFileSync(`${rootDir}/manifest`, `build_version=0`); - await rokuDeploy.createPackage({ - files: [ - 'manifest' - ], - stagingDir: stagingDir, - outDir: outDir, - rootDir: rootDir, - incrementBuildNumber: false - }, (info) => { - expect(info.manifestData.build_version).to.equal('0'); - }); - }); - }); - it('runs via the command line using the rokudeploy.json file', function test() { this.timeout(20000); //build the project diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 0105fde..bb3f959 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import * as fsExtra from 'fs-extra'; //TODO: This was removed in Bronley commit. How to fix errors? +import * as fsExtra from 'fs-extra'; import type { WriteStream, ReadStream } from 'fs-extra'; import * as r from 'postman-request'; import type * as requestType from 'request'; @@ -640,34 +640,6 @@ export class RokuDeploy { */ private __getOptions(options: RokuDeployOptions = {}) { let fileOptions: RokuDeployOptions = {}; - const fileNames = ['rokudeploy.json', 'bsconfig.json']; - if (options.project) { - fileNames.unshift(options.project); - } - - for (const fileName of fileNames) { - if (fsExtra.existsSync(fileName)) { - let configFileText = fsExtra.readFileSync(fileName).toString(); - let parseErrors = [] as ParseError[]; - fileOptions = parseJsonc(configFileText, parseErrors, { - allowEmptyContent: true, - allowTrailingComma: true, - disallowComments: false - }); - if (parseErrors.length > 0) { - throw new Error(`Error parsing "${path.resolve(fileName)}": ` + JSON.stringify( - parseErrors.map(x => { - return { - message: printParseErrorCode(x.error), - offset: x.offset, - length: x.length - }; - }) - )); - } - break; - } - } let defaultOptions = { outDir: './out', @@ -997,15 +969,6 @@ export interface ZipPackageOptions { outDir?: string; } -export interface CreatePackageOptions { - rootDir?: string; - files?: FileEntry[]; - stagingDir?: string; - retainStagingDir?: boolean; - outDir?: string; - incrementBuildNumber?: boolean; -} - export interface PublishOptions { host: string; password: string; diff --git a/src/cli.ts b/src/cli.ts index 72da67b..8be0fba 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,8 +1,10 @@ #!/usr/bin/env node import * as yargs from 'yargs'; +import { rokuDeploy } from './index'; +import { ExecCommand } from './commands/ExecCommand'; +import { TextCommand } from './commands/TextCommand'; import { PrepublishCommand } from './commands/PrepublishCommand'; import { ZipPackageCommand } from './commands/ZipPackageCommand'; -import { CreatePackageCommand } from './commands/CreatePackageCommand'; import { PublishCommand } from './commands/PublishCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; @@ -19,52 +21,71 @@ import { ZipFolderCommand } from './commands/ZipFolderCommand'; void yargs - //not exposed - // .command('stage') - // .command('zip') - // .command('closeChannel') - // .command('sideload') - // .command('convertToSquashfs') //alias: squash - // .command('rekeyDevice') //alias: rekey - // .command('createSignedPackage') //alias: sign - // .command('deleteDevChannel') // alias: rmdev deldev + .command('bundle', 'execute build actions for bundling app', (builder) => { + return builder + .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + }, (args: any) => { + return new ExecCommand( + 'stage|zip', + args.configPath + ).run(); + }) + + .command('deploy', 'execute build actions for deploying app', (builder) => { + return builder + .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + }, (args: any) => { + return new ExecCommand( + 'stage|zip|delete|close|sideload', + args.configPath + ).run(); + }) - .command('keypress') - .command('keyup') - .command('keydown') - .command('text') //alias: sendText - .command('screenshot') // alias: captureScreenshot - .command('deviceinfo') // alias: getDeviceInfo - .command('devid') // alias: getDevId + .command('package', 'execute build actions for packaging app', (builder) => { + return builder + .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + }, (args: any) => { + return new ExecCommand( + 'close|rekey|stage|zip|delete|close|sideload|squash|sign', + args.configPath + ).run(); + }) - //bundle - .command('bundle', ()=>{ - const command = new ExecCommand({ - actions: 'stage|zip' - }) + .command('exec', 'larger command for handling a series of smaller commands', (builder) => { + return builder + .option('actions', { type: 'string', description: 'The actions to be executed, separated by |', demandOption: true }) + .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + }, (args: any) => { + return new ExecCommand(args.actions, args.configPath).run(); }) - //deploy - .command('deploy', ()=>{ - const command = new ExecCommand({ - actions: 'stage|zip|delete|close|sideload' - }) + .command(['sendText', 'text'], 'Send text command', (builder) => { + return builder + .option('text', { type: 'string', description: 'The text to send', demandOption: true }); + }, (args: any) => { + return new TextCommand().run(args); //TODO: do this through exec command to get default args like host and port? or add those to here and go through separate command for better testing }) - //package - .command('package', ()=>{ - const command = new ExecCommand({ - actions: 'close|rekey|stage|zip|delete|close|sideload|squash|sign' - }) + .command('keypress', 'send keypress command', (builder) => { + return builder + .option('key', { type: 'string', description: 'The key to send', demandOption: true }); + }, async (args: any) => { + await rokuDeploy.keyPress(args.text); //TODO: Go through exec command, separate command, or use key event? }) - //exec - .command('exec', ()=>{ - const command = new ExecCommand({ - actions: builder.args.actions - }) + .command('keyup', 'send keyup command', (builder) => { + return builder + .option('key', { type: 'string', description: 'The key to send', demandOption: true }); + }, async (args: any) => { + await rokuDeploy.keyUp(args.text); //TODO: Go through exec command, separate command, or use key event? }) + .command('keydown', 'send keydown command', (builder) => { + return builder + .option('key', { type: 'string', description: 'The key to send', demandOption: true }); + }, async (args: any) => { + await rokuDeploy.keyDown(args.text); //TODO: Go through exec command, separate command, or use key event? + }) .command(['stage', 'prepublishToStaging'], 'Copies all of the referenced files to the staging folder', (builder) => { return builder @@ -74,7 +95,7 @@ void yargs return new PrepublishCommand().run(args); }) - .command('zip', 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { + .command(['zip', 'zipPackage'], 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { return builder .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); @@ -82,15 +103,6 @@ void yargs return new ZipPackageCommand().run(args); }) - .command('createPackage', 'Create a zip folder containing all of the specified roku project files', (builder) => { - return builder - .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) - .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); - }, (args: any) => { - return new CreatePackageCommand().run(args); - }) - .command('publish', 'Publish a pre-existing packaged zip file to a remote Roku', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) @@ -101,7 +113,7 @@ void yargs return new PublishCommand().run(args); }) - .command('convertToSquashfs', 'Convert a pre-existing packaged zip file to a squashfs file', (builder) => { + .command(['squash', 'convertToSquashfs'], 'Convert a pre-existing packaged zip file to a squashfs file', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); @@ -109,7 +121,7 @@ void yargs return new ConvertToSquashfsCommand().run(args); }) - .command('rekeyDevice', 'Rekey a device', (builder) => { + .command(['rekey', 'rekeyDevice'], 'Rekey a device', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) @@ -121,7 +133,7 @@ void yargs return new RekeyDeviceCommand().run(args); }) - .command('signExistingPackage', 'Sign a package', (builder) => { + .command('createSignedPackage', 'Sign a package', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) @@ -149,7 +161,7 @@ void yargs return new DeployCommand().run(args); }) - .command('deleteInstalledChannel', 'Delete an installed channel', (builder) => { + .command(['deleteDevChannel', 'deleteInstalledChannel', 'rmdev', 'delete'], 'Delete an installed channel', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); @@ -157,12 +169,12 @@ void yargs return new DeleteInstalledChannelCommand().run(args); }) - .command('takeScreenshot', 'Take a screenshot', (builder) => { + .command(['screenshot', 'captureScreenshot'], 'Take a screenshot', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); }, (args: any) => { - return new TakeScreenshotCommand().run(args); + return new TakeScreenshotCommand().run(args);//TODO: rename }) .command('getOutputZipFilePath', 'Centralizes getting output zip file path based on passed in options', (builder) => { @@ -182,14 +194,14 @@ void yargs return new GetOutputPkgFilePathCommand().run(args); }) - .command('getDeviceInfo', 'Get the `device-info` response from a Roku device', (builder) => { + .command(['getDeviceInfo', 'deviceinfo'], 'Get the `device-info` response from a Roku device', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }); }, (args: any) => { return new GetDeviceInfoCommand().run(args); }) - .command('getDevId', 'Get Dev ID', (builder) => { + .command(['getDevId', 'devid'], 'Get Dev ID', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }); }, (args: any) => { diff --git a/src/commands/CreatePackageCommand.ts b/src/commands/CreatePackageCommand.ts deleted file mode 100644 index f4b4718..0000000 --- a/src/commands/CreatePackageCommand.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { rokuDeploy } from '../index'; - -export class CreatePackageCommand { - async run(args) { - await rokuDeploy.createPackage({ - stagingDir: args.stagingDir, - outDir: args.outDir, - rootDir: args.rootDir - }); - } -} diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts index a0405c7..bf4cfc3 100644 --- a/src/commands/ExecCommand.ts +++ b/src/commands/ExecCommand.ts @@ -1,21 +1,66 @@ +import { rokuDeploy } from '../index'; +import { cwd } from '../testUtils.spec'; +import { util } from '../util'; + export class ExecCommand { - constructor(options: {actions: string, configPath: string, ...rokuDeployOptions }){ - this.actions = options.actions.split('|'); + private actions: string[]; + + private configPath: string; + + // eslint-disable-next-line @typescript-eslint/ban-types + private options: {}; + + constructor(actions: string, configPath: string, ...rokuDeployOptions) { + this.actions = actions.split('|'); + this.configPath = configPath; + this.options = rokuDeployOptions; } - run() { + async run() { //load options from json - const options = { - ...getFromJson(this.configPath ?? `${cwd}/rokudeploy.json`), - this.options - }; - - if(this.actions.includes('stage')){ - rokuDeploy.stage(); + this.options = util.getOptionsFromJson(this.options); + + // Possibilities: + // 'stage|zip' + // 'stage|zip|delete|close|sideload' + // 'close|rekey|stage|zip|delete|close|sideload|squash|sign' + + if (this.actions.includes('stage')) { + await rokuDeploy.stage(this.options); + } + + if (this.actions.includes('zip')) { + await rokuDeploy.zip(this.options); + } + + if (this.actions.includes('delete')) { + await rokuDeploy.deleteDevChannel(this.options); + } + + if (this.actions.includes('close')) { + await rokuDeploy.closeChannel(this.options); + } + + if (this.actions.includes('sideload')) { + await rokuDeploy.sideload(this.options); } - if(this.actions.includes('zip')){ - rokuDeploy.zip(); + if (this.actions.includes('stage')) { + await rokuDeploy.stage(this.options); } + + if (this.actions.includes('rekey')) { + await rokuDeploy.rekeyDevice(this.options); + } + + if (this.actions.includes('squash')) { + await rokuDeploy.convertToSquashfs(this.options); + } + + if (this.actions.includes('sign')) { + await rokuDeploy.createSignedPackage(this.options); + } + + } -} \ No newline at end of file +} diff --git a/src/commands/TextCommand.ts b/src/commands/TextCommand.ts new file mode 100644 index 0000000..5408ef8 --- /dev/null +++ b/src/commands/TextCommand.ts @@ -0,0 +1,8 @@ +import { rokuDeploy } from '../index'; + +export class TextCommand { + // this.options = getDefaultArgsFromJson(this.configPath ?? `${cwd}/rokudeploy.json`);TODO + async run(args) { + await rokuDeploy.sendText(args.text); + } +} diff --git a/src/util.ts b/src/util.ts index c1d648f..e807ff4 100644 --- a/src/util.ts +++ b/src/util.ts @@ -483,6 +483,25 @@ export class Util { return table.join('\n'); } + /** + * A function to fill in any missing arguments with JSON values + */ + public getOptionsFromJson(defaultArgs) { //TODO: create a test for this in cli.spec.ts too + let args = { ...defaultArgs }; + const fileNames = ['rokudeploy.json', 'bsconfig.json']; + + for (const fileName of fileNames) { + if (fsExtra.existsSync(fileName)) { + let rokudeployArgs = JSON.parse(fs.readFileSync('rokudeploy.json', 'utf-8')); + // args = Object.assign(rokudeployArgs ?? {}, args); + args = Object.assign(rokudeployArgs, args); + break; + } + } + + return args; + } + } export let util = new Util(); From 46fe1293f81317105fb6e1d70199116195a06a5c Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 22 Feb 2024 14:32:37 -0500 Subject: [PATCH 26/93] Adding cli tests --- src/cli.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 4cf25f3..71d486b 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -39,6 +39,11 @@ describe('cli', () => { sinon.restore(); }); + it('Successfully bundles an app', () => { + execSync(`node ${cwd}/dist/cli.js bundle --rootDir ${rootDir} --outDir ${outDir}`); + expectPathExists(`${outDir}/roku-deploy.zip`); + }); + it('Successfully runs prepublishToStaging', () => { //make the files fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); @@ -63,11 +68,6 @@ describe('cli', () => { expectPathExists(`${outDir}/roku-deploy.zip`); }); - it('Successfully uses createPackage to create .pkg', () => { - execSync(`node ${cwd}/dist/cli.js createPackage --stagingDir ${stagingDir} --rootDir ${rootDir} --outDir ${outDir}`); - expectPathExists(`${outDir}/roku-deploy.zip`); - }); - it('Publish passes proper options', async () => { const stub = sinon.stub(rokuDeploy, 'publish').callsFake(async () => { return Promise.resolve({ From 36502e18e849be5e25a71bb7cc8194b41082c3e2 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 22 Feb 2024 14:33:12 -0500 Subject: [PATCH 27/93] Delete deployAndSignPackage tests, a deleted function in rokudeploy --- src/RokuDeploy.spec.ts | 89 ------------------------------------------ 1 file changed, 89 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 93da38c..c9447b7 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3597,95 +3597,6 @@ describe('index', () => { expect(getToFileIsResolved).to.be.true; }); }); - - describe('deployAndSignPackage', () => { - beforeEach(() => { - //pretend the deploy worked - sinon.stub(rokuDeploy, 'deploy').returns(Promise.resolve(null)); - //pretend the sign worked - sinon.stub(rokuDeploy, 'signExistingPackage').returns(Promise.resolve(null)); - //pretend fetching the signed package worked - sinon.stub(rokuDeploy, 'retrieveSignedPackage').returns(Promise.resolve('some_local_path')); - }); - - it('succeeds and does proper things with staging folder', async () => { - let stub = sinon.stub(rokuDeploy['fsExtra'], 'remove').returns(Promise.resolve() as any); - - //this should not fail - let pkgFilePath = await rokuDeploy.deployAndSignPackage({ - host: '1.2.3.4', - password: 'password', - signingPassword: 'secret', - retainStagingDir: false - }); - - //the return value should equal what retrieveSignedPackage returned. - expect(pkgFilePath).to.equal('some_local_path'); - - //fsExtra.remove should have been called - expect(stub.getCalls()).to.be.lengthOf(1); - - //call it again, but specify true for retainStagingDir - await rokuDeploy.deployAndSignPackage({ - host: '1.2.3.4', - password: 'password', - signingPassword: 'secret', - retainStagingDir: true - }); - //call count should NOT increase - expect(stub.getCalls()).to.be.lengthOf(1); - - //call it again, but don't specify retainStagingDir at all (it should default to FALSE) - await rokuDeploy.deployAndSignPackage({ - host: '1.2.3.4', - password: 'password', - signingPassword: 'secret' - }); - //call count should NOT increase - expect(stub.getCalls()).to.be.lengthOf(2); - }); - - it('converts to squashfs if we request it to', async () => { - // options.convertToSquashfs = true; - let stub = sinon.stub(rokuDeploy, 'convertToSquashfs').returns(Promise.resolve(null)); - await rokuDeploy.deployAndSignPackage({ - host: '1.2.3.4', - password: 'password', - signingPassword: 'secret', - convertToSquashfs: true - }); - expect(stub.getCalls()).to.be.lengthOf(1); - }); - }); - - function mockDoGetRequest(body = '', statusCode = 200) { - return sinon.stub(rokuDeploy as any, 'doGetRequest').callsFake((params) => { - let results = { response: { statusCode: statusCode }, body: body }; - rokuDeploy['checkRequest'](results); - return Promise.resolve(results); - }); - } - - function mockDoPostRequest(body = '', statusCode = 200) { - return sinon.stub(rokuDeploy as any, 'doPostRequest').callsFake((params) => { - let results = { response: { statusCode: statusCode }, body: body }; - rokuDeploy['checkRequest'](results); - return Promise.resolve(results); - }); - } - - async function assertThrowsAsync(fn) { - let f = () => { }; - try { - await fn(); - } catch (e) { - f = () => { - throw e; - }; - } finally { - assert.throws(f); - } - } }); function getFakeResponseBody(messages: string): string { From c058dd6455ffe3c23f9c82197d59c23c01593861 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 22 Feb 2024 14:33:57 -0500 Subject: [PATCH 28/93] Add defaultsFromJson tests --- src/util.spec.ts | 52 +++++++++++++++++++++++++++++++++++++++++++++++- src/util.ts | 5 +++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/util.spec.ts b/src/util.spec.ts index f58c18c..eeb4726 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -1,7 +1,7 @@ import { util, standardizePath as s } from './util'; import { expect } from 'chai'; import * as fsExtra from 'fs-extra'; -import { tempDir } from './testUtils.spec'; +import { tempDir, rootDir } from './testUtils.spec'; import * as path from 'path'; import * as dns from 'dns'; import { createSandbox } from 'sinon'; @@ -14,6 +14,7 @@ describe('util', () => { }); afterEach(() => { + fsExtra.emptyDirSync(tempDir); sinon.restore(); }); @@ -334,4 +335,53 @@ describe('util', () => { expect(result).to.eql(expectedOutput); }); }); + + describe('getOptionsFromJson', () => { + beforeEach(() => { + fsExtra.ensureDirSync(rootDir); + process.chdir(rootDir); + }); + it('should fill in missing options from rokudeploy.json', () => { + fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { password: 'password' }); + let options = util.getOptionsFromJson({ + rootDir: `${rootDir}`, + host: '1.2.3.4' + }); + let expectedOutput = { + rootDir: `${rootDir}`, + host: '1.2.3.4', + password: 'password' + }; + expect(options).to.eql(expectedOutput); + }); + + it('should fill in missing default options from bsconfig.json', () => { + fsExtra.writeJsonSync(s`${rootDir}/bsconfig.json`, { password: 'password' }); + let options = util.getOptionsFromJson({ + rootDir: `${rootDir}`, + host: '1.2.3.4' + }); + let expectedOutput = { + rootDir: `${rootDir}`, + host: '1.2.3.4', + password: 'password' + }; + expect(options).to.eql(expectedOutput); + + }); + + it('should not replace default options', () => { + fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { host: '4.3.2.1' }); + let options = util.getOptionsFromJson({ + rootDir: `${rootDir}`, + host: '1.2.3.4' + }); + let expectedOutput = { + rootDir: `${rootDir}`, + host: '1.2.3.4', + }; + expect(options).to.eql(expectedOutput); + + }); + }); }); diff --git a/src/util.ts b/src/util.ts index e807ff4..9fd883b 100644 --- a/src/util.ts +++ b/src/util.ts @@ -492,9 +492,10 @@ export class Util { for (const fileName of fileNames) { if (fsExtra.existsSync(fileName)) { - let rokudeployArgs = JSON.parse(fs.readFileSync('rokudeploy.json', 'utf-8')); + const sourcePath = path.join(defaultArgs.rootDir, fileName); + const rokuDeployArgs = JSON.parse(fsExtra.readFileSync(sourcePath, 'utf8')); // args = Object.assign(rokudeployArgs ?? {}, args); - args = Object.assign(rokudeployArgs, args); + args = Object.assign(rokuDeployArgs, args); break; } } From 5859f91d78d8103e77409f0aac94c259a63d9291 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 08:58:09 -0500 Subject: [PATCH 29/93] Move some tests to utils test file, re add other functions that might have been accidentally deleted, fix some errors with fsExtra --- src/RokuDeploy.spec.ts | 168 ++++++++++------------------------------- src/util.spec.ts | 117 +++++++++++++++++++++++++++- 2 files changed, 157 insertions(+), 128 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index c9447b7..99056a3 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -631,12 +631,12 @@ describe('index', () => { it('computes absolute path for all operations', async () => { const ensureDirPaths = []; - sinon.stub(rokuDeploy.fsExtra, 'ensureDir').callsFake((p) => { + sinon.stub(fsExtra, 'ensureDir').callsFake((p) => { ensureDirPaths.push(p); return Promise.resolve; }); const copyPaths = [] as Array<{ src: string; dest: string }>; - sinon.stub(rokuDeploy.fsExtra as any, 'copy').callsFake((src, dest) => { + sinon.stub(fsExtra as any, 'copy').callsFake((src, dest) => { copyPaths.push({ src: src as string, dest: dest as string }); return Promise.resolve(); }); @@ -828,10 +828,10 @@ describe('index', () => { }); it('failure to close read stream does not crash', async () => { - const orig = rokuDeploy.fsExtra.createReadStream; + const orig = fsExtra.createReadStream; //wrap the stream.close call so we can throw - sinon.stub(rokuDeploy.fsExtra, 'createReadStream').callsFake((pathLike) => { - const stream = orig.call(rokuDeploy.fsExtra, pathLike); + sinon.stub(fsExtra, 'createReadStream').callsFake((pathLike) => { + const stream = orig.call(fsExtra, pathLike); const originalClose = stream.close; stream.close = () => { originalClose.call(stream); @@ -1810,17 +1810,17 @@ describe('index', () => { }); }); it('is resilient to file system errors', async () => { - let copy = rokuDeploy.fsExtra.copy; + let copy = fsExtra.copy; let count = 0; //mock writeFile so we can throw a few errors during the test - sinon.stub(rokuDeploy.fsExtra, 'copy').callsFake((...args) => { + sinon.stub(fsExtra, 'copy').callsFake((...args) => { count += 1; //fail a few times if (count < 5) { throw new Error('fake error thrown as part of the unit test'); } else { - return copy.apply(rokuDeploy.fsExtra, args); + return copy.apply(fsExtra, args); } }); @@ -1844,17 +1844,17 @@ describe('index', () => { }); it('throws underlying error after the max fs error threshold is reached', async () => { - let copy = rokuDeploy.fsExtra.copy; + let copy = fsExtra.copy; let count = 0; //mock writeFile so we can throw a few errors during the test - sinon.stub(rokuDeploy.fsExtra, 'copy').callsFake((...args) => { + sinon.stub(fsExtra, 'copy').callsFake((...args) => { count += 1; //fail a few times if (count < 15) { throw new Error('fake error thrown as part of the unit test'); } else { - return copy.apply(rokuDeploy.fsExtra, args); + return copy.apply(fsExtra, args); } }); @@ -3127,125 +3127,10 @@ describe('index', () => { }); }); - describe('getDestPath', () => { - it('handles unrelated exclusions properly', () => { - expect( - rokuDeploy.getDestPath( - s`${rootDir}/components/comp1/comp1.brs`, - [ - '**/*', - '!exclude.me' - ], - rootDir - ) - ).to.equal(s`components/comp1/comp1.brs`); - }); - - it('finds dest path for top-level path', () => { - expect( - rokuDeploy.getDestPath( - s`${rootDir}/components/comp1/comp1.brs`, - ['components/**/*'], - rootDir - ) - ).to.equal(s`components/comp1/comp1.brs`); - }); - - it('does not find dest path for non-matched top-level path', () => { - expect( - rokuDeploy.getDestPath( - s`${rootDir}/source/main.brs`, - ['components/**/*'], - rootDir - ) - ).to.be.undefined; - }); - - it('excludes a file that is negated', () => { - expect( - rokuDeploy.getDestPath( - s`${rootDir}/source/main.brs`, - [ - 'source/**/*', - '!source/main.brs' - ], - rootDir - ) - ).to.be.undefined; - }); - - it('excludes file from non-rootdir top-level pattern', () => { - expect( - rokuDeploy.getDestPath( - s`${rootDir}/../externalDir/source/main.brs`, - [ - '!../externalDir/**/*' - ], - rootDir - ) - ).to.be.undefined; - }); - - it('excludes a file that is negated in src;dest;', () => { - expect( - rokuDeploy.getDestPath( - s`${rootDir}/source/main.brs`, - [ - 'source/**/*', - { - src: '!source/main.brs' - } - ], - rootDir - ) - ).to.be.undefined; - }); - - it('works for brighterscript files', () => { - let destPath = rokuDeploy.getDestPath( - util.standardizePath(`${cwd}/src/source/main.bs`), - [ - 'manifest', - 'source/**/*.bs' - ], - s`${cwd}/src` - ); - expect(s`${destPath}`).to.equal(s`source/main.bs`); - }); - - it('excludes a file found outside the root dir', () => { - expect( - rokuDeploy.getDestPath( - s`${rootDir}/../source/main.brs`, - [ - '../source/**/*' - ], - rootDir - ) - ).to.be.undefined; - }); - }); - - describe('normalizeRootDir', () => { - it('handles falsey values', () => { - expect(rokuDeploy.normalizeRootDir(null)).to.equal(cwd); - expect(rokuDeploy.normalizeRootDir(undefined)).to.equal(cwd); - expect(rokuDeploy.normalizeRootDir('')).to.equal(cwd); - expect(rokuDeploy.normalizeRootDir(' ')).to.equal(cwd); - expect(rokuDeploy.normalizeRootDir('\t')).to.equal(cwd); - }); - - it('handles non-falsey values', () => { - expect(rokuDeploy.normalizeRootDir(cwd)).to.equal(cwd); - expect(rokuDeploy.normalizeRootDir('./')).to.equal(cwd); - expect(rokuDeploy.normalizeRootDir('./testProject')).to.equal(path.join(cwd, 'testProject')); - }); - }); - describe('retrieveSignedPackage', () => { let onHandler: any; beforeEach(() => { - sinon.stub(rokuDeploy.fsExtra, 'ensureDir').callsFake(((pth: string, callback: (err: Error) => void) => { + sinon.stub(fsExtra, 'ensureDir').callsFake(((pth: string, callback: (err: Error) => void) => { //do nothing, assume the dir gets created }) as any); @@ -3597,6 +3482,35 @@ describe('index', () => { expect(getToFileIsResolved).to.be.true; }); }); + + function mockDoGetRequest(body = '', statusCode = 200) { + return sinon.stub(rokuDeploy as any, 'doGetRequest').callsFake((params) => { + let results = { response: { statusCode: statusCode }, body: body }; + rokuDeploy['checkRequest'](results); + return Promise.resolve(results); + }); + } + + function mockDoPostRequest(body = '', statusCode = 200) { + return sinon.stub(rokuDeploy as any, 'doPostRequest').callsFake((params) => { + let results = { response: { statusCode: statusCode }, body: body }; + rokuDeploy['checkRequest'](results); + return Promise.resolve(results); + }); + } + + async function assertThrowsAsync(fn) { + let f = () => { }; + try { + await fn(); + } catch (e) { + f = () => { + throw e; + }; + } finally { + assert.throws(f); + } + } }); function getFakeResponseBody(messages: string): string { diff --git a/src/util.spec.ts b/src/util.spec.ts index eeb4726..1705127 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -1,7 +1,7 @@ import { util, standardizePath as s } from './util'; import { expect } from 'chai'; import * as fsExtra from 'fs-extra'; -import { tempDir, rootDir } from './testUtils.spec'; +import { cwd, tempDir, rootDir } from './testUtils.spec'; import * as path from 'path'; import * as dns from 'dns'; import { createSandbox } from 'sinon'; @@ -336,6 +336,121 @@ describe('util', () => { }); }); + describe('normalizeRootDir', () => { + it('handles falsey values', () => { + expect(util.normalizeRootDir(null)).to.equal(cwd); + expect(util.normalizeRootDir(undefined)).to.equal(cwd); + expect(util.normalizeRootDir('')).to.equal(cwd); + expect(util.normalizeRootDir(' ')).to.equal(cwd); + expect(util.normalizeRootDir('\t')).to.equal(cwd); + }); + + it('handles non-falsey values', () => { + expect(util.normalizeRootDir(cwd)).to.equal(cwd); + expect(util.normalizeRootDir('./')).to.equal(cwd); + expect(util.normalizeRootDir('./testProject')).to.equal(path.join(cwd, 'testProject')); + }); + }); + + describe('getDestPath', () => { + it('handles unrelated exclusions properly', () => { + expect( + util.getDestPath( + s`${rootDir}/components/comp1/comp1.brs`, + [ + '**/*', + '!exclude.me' + ], + rootDir + ) + ).to.equal(s`components/comp1/comp1.brs`); + }); + + it('finds dest path for top-level path', () => { + expect( + util.getDestPath( + s`${rootDir}/components/comp1/comp1.brs`, + ['components/**/*'], + rootDir + ) + ).to.equal(s`components/comp1/comp1.brs`); + }); + + it('does not find dest path for non-matched top-level path', () => { + expect( + util.getDestPath( + s`${rootDir}/source/main.brs`, + ['components/**/*'], + rootDir + ) + ).to.be.undefined; + }); + + it('excludes a file that is negated', () => { + expect( + util.getDestPath( + s`${rootDir}/source/main.brs`, + [ + 'source/**/*', + '!source/main.brs' + ], + rootDir + ) + ).to.be.undefined; + }); + + it('excludes file from non-rootdir top-level pattern', () => { + expect( + util.getDestPath( + s`${rootDir}/../externalDir/source/main.brs`, + [ + '!../externalDir/**/*' + ], + rootDir + ) + ).to.be.undefined; + }); + + it('excludes a file that is negated in src;dest;', () => { + expect( + util.getDestPath( + s`${rootDir}/source/main.brs`, + [ + 'source/**/*', + { + src: '!source/main.brs' + } + ], + rootDir + ) + ).to.be.undefined; + }); + + it('works for brighterscript files', () => { + let destPath = util.getDestPath( + util.standardizePath(`${cwd}/src/source/main.bs`), + [ + 'manifest', + 'source/**/*.bs' + ], + s`${cwd}/src` + ); + expect(s`${destPath}`).to.equal(s`source/main.bs`); + }); + + it('excludes a file found outside the root dir', () => { + expect( + util.getDestPath( + s`${rootDir}/../source/main.brs`, + [ + '../source/**/*' + ], + rootDir + ) + ).to.be.undefined; + }); + }); + describe('getOptionsFromJson', () => { beforeEach(() => { fsExtra.ensureDirSync(rootDir); From 8ae9acec4e28214fb84021e567d801c027b5296f Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 09:45:36 -0500 Subject: [PATCH 30/93] Change signExistingPackage to CreateSignedPackage --- src/RokuDeploy.spec.ts | 14 +++++++------- src/RokuDeploy.ts | 2 +- src/cli.spec.ts | 6 +++--- src/cli.ts | 4 ++-- ...ageCommand.ts => CreateSignedPackageCommand.ts} | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) rename src/commands/{SignExistingPackageCommand.ts => CreateSignedPackageCommand.ts} (72%) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 99056a3..b0ccc07 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -1338,14 +1338,14 @@ describe('index', () => { }); }); - describe('signExistingPackage', () => { + describe('createSignedPackage', () => { beforeEach(() => { fsExtra.outputFileSync(`${stagingDir}/manifest`, ``); }); it('should return our error if signingPassword is not supplied', async () => { await expectThrowsAsync(async () => { - await rokuDeploy.signPackage({ + await rokuDeploy.createSignedPackage({ host: '1.2.3.4', password: 'password', signingPassword: undefined, @@ -1362,7 +1362,7 @@ describe('index', () => { process.nextTick(callback, error); return {} as any; }); - await rokuDeploy.signPackage({ + await rokuDeploy.createSignedPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1378,7 +1378,7 @@ describe('index', () => { it('should return our error if it received invalid data', async () => { try { mockDoPostRequest(null); - await rokuDeploy.signPackage({ + await rokuDeploy.createSignedPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1399,7 +1399,7 @@ describe('index', () => { mockDoPostRequest(body); await expectThrowsAsync( - rokuDeploy.signPackage({ + rokuDeploy.createSignedPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1415,7 +1415,7 @@ describe('index', () => { node.appendChild(pkgDiv);`; mockDoPostRequest(body); - let pkgPath = await rokuDeploy.signPackage({ + let pkgPath = await rokuDeploy.createSignedPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, @@ -1427,7 +1427,7 @@ describe('index', () => { it('should return our fallback error if neither error or package link was detected', async () => { mockDoPostRequest(); await expectThrowsAsync( - rokuDeploy.signPackage({ + rokuDeploy.createSignedPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index bb3f959..62dc8be 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -1002,7 +1002,7 @@ export interface RekeyDeviceOptions { devId: string; } -export interface SignExistingPackageOptions { +export interface CreateSignedPackageOptions { host: string; password: string; signingPassword: string; diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 71d486b..f151a25 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -8,7 +8,7 @@ import { rokuDeploy } from './index'; import { PublishCommand } from './commands/PublishCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; -import { SignExistingPackageCommand } from './commands/SignExistingPackageCommand'; +import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; import { DeployCommand } from './commands/DeployCommand'; import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannelCommand'; import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; @@ -141,11 +141,11 @@ describe('cli', () => { }); it('Signs an existing package', async () => { - const stub = sinon.stub(rokuDeploy, 'signExistingPackage').callsFake(async () => { + const stub = sinon.stub(rokuDeploy, 'createSignedPackage').callsFake(async () => { return Promise.resolve(''); }); - const command = new SignExistingPackageCommand(); + const command = new CreateSignedPackageCommand(); await command.run({ host: '1.2.3.4', password: '5536', diff --git a/src/cli.ts b/src/cli.ts index 8be0fba..14aa9d8 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -8,7 +8,7 @@ import { ZipPackageCommand } from './commands/ZipPackageCommand'; import { PublishCommand } from './commands/PublishCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; -import { SignExistingPackageCommand } from './commands/SignExistingPackageCommand'; +import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; import { RetrieveSignedPackageCommand } from './commands/RetrieveSignedPackageCommand'; import { DeployCommand } from './commands/DeployCommand'; import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannelCommand'; @@ -140,7 +140,7 @@ void yargs .option('signingPassword', { type: 'string', description: 'The password of the signing key', demandOption: false }) .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }); }, (args: any) => { - return new SignExistingPackageCommand().run(args); + return new CreateSignedPackageCommand().run(args); }) .command('retrieveSignedPackage', 'Retrieve a signed package', (builder) => { diff --git a/src/commands/SignExistingPackageCommand.ts b/src/commands/CreateSignedPackageCommand.ts similarity index 72% rename from src/commands/SignExistingPackageCommand.ts rename to src/commands/CreateSignedPackageCommand.ts index 3b1175e..8488650 100644 --- a/src/commands/SignExistingPackageCommand.ts +++ b/src/commands/CreateSignedPackageCommand.ts @@ -1,8 +1,8 @@ import { rokuDeploy } from '../index'; -export class SignExistingPackageCommand { +export class CreateSignedPackageCommand { async run(args) { - await rokuDeploy.signPackage({ + await rokuDeploy.createSignedPackage({ host: args.host, password: args.password, signingPassword: args.signingPassword, From cc0f4b8e4aed1a3e7cc12789f8ef60108cfb1215 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 09:47:57 -0500 Subject: [PATCH 31/93] Delete retrieveSignedPackage --- src/RokuDeploy.spec.ts | 105 ----------------------------------------- src/cli.spec.ts | 23 --------- src/cli.ts | 10 ---- 3 files changed, 138 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index b0ccc07..0429510 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3127,111 +3127,6 @@ describe('index', () => { }); }); - describe('retrieveSignedPackage', () => { - let onHandler: any; - beforeEach(() => { - sinon.stub(fsExtra, 'ensureDir').callsFake(((pth: string, callback: (err: Error) => void) => { - //do nothing, assume the dir gets created - }) as any); - - //intercept the http request - sinon.stub(request, 'get').callsFake(() => { - let req: any = { - on: (event, callback) => { - process.nextTick(() => { - onHandler(event, callback); - }); - return req; - }, - pipe: async () => { - //if a write stream gets created, write some stuff and close it - const writeStream = await writeStreamPromise; - writeStream.write('test'); - writeStream.close(); - } - }; - return req; - }); - }); - - it('returns a pkg file path on success', async () => { - onHandler = (event, callback) => { - if (event === 'response') { - callback({ - statusCode: 200 - }); - } - }; - let pkgFilePath = await rokuDeploy.retrieveSignedPackage('path_to_pkg', { - host: '1.2.3.4', - outFile: 'roku-deploy-test', - password: 'aaaa' - }); - expect(pkgFilePath).to.equal(path.join(process.cwd(), 'out', 'roku-deploy-test.pkg')); - }); - - it('returns a pkg file path on success', async () => { - //the write stream should return null, which causes a specific branch to be executed - createWriteStreamStub.callsFake(() => { - return null; - }); - - onHandler = (event, callback) => { - if (event === 'response') { - callback({ - statusCode: 200 - }); - } - }; - - let error: Error; - try { - await rokuDeploy.retrieveSignedPackage('path_to_pkg', { - host: '1.2.3.4', - password: 'password', - outFile: 'roku-deploy-test' - }); - } catch (e) { - error = e as any; - } - expect(error.message.startsWith('Unable to create write stream for')).to.be.true; - }); - - it('throws when error in request is encountered', async () => { - onHandler = (event, callback) => { - if (event === 'error') { - callback(new Error('Some error')); - } - }; - await expectThrowsAsync( - rokuDeploy.retrieveSignedPackage('path_to_pkg', { - host: '1.2.3.4', - outFile: 'roku-deploy-test', - password: 'aaaa' - }), - 'Some error' - ); - }); - - it('throws when status code is non 200', async () => { - onHandler = (event, callback) => { - if (event === 'response') { - callback({ - statusCode: 500 - }); - } - }; - await expectThrowsAsync( - rokuDeploy.retrieveSignedPackage('path_to_pkg', { - host: '1.2.3.4', - outFile: 'roku-deploy-test', - password: 'aaaa' - }), - 'Invalid response code: 500' - ); - }); - }); - describe('checkRequest', () => { it('throws FailedDeviceResponseError when necessary', () => { sinon.stub(rokuDeploy as any, 'getRokuMessagesFromResponseBody').returns({ diff --git a/src/cli.spec.ts b/src/cli.spec.ts index f151a25..eaaf1fc 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -14,7 +14,6 @@ import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannel import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; -import { RetrieveSignedPackageCommand } from './commands/RetrieveSignedPackageCommand'; const sinon = createSandbox(); @@ -163,28 +162,6 @@ describe('cli', () => { }); }); - it('Retrieves a signed package', async () => { - const stub = sinon.stub(rokuDeploy, 'retrieveSignedPackage').callsFake(async () => { - return Promise.resolve(''); - }); - - const command = new RetrieveSignedPackageCommand(); - await command.run({ - pathToPkg: 'path_to_pkg', - host: '1.2.3.4', - password: '5536', - outFile: 'roku-deploy-test' - }); - - expect( - stub.getCall(0).args - ).to.eql(['path_to_pkg', { - host: '1.2.3.4', - password: '5536', - outFile: 'roku-deploy-test' - }]); - }); - it('Deploys a package', async () => { const stub = sinon.stub(rokuDeploy, 'deploy').callsFake(async () => { return Promise.resolve({ diff --git a/src/cli.ts b/src/cli.ts index 14aa9d8..16cfe0a 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -9,7 +9,6 @@ import { PublishCommand } from './commands/PublishCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; -import { RetrieveSignedPackageCommand } from './commands/RetrieveSignedPackageCommand'; import { DeployCommand } from './commands/DeployCommand'; import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannelCommand'; import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; @@ -143,15 +142,6 @@ void yargs return new CreateSignedPackageCommand().run(args); }) - .command('retrieveSignedPackage', 'Retrieve a signed package', (builder) => { - return builder - .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) - .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) - .option('outFile', { type: 'string', description: 'The output file', demandOption: false }); - }, (args: any) => { - return new RetrieveSignedPackageCommand().run(args); - }) - .command('deploy', 'Deploy a pre-existing packaged zip file to a remote Roku', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) From cbfcaed14325c5ee0779c1850abdb277ffb18fb8 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 09:50:13 -0500 Subject: [PATCH 32/93] Move getFilePaths --- src/RokuDeploy.spec.ts | 650 +------------------ src/commands/RetrieveSignedPackageCommand.ts | 11 - src/util.spec.ts | 650 ++++++++++++++++++- src/util.ts | 4 +- 4 files changed, 654 insertions(+), 661 deletions(-) delete mode 100644 src/commands/RetrieveSignedPackageCommand.ts diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 0429510..38ec4f5 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -12,7 +12,7 @@ import type { BeforeZipCallbackInfo } from './RokuDeploy'; import { RokuDeploy } from './RokuDeploy'; import * as errors from './Errors'; import { util, standardizePath as s, standardizePathPosix as sp } from './util'; -import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; +import type { RokuDeployOptions } from './RokuDeployOptions'; import { cwd, expectPathExists, expectPathNotExists, expectThrowsAsync, outDir, rootDir, stagingDir, tempDir, writeFiles } from './testUtils.spec'; import { createSandbox } from 'sinon'; import * as r from 'postman-request'; @@ -641,7 +641,7 @@ describe('index', () => { return Promise.resolve(); }); - sinon.stub(rokuDeploy, 'getFilePaths').returns( + sinon.stub(util, 'getFilePaths').returns( Promise.resolve([ { src: s`${rootDir}/source/main.brs`, @@ -1742,7 +1742,7 @@ describe('index', () => { let stagingDirValue = rokuDeploy.getOptions(opts).stagingDir; //getFilePaths detects the file - expect(await rokuDeploy.getFilePaths(['renamed_test.md'], opts.rootDir)).to.eql([{ + expect(await util.getFilePaths(['renamed_test.md'], opts.rootDir)).to.eql([{ src: s`${opts.rootDir}/renamed_test.md`, dest: s`renamed_test.md` }]); @@ -1787,7 +1787,7 @@ describe('index', () => { let stagingPath = rokuDeploy.getOptions(opts).stagingDir; //getFilePaths detects the file expect( - (await rokuDeploy.getFilePaths(opts.files, opts.rootDir)).sort((a, b) => a.src.localeCompare(b.src)) + (await util.getFilePaths(opts.files, opts.rootDir)).sort((a, b) => a.src.localeCompare(b.src)) ).to.eql([{ src: s`${tempDir}/mainProject/source/lib/lib.brs`, dest: s`source/lib/lib.brs` @@ -2477,648 +2477,6 @@ describe('index', () => { }); }); - describe('getFilePaths', () => { - const otherProjectName = 'otherProject'; - const otherProjectDir = sp`${rootDir}/../${otherProjectName}`; - //create baseline project structure - beforeEach(() => { - fsExtra.ensureDirSync(`${rootDir}/components/emptyFolder`); - writeFiles(rootDir, [ - `manifest`, - `source/main.brs`, - `source/lib.brs`, - `components/component1.xml`, - `components/component1.brs`, - `components/screen1/screen1.xml`, - `components/screen1/screen1.brs` - ]); - }); - - async function getFilePaths(files: FileEntry[], rootDirOverride = rootDir) { - return (await rokuDeploy.getFilePaths(files, rootDirOverride)) - .sort((a, b) => a.src.localeCompare(b.src)); - } - - describe('top-level-patterns', () => { - it('excludes a file that is negated', async () => { - expect(await getFilePaths([ - 'source/**/*', - '!source/main.brs' - ])).to.eql([{ - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }]); - }); - - it('excludes file from non-rootdir top-level pattern', async () => { - writeFiles(rootDir, ['../externalDir/source/main.brs']); - expect(await getFilePaths([ - '../externalDir/**/*', - '!../externalDir/**/*' - ])).to.eql([]); - }); - - it('throws when using top-level string referencing file outside the root dir', async () => { - writeFiles(rootDir, [`../source/main.brs`]); - await expectThrowsAsync(async () => { - await getFilePaths([ - '../source/**/*' - ]); - }, 'Cannot reference a file outside of rootDir when using a top-level string. Please use a src;des; object instead'); - }); - - it('works for brighterscript files', async () => { - writeFiles(rootDir, ['src/source/main.bs']); - expect(await getFilePaths([ - 'manifest', - 'source/**/*.bs' - ], s`${rootDir}/src`)).to.eql([{ - src: s`${rootDir}/src/source/main.bs`, - dest: s`source/main.bs` - }]); - }); - - it('works for root-level double star in top-level pattern', async () => { - expect(await getFilePaths([ - '**/*' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, - { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, - { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, - { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, - { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, - { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('works for multile entries', async () => { - expect(await getFilePaths([ - 'source/**/*', - 'components/**/*', - 'manifest' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('copies top-level-string single-star globs', async () => { - writeFiles(rootDir, [ - 'source/lib.brs', - 'source/main.brs' - ]); - expect(await getFilePaths([ - 'source/*.brs' - ])).to.eql([{ - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('works for double-star globs', async () => { - expect(await getFilePaths([ - '**/*.brs' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('copies subdir-level relative double-star globs', async () => { - expect(await getFilePaths([ - 'components/**/*.brs' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }]); - }); - - it('Finds folder using square brackets glob pattern', async () => { - fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); - expect(await getFilePaths([ - '[test]/*' - ], - rootDir - )).to.eql([{ - src: s`${rootDir}/e/file.brs`, - dest: s`e/file.brs` - }]); - }); - - it('Finds folder with escaped square brackets glob pattern as name', async () => { - fsExtra.outputFileSync(`${rootDir}/[test]/file.brs`, ''); - fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); - expect(await getFilePaths([ - '\\[test\\]/*' - ], - rootDir - )).to.eql([{ - src: s`${rootDir}/[test]/file.brs`, - dest: s`[test]/file.brs` - }]); - }); - - it('throws exception when top-level strings reference files not under rootDir', async () => { - writeFiles(otherProjectDir, [ - 'manifest' - ]); - await expectThrowsAsync( - getFilePaths([ - `../${otherProjectName}/**/*` - ]) - ); - }); - - it('applies negated patterns', async () => { - expect(await getFilePaths([ - //include all components - 'components/**/*.brs', - //exclude all xml files - '!components/**/*.xml', - //re-include a specific xml file - 'components/screen1/screen1.xml' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }]); - }); - - it('handles negated multi-globs', async () => { - expect((await getFilePaths([ - 'components/**/*', - '!components/screen1/**/*' - ])).map(x => x.dest)).to.eql([ - s`components/component1.brs`, - s`components/component1.xml` - ]); - }); - - it('allows negating paths outside rootDir without requiring src;dest; syntax', async () => { - fsExtra.outputFileSync(`${rootDir}/../externalLib/source/lib.brs`, ''); - const filePaths = await getFilePaths([ - 'source/**/*', - { src: '../externalLib/**/*', dest: 'source' }, - '!../externalLib/source/**/*' - ], rootDir); - expect( - filePaths.map(x => s`${x.src}`).sort() - ).to.eql([ - s`${rootDir}/source/lib.brs`, - s`${rootDir}/source/main.brs` - ]); - }); - - it('applies multi-glob paths relative to rootDir', async () => { - expect(await getFilePaths([ - 'manifest', - 'source/**/*', - 'components/**/*', - '!components/scenes/**/*' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('ignores non-glob folder paths', async () => { - expect(await getFilePaths([ - //this is the folder called "components" - 'components' - ])).to.eql([]); //there should be no matches because rokudeploy ignores folders - }); - - }); - - describe('{src;dest} objects', () => { - it('excludes a file that is negated in src;dest;', async () => { - expect(await getFilePaths([ - 'source/**/*', - { - src: '!source/main.brs' - } - ])).to.eql([{ - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }]); - }); - - it('works for root-level double star in {src;dest} object', async () => { - expect(await getFilePaths([{ - src: '**/*', - dest: '' - } - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, - { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, - { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, - { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, - { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, - { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('uses the root of staging folder for dest when not specified with star star', async () => { - writeFiles(otherProjectDir, [ - 'components/component1/subComponent/screen.brs', - 'manifest', - 'source/thirdPartyLib.brs' - ]); - expect(await getFilePaths([{ - src: `${otherProjectDir}/**/*` - }])).to.eql([{ - src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, - dest: s`components/component1/subComponent/screen.brs` - }, { - src: s`${otherProjectDir}/manifest`, - dest: s`manifest` - }, { - src: s`${otherProjectDir}/source/thirdPartyLib.brs`, - dest: s`source/thirdPartyLib.brs` - }]); - }); - - it('copies absolute path files to specified dest', async () => { - writeFiles(otherProjectDir, [ - 'source/thirdPartyLib.brs' - ]); - expect(await getFilePaths([{ - src: `${otherProjectDir}/source/thirdPartyLib.brs`, - dest: 'lib/thirdPartyLib.brs' - }])).to.eql([{ - src: s`${otherProjectDir}/source/thirdPartyLib.brs`, - dest: s`lib/thirdPartyLib.brs` - }]); - }); - - it('copies relative path files to specified dest', async () => { - const rootDirName = path.basename(rootDir); - writeFiles(rootDir, [ - 'source/main.brs' - ]); - expect(await getFilePaths([{ - src: `../${rootDirName}/source/main.brs`, - dest: 'source/main.brs' - }])).to.eql([{ - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('maintains relative path after **', async () => { - writeFiles(otherProjectDir, [ - 'components/component1/subComponent/screen.brs', - 'manifest', - 'source/thirdPartyLib.brs' - ]); - expect(await getFilePaths([{ - src: `../otherProject/**/*`, - dest: 'outFolder/' - }])).to.eql([{ - src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, - dest: s`outFolder/components/component1/subComponent/screen.brs` - }, { - src: s`${otherProjectDir}/manifest`, - dest: s`outFolder/manifest` - }, { - src: s`${otherProjectDir}/source/thirdPartyLib.brs`, - dest: s`outFolder/source/thirdPartyLib.brs` - }]); - }); - - it('works for other globs', async () => { - expect(await getFilePaths([{ - src: `components/screen1/*creen1.brs`, - dest: s`/source` - }])).to.eql([{ - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`source/screen1.brs` - }]); - }); - - it('applies negated patterns', async () => { - writeFiles(rootDir, [ - 'components/component1.brs', - 'components/component1.xml', - 'components/screen1/screen1.brs', - 'components/screen1/screen1.xml' - ]); - expect(await getFilePaths([ - //include all component brs files - 'components/**/*.brs', - //exclude all xml files - '!components/**/*.xml', - //re-include a specific xml file - 'components/screen1/screen1.xml' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }]); - }); - }); - - it('converts relative rootDir path to absolute', async () => { - let stub = sinon.stub(rokuDeploy, 'getOptions').callThrough(); - await getFilePaths([ - 'source/main.brs' - ], './rootDir'); - expect(stub.callCount).to.be.greaterThan(0); - expect(stub.getCall(0).args[0].rootDir).to.eql('./rootDir'); - expect(stub.getCall(0).returnValue.rootDir).to.eql(s`${cwd}/rootDir`); - }); - - it('works when using a different current working directory than rootDir', async () => { - writeFiles(rootDir, [ - 'manifest', - 'images/splash_hd.jpg' - ]); - //sanity check, make sure it works without fiddling with cwd intact - let paths = await getFilePaths([ - 'manifest', - 'images/splash_hd.jpg' - ]); - - expect(paths).to.eql([{ - src: s`${rootDir}/images/splash_hd.jpg`, - dest: s`images/splash_hd.jpg` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }]); - - //change the working directory and verify everything still works - - let wrongCwd = path.dirname(path.resolve(options.rootDir)); - process.chdir(wrongCwd); - - paths = await getFilePaths([ - 'manifest', - 'images/splash_hd.jpg' - ]); - - expect(paths).to.eql([{ - src: s`${rootDir}/images/splash_hd.jpg`, - dest: s`images/splash_hd.jpg` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }]); - }); - - it('supports absolute paths from outside of the rootDir', async () => { - options = rokuDeploy.getOptions(options); - - //dest not specified - expect(await rokuDeploy.getFilePaths([{ - src: sp`${cwd}/README.md` - }], options.rootDir)).to.eql([{ - src: s`${cwd}/README.md`, - dest: s`README.md` - }]); - - //dest specified - expect(await rokuDeploy.getFilePaths([{ - src: sp`${cwd}/README.md`, - dest: 'docs/README.md' - }], options.rootDir)).to.eql([{ - src: s`${cwd}/README.md`, - dest: s`docs/README.md` - }]); - - let paths: any[]; - - paths = await rokuDeploy.getFilePaths([{ - src: sp`${cwd}/README.md`, - dest: s`docs/README.md` - }], outDir); - - expect(paths).to.eql([{ - src: s`${cwd}/README.md`, - dest: s`docs/README.md` - }]); - - //top-level string paths pointing to files outside the root should thrown an exception - await expectThrowsAsync(async () => { - paths = await rokuDeploy.getFilePaths([ - sp`${cwd}/README.md` - ], outDir); - }); - }); - - it('supports relative paths that grab files from outside of the rootDir', async () => { - writeFiles(`${rootDir}/../`, [ - 'README.md' - ]); - expect( - await rokuDeploy.getFilePaths([{ - src: sp`../README.md` - }], rootDir) - ).to.eql([{ - src: s`${rootDir}/../README.md`, - dest: s`README.md` - }]); - - expect( - await rokuDeploy.getFilePaths([{ - src: sp`../README.md`, - dest: 'docs/README.md' - }], rootDir) - ).to.eql([{ - src: s`${rootDir}/../README.md`, - dest: s`docs/README.md` - }]); - }); - - it('should throw exception because we cannot have top-level string paths pointed to files outside the root', async () => { - writeFiles(rootDir, [ - '../README.md' - ]); - await expectThrowsAsync( - rokuDeploy.getFilePaths([ - path.posix.join('..', 'README.md') - ], outDir) - ); - }); - - it('supports overriding paths', async () => { - let paths = await rokuDeploy.getFilePaths([{ - src: sp`${rootDir}/components/component1.brs`, - dest: 'comp1.brs' - }, { - src: sp`${rootDir}/components/screen1/screen1.brs`, - dest: 'comp1.brs' - }], rootDir); - expect(paths).to.be.lengthOf(1); - expect(s`${paths[0].src}`).to.equal(s`${rootDir}/components/screen1/screen1.brs`); - }); - - it('supports overriding paths from outside the root dir', async () => { - let thisRootDir = s`${tempDir}/tempTestOverrides/src`; - try { - - fsExtra.ensureDirSync(s`${thisRootDir}/source`); - fsExtra.ensureDirSync(s`${thisRootDir}/components`); - fsExtra.ensureDirSync(s`${thisRootDir}/../.tmp`); - - fsExtra.writeFileSync(s`${thisRootDir}/source/main.brs`, ''); - fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.brs`, ''); - fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.xml`, ''); - fsExtra.writeFileSync(s`${thisRootDir}/../.tmp/MainScene.brs`, ''); - - let files = [ - '**/*.xml', - '**/*.brs', - { - src: '../.tmp/MainScene.brs', - dest: 'components/MainScene.brs' - } - ]; - let paths = await rokuDeploy.getFilePaths(files, thisRootDir); - - //the MainScene.brs file from source should NOT be included - let mainSceneEntries = paths.filter(x => s`${x.dest}` === s`components/MainScene.brs`); - expect( - mainSceneEntries, - `Should only be one files entry for 'components/MainScene.brs'` - ).to.be.lengthOf(1); - expect(s`${mainSceneEntries[0].src}`).to.eql(s`${thisRootDir}/../.tmp/MainScene.brs`); - } finally { - //clean up - await fsExtra.remove(s`${thisRootDir}/../`); - } - }); - - it('maintains original file path', async () => { - fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); - expect( - await rokuDeploy.getFilePaths([ - 'components/CustomButton.brs' - ], rootDir) - ).to.eql([{ - src: s`${rootDir}/components/CustomButton.brs`, - dest: s`components/CustomButton.brs` - }]); - }); - - it('correctly assumes file path if not given', async () => { - fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); - expect( - (await rokuDeploy.getFilePaths([ - { src: 'components/*' } - ], rootDir)).sort((a, b) => a.src.localeCompare(b.src)) - ).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, { - src: s`${rootDir}/components/CustomButton.brs`, - dest: s`components/CustomButton.brs` - }]); - }); - }); - describe('computeFileDestPath', () => { it('treats {src;dest} without dest as a top-level string', () => { expect( diff --git a/src/commands/RetrieveSignedPackageCommand.ts b/src/commands/RetrieveSignedPackageCommand.ts deleted file mode 100644 index 411dfd9..0000000 --- a/src/commands/RetrieveSignedPackageCommand.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { rokuDeploy } from '../index'; - -export class RetrieveSignedPackageCommand { - async run(args) { - await rokuDeploy.retrieveSignedPackage(args.pathToPkg, { - host: args.host, - password: args.password, - outFile: args.outFile - }); - } -} diff --git a/src/util.spec.ts b/src/util.spec.ts index 1705127..ea34990 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -1,10 +1,12 @@ -import { util, standardizePath as s } from './util'; +import { util, standardizePath as s, standardizePathPosix as sp } from './util'; import { expect } from 'chai'; import * as fsExtra from 'fs-extra'; -import { cwd, tempDir, rootDir } from './testUtils.spec'; +import { cwd, tempDir, rootDir, outDir, expectThrowsAsync, writeFiles } from './testUtils.spec'; import * as path from 'path'; import * as dns from 'dns'; import { createSandbox } from 'sinon'; +import { RokuDeploy } from './RokuDeploy'; +import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; const sinon = createSandbox(); describe('util', () => { @@ -451,6 +453,650 @@ describe('util', () => { }); }); + describe('getFilePaths', () => { + const otherProjectName = 'otherProject'; + const otherProjectDir = sp`${rootDir}/../${otherProjectName}`; + let rokuDeploy: RokuDeploy; + let options: RokuDeployOptions; + //create baseline project structure + beforeEach(() => { + rokuDeploy = new RokuDeploy(); + options = rokuDeploy.getOptions({}); + fsExtra.ensureDirSync(`${rootDir}/components/emptyFolder`); + writeFiles(rootDir, [ + `manifest`, + `source/main.brs`, + `source/lib.brs`, + `components/component1.xml`, + `components/component1.brs`, + `components/screen1/screen1.xml`, + `components/screen1/screen1.brs` + ]); + }); + + async function getFilePaths(files: FileEntry[], rootDirOverride = rootDir) { + return (await util.getFilePaths(files, rootDirOverride)) + .sort((a, b) => a.src.localeCompare(b.src)); + } + + describe('top-level-patterns', () => { + it('excludes a file that is negated', async () => { + expect(await getFilePaths([ + 'source/**/*', + '!source/main.brs' + ])).to.eql([{ + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }]); + }); + + it('excludes file from non-rootdir top-level pattern', async () => { + writeFiles(rootDir, ['../externalDir/source/main.brs']); + expect(await getFilePaths([ + '../externalDir/**/*', + '!../externalDir/**/*' + ])).to.eql([]); + }); + + it('throws when using top-level string referencing file outside the root dir', async () => { + writeFiles(rootDir, [`../source/main.brs`]); + await expectThrowsAsync(async () => { + await getFilePaths([ + '../source/**/*' + ]); + }, 'Cannot reference a file outside of rootDir when using a top-level string. Please use a src;des; object instead'); + }); + + it('works for brighterscript files', async () => { + writeFiles(rootDir, ['src/source/main.bs']); + expect(await getFilePaths([ + 'manifest', + 'source/**/*.bs' + ], s`${rootDir}/src`)).to.eql([{ + src: s`${rootDir}/src/source/main.bs`, + dest: s`source/main.bs` + }]); + }); + + it('works for root-level double star in top-level pattern', async () => { + expect(await getFilePaths([ + '**/*' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, + { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, + { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, + { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, + { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, + { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('works for multile entries', async () => { + expect(await getFilePaths([ + 'source/**/*', + 'components/**/*', + 'manifest' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('copies top-level-string single-star globs', async () => { + writeFiles(rootDir, [ + 'source/lib.brs', + 'source/main.brs' + ]); + expect(await getFilePaths([ + 'source/*.brs' + ])).to.eql([{ + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('works for double-star globs', async () => { + expect(await getFilePaths([ + '**/*.brs' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('copies subdir-level relative double-star globs', async () => { + expect(await getFilePaths([ + 'components/**/*.brs' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }]); + }); + + it('Finds folder using square brackets glob pattern', async () => { + fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); + expect(await getFilePaths([ + '[test]/*' + ], + rootDir + )).to.eql([{ + src: s`${rootDir}/e/file.brs`, + dest: s`e/file.brs` + }]); + }); + + it('Finds folder with escaped square brackets glob pattern as name', async () => { + fsExtra.outputFileSync(`${rootDir}/[test]/file.brs`, ''); + fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); + expect(await getFilePaths([ + '\\[test\\]/*' + ], + rootDir + )).to.eql([{ + src: s`${rootDir}/[test]/file.brs`, + dest: s`[test]/file.brs` + }]); + }); + + it('throws exception when top-level strings reference files not under rootDir', async () => { + writeFiles(otherProjectDir, [ + 'manifest' + ]); + await expectThrowsAsync( + getFilePaths([ + `../${otherProjectName}/**/*` + ]) + ); + }); + + it('applies negated patterns', async () => { + expect(await getFilePaths([ + //include all components + 'components/**/*.brs', + //exclude all xml files + '!components/**/*.xml', + //re-include a specific xml file + 'components/screen1/screen1.xml' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }]); + }); + + it('handles negated multi-globs', async () => { + expect((await getFilePaths([ + 'components/**/*', + '!components/screen1/**/*' + ])).map(x => x.dest)).to.eql([ + s`components/component1.brs`, + s`components/component1.xml` + ]); + }); + + it('allows negating paths outside rootDir without requiring src;dest; syntax', async () => { + fsExtra.outputFileSync(`${rootDir}/../externalLib/source/lib.brs`, ''); + const filePaths = await getFilePaths([ + 'source/**/*', + { src: '../externalLib/**/*', dest: 'source' }, + '!../externalLib/source/**/*' + ], rootDir); + expect( + filePaths.map(x => s`${x.src}`).sort() + ).to.eql([ + s`${rootDir}/source/lib.brs`, + s`${rootDir}/source/main.brs` + ]); + }); + + it('applies multi-glob paths relative to rootDir', async () => { + expect(await getFilePaths([ + 'manifest', + 'source/**/*', + 'components/**/*', + '!components/scenes/**/*' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('ignores non-glob folder paths', async () => { + expect(await getFilePaths([ + //this is the folder called "components" + 'components' + ])).to.eql([]); //there should be no matches because rokudeploy ignores folders + }); + + }); + + describe('{src;dest} objects', () => { + it('excludes a file that is negated in src;dest;', async () => { + expect(await getFilePaths([ + 'source/**/*', + { + src: '!source/main.brs' + } + ])).to.eql([{ + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }]); + }); + + it('works for root-level double star in {src;dest} object', async () => { + expect(await getFilePaths([{ + src: '**/*', + dest: '' + } + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, + { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, + { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, + { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, + { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, + { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('uses the root of staging folder for dest when not specified with star star', async () => { + writeFiles(otherProjectDir, [ + 'components/component1/subComponent/screen.brs', + 'manifest', + 'source/thirdPartyLib.brs' + ]); + expect(await getFilePaths([{ + src: `${otherProjectDir}/**/*` + }])).to.eql([{ + src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, + dest: s`components/component1/subComponent/screen.brs` + }, { + src: s`${otherProjectDir}/manifest`, + dest: s`manifest` + }, { + src: s`${otherProjectDir}/source/thirdPartyLib.brs`, + dest: s`source/thirdPartyLib.brs` + }]); + }); + + it('copies absolute path files to specified dest', async () => { + writeFiles(otherProjectDir, [ + 'source/thirdPartyLib.brs' + ]); + expect(await getFilePaths([{ + src: `${otherProjectDir}/source/thirdPartyLib.brs`, + dest: 'lib/thirdPartyLib.brs' + }])).to.eql([{ + src: s`${otherProjectDir}/source/thirdPartyLib.brs`, + dest: s`lib/thirdPartyLib.brs` + }]); + }); + + it('copies relative path files to specified dest', async () => { + const rootDirName = path.basename(rootDir); + writeFiles(rootDir, [ + 'source/main.brs' + ]); + expect(await getFilePaths([{ + src: `../${rootDirName}/source/main.brs`, + dest: 'source/main.brs' + }])).to.eql([{ + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('maintains relative path after **', async () => { + writeFiles(otherProjectDir, [ + 'components/component1/subComponent/screen.brs', + 'manifest', + 'source/thirdPartyLib.brs' + ]); + expect(await getFilePaths([{ + src: `../otherProject/**/*`, + dest: 'outFolder/' + }])).to.eql([{ + src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, + dest: s`outFolder/components/component1/subComponent/screen.brs` + }, { + src: s`${otherProjectDir}/manifest`, + dest: s`outFolder/manifest` + }, { + src: s`${otherProjectDir}/source/thirdPartyLib.brs`, + dest: s`outFolder/source/thirdPartyLib.brs` + }]); + }); + + it('works for other globs', async () => { + expect(await getFilePaths([{ + src: `components/screen1/*creen1.brs`, + dest: s`/source` + }])).to.eql([{ + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`source/screen1.brs` + }]); + }); + + it('applies negated patterns', async () => { + writeFiles(rootDir, [ + 'components/component1.brs', + 'components/component1.xml', + 'components/screen1/screen1.brs', + 'components/screen1/screen1.xml' + ]); + expect(await getFilePaths([ + //include all component brs files + 'components/**/*.brs', + //exclude all xml files + '!components/**/*.xml', + //re-include a specific xml file + 'components/screen1/screen1.xml' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }]); + }); + }); + + it('converts relative rootDir path to absolute', async () => { + let stub = sinon.stub(rokuDeploy, 'getOptions').callThrough(); + await getFilePaths([ + 'source/main.brs' + ], './rootDir'); + expect(stub.callCount).to.be.greaterThan(0); + expect(stub.getCall(0).args[0].rootDir).to.eql('./rootDir'); + expect(stub.getCall(0).returnValue.rootDir).to.eql(s`${cwd}/rootDir`); + }); + + it('works when using a different current working directory than rootDir', async () => { + writeFiles(rootDir, [ + 'manifest', + 'images/splash_hd.jpg' + ]); + //sanity check, make sure it works without fiddling with cwd intact + let paths = await getFilePaths([ + 'manifest', + 'images/splash_hd.jpg' + ]); + + expect(paths).to.eql([{ + src: s`${rootDir}/images/splash_hd.jpg`, + dest: s`images/splash_hd.jpg` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }]); + + //change the working directory and verify everything still works + + let wrongCwd = path.dirname(path.resolve(options.rootDir)); + process.chdir(wrongCwd); + + paths = await getFilePaths([ + 'manifest', + 'images/splash_hd.jpg' + ]); + + expect(paths).to.eql([{ + src: s`${rootDir}/images/splash_hd.jpg`, + dest: s`images/splash_hd.jpg` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }]); + }); + + it('supports absolute paths from outside of the rootDir', async () => { + //dest not specified + expect(await getFilePaths([{ + src: sp`${cwd}/README.md` + }], options.rootDir)).to.eql([{ + src: s`${cwd}/README.md`, + dest: s`README.md` + }]); + + //dest specified + expect(await getFilePaths([{ + src: sp`${cwd}/README.md`, + dest: 'docs/README.md' + }], options.rootDir)).to.eql([{ + src: s`${cwd}/README.md`, + dest: s`docs/README.md` + }]); + + let paths: any[]; + + paths = await getFilePaths([{ + src: sp`${cwd}/README.md`, + dest: s`docs/README.md` + }], outDir); + + expect(paths).to.eql([{ + src: s`${cwd}/README.md`, + dest: s`docs/README.md` + }]); + + //top-level string paths pointing to files outside the root should thrown an exception + await expectThrowsAsync(async () => { + paths = await getFilePaths([ + sp`${cwd}/README.md` + ], outDir); + }); + }); + + it('supports relative paths that grab files from outside of the rootDir', async () => { + writeFiles(`${rootDir}/../`, [ + 'README.md' + ]); + expect( + await getFilePaths([{ + src: sp`../README.md` + }], rootDir) + ).to.eql([{ + src: s`${rootDir}/../README.md`, + dest: s`README.md` + }]); + + expect( + await getFilePaths([{ + src: sp`../README.md`, + dest: 'docs/README.md' + }], rootDir) + ).to.eql([{ + src: s`${rootDir}/../README.md`, + dest: s`docs/README.md` + }]); + }); + + it('should throw exception because we cannot have top-level string paths pointed to files outside the root', async () => { + writeFiles(rootDir, [ + '../README.md' + ]); + await expectThrowsAsync( + getFilePaths([ + path.posix.join('..', 'README.md') + ], outDir) + ); + }); + + it('supports overriding paths', async () => { + let paths = await getFilePaths([{ + src: sp`${rootDir}/components/component1.brs`, + dest: 'comp1.brs' + }, { + src: sp`${rootDir}/components/screen1/screen1.brs`, + dest: 'comp1.brs' + }], rootDir); + expect(paths).to.be.lengthOf(1); + expect(s`${paths[0].src}`).to.equal(s`${rootDir}/components/screen1/screen1.brs`); + }); + + it('supports overriding paths from outside the root dir', async () => { + let thisRootDir = s`${tempDir}/tempTestOverrides/src`; + try { + + fsExtra.ensureDirSync(s`${thisRootDir}/source`); + fsExtra.ensureDirSync(s`${thisRootDir}/components`); + fsExtra.ensureDirSync(s`${thisRootDir}/../.tmp`); + + fsExtra.writeFileSync(s`${thisRootDir}/source/main.brs`, ''); + fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.brs`, ''); + fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.xml`, ''); + fsExtra.writeFileSync(s`${thisRootDir}/../.tmp/MainScene.brs`, ''); + + let files = [ + '**/*.xml', + '**/*.brs', + { + src: '../.tmp/MainScene.brs', + dest: 'components/MainScene.brs' + } + ]; + let paths = await getFilePaths(files, thisRootDir); + + //the MainScene.brs file from source should NOT be included + let mainSceneEntries = paths.filter(x => s`${x.dest}` === s`components/MainScene.brs`); + expect( + mainSceneEntries, + `Should only be one files entry for 'components/MainScene.brs'` + ).to.be.lengthOf(1); + expect(s`${mainSceneEntries[0].src}`).to.eql(s`${thisRootDir}/../.tmp/MainScene.brs`); + } finally { + //clean up + await fsExtra.remove(s`${thisRootDir}/../`); + } + }); + + it('maintains original file path', async () => { + fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); + expect( + await getFilePaths([ + 'components/CustomButton.brs' + ], rootDir) + ).to.eql([{ + src: s`${rootDir}/components/CustomButton.brs`, + dest: s`components/CustomButton.brs` + }]); + }); + + it('correctly assumes file path if not given', async () => { + fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); + expect( + (await getFilePaths([ + { src: 'components/*' } + ], rootDir)).sort((a, b) => a.src.localeCompare(b.src)) + ).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, { + src: s`${rootDir}/components/CustomButton.brs`, + dest: s`components/CustomButton.brs` + }]); + }); + }); + describe('getOptionsFromJson', () => { beforeEach(() => { fsExtra.ensureDirSync(rootDir); diff --git a/src/util.ts b/src/util.ts index 9fd883b..7c1846d 100644 --- a/src/util.ts +++ b/src/util.ts @@ -291,7 +291,7 @@ export class Util { public async getFilePaths(files: FileEntry[], rootDir: string): Promise { //if the rootDir isn't absolute, convert it to absolute using the standard options flow if (path.isAbsolute(rootDir) === false) { - rootDir = this.getOptions({ rootDir: rootDir }).rootDir; + rootDir = rokuDeploy.getOptions({ rootDir: rootDir }).rootDir; //TODO: This moved from rokudeploy to here, but if we need to get options how do we fix this? } const entries = this.normalizeFilesArray(files); const srcPathsByIndex = await util.globAllByIndex( @@ -486,7 +486,7 @@ export class Util { /** * A function to fill in any missing arguments with JSON values */ - public getOptionsFromJson(defaultArgs) { //TODO: create a test for this in cli.spec.ts too + public getOptionsFromJson(defaultArgs) {//TODO: The original function handled parse errors, but this one doesn't let args = { ...defaultArgs }; const fileNames = ['rokudeploy.json', 'bsconfig.json']; From c74ef8e9f01974ebd1154f95d573d0c811ece6eb Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 09:51:48 -0500 Subject: [PATCH 33/93] Random changes I forgot to put in the other pushes --- src/RokuDeploy.spec.ts | 2 +- src/RokuDeploy.ts | 23 ++--------------------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 38ec4f5..c4f44b8 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -56,7 +56,7 @@ describe('index', () => { writeStreamPromise = writeStreamDeferred.promise as any; //fake out the write stream function - createWriteStreamStub = sinon.stub(rokuDeploy.fsExtra, 'createWriteStream').callsFake((filePath: PathLike) => { + createWriteStreamStub = sinon.stub(fsExtra, 'createWriteStream').callsFake((filePath: PathLike) => { const writeStream = fs.createWriteStream(filePath); writeStreamDeferred.resolve(writeStream); writeStreamDeferred.isComplete = true; diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 62dc8be..ad94f4d 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -48,7 +48,7 @@ export class RokuDeploy { throw new Error(`rootDir does not exist at "${rootDir}"`); } - let fileObjects = await this.getFilePaths(options.files, rootDir); + let fileObjects = await util.getFilePaths(options.files, rootDir); //copy all of the files await Promise.all(fileObjects.map(async (fileObject) => { let destFilePath = util.standardizePath(`${stagingPath}/${fileObject.dest}`); @@ -370,7 +370,7 @@ export class RokuDeploy { * Sign a pre-existing package using Roku and return path to retrieve it * @param options */ - public async createSignedPackage(options: SignExistingPackageOptions): Promise { + public async createSignedPackage(options: CreateSignedPackageOptions): Promise { options = this.getOptions(options) as any; if (!options.signingPassword) { throw new errors.MissingRequiredOptionError('Must supply signingPassword'); @@ -1013,15 +1013,6 @@ export interface CreateSignedPackageOptions { devId?: string; } -export interface RetrieveSignedPackageOptions { - host: string; - password: string; - packagePort?: number; - timeout?: number; - username?: string; - outDir?: string; - outFile?: string; -} export interface DeleteInstalledChannelOptions { host: string; password: string; @@ -1043,16 +1034,6 @@ export interface DeployOptions { outDir?: string; } -export interface DeployAndSignPackageOptions { - host: string; - password: string; - signingPassword: string; - rootDir?: string; - files?: FileEntry[]; - retainStagingDir?: boolean; - convertToSquashfs?: boolean; - stagingDir?: string; -} export interface GetOutputPkgFilePathOptions { outFile?: string; outDir?: string; From 583d9608ced0926e8686056e2422c44608c7d927 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 09:55:21 -0500 Subject: [PATCH 34/93] Change to different notation since getOutputZipFilePath and getOutputPkgPath were made private --- src/RokuDeploy.spec.ts | 10 +++++----- src/commands/GetOutputPkgFilePathCommand.ts | 3 ++- src/commands/GetOutputZipFilePathCommand.ts | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index c4f44b8..9facc3b 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -82,7 +82,7 @@ describe('index', () => { describe('getOutputPkgFilePath', () => { it('should return correct path if given basename', () => { - let outputPath = rokuDeploy.getOutputPkgFilePath({ + let outputPath = rokuDeploy['getOutputPkgFilePath']({ outFile: 'roku-deploy', outDir: outDir }); @@ -90,7 +90,7 @@ describe('index', () => { }); it('should return correct path if given outFile option ending in .zip', () => { - let outputPath = rokuDeploy.getOutputPkgFilePath({ + let outputPath = rokuDeploy['getOutputPkgFilePath']({ outFile: 'roku-deploy.zip', outDir: outDir }); @@ -100,7 +100,7 @@ describe('index', () => { describe('getOutputZipFilePath', () => { it('should return correct path if given basename', () => { - let outputPath = rokuDeploy.getOutputZipFilePath({ + let outputPath = rokuDeploy['getOutputZipFilePath']({ outFile: 'roku-deploy', outDir: outDir }); @@ -108,7 +108,7 @@ describe('index', () => { }); it('should return correct path if given outFile option ending in .zip', () => { - let outputPath = rokuDeploy.getOutputZipFilePath({ + let outputPath = rokuDeploy['getOutputZipFilePath']({ outFile: 'roku-deploy.zip', outDir: outDir }); @@ -866,7 +866,7 @@ describe('index', () => { outDir: outDir, outFile: 'fileThatDoesNotExist.zip' }); - }, `Cannot publish because file does not exist at '${rokuDeploy.getOutputZipFilePath({ + }, `Cannot publish because file does not exist at '${rokuDeploy['getOutputZipFilePath']({ outFile: 'fileThatDoesNotExist.zip', outDir: outDir })}'`); diff --git a/src/commands/GetOutputPkgFilePathCommand.ts b/src/commands/GetOutputPkgFilePathCommand.ts index 78fff13..0861d1e 100644 --- a/src/commands/GetOutputPkgFilePathCommand.ts +++ b/src/commands/GetOutputPkgFilePathCommand.ts @@ -2,7 +2,8 @@ import { rokuDeploy } from '../index'; export class GetOutputPkgFilePathCommand { run(args) { - const outputPath = rokuDeploy.getOutputPkgFilePath({ + // eslint-disable-next-line @typescript-eslint/dot-notation + const outputPath = rokuDeploy['getOutputPkgPath']({ outFile: args.outFile, outDir: args.outDir }); diff --git a/src/commands/GetOutputZipFilePathCommand.ts b/src/commands/GetOutputZipFilePathCommand.ts index 5525057..bd9d7de 100644 --- a/src/commands/GetOutputZipFilePathCommand.ts +++ b/src/commands/GetOutputZipFilePathCommand.ts @@ -2,7 +2,8 @@ import { rokuDeploy } from '../index'; export class GetOutputZipFilePathCommand { run(args) { - const outputPath = rokuDeploy.getOutputZipFilePath({ + // eslint-disable-next-line @typescript-eslint/dot-notation + const outputPath = rokuDeploy['getOutputZipFilePath']({ outFile: args.outFile, outDir: args.outDir }); From 6d874a669943e8b24eb4c9e854cd89cd632ddc9c Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 09:57:45 -0500 Subject: [PATCH 35/93] Change notation for normalizeDeviceInfoFieldValue since it was made privete --- src/RokuDeploy.spec.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 9facc3b..1d39c3f 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -574,24 +574,24 @@ describe('index', () => { describe('normalizeDeviceInfoFieldValue', () => { it('converts normal values', () => { - expect(rokuDeploy.normalizeDeviceInfoFieldValue('true')).to.eql(true); - expect(rokuDeploy.normalizeDeviceInfoFieldValue('false')).to.eql(false); - expect(rokuDeploy.normalizeDeviceInfoFieldValue('1')).to.eql(1); - expect(rokuDeploy.normalizeDeviceInfoFieldValue('1.2')).to.eql(1.2); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('true')).to.eql(true); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('false')).to.eql(false); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('1')).to.eql(1); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('1.2')).to.eql(1.2); //it'll trim whitespace too - expect(rokuDeploy.normalizeDeviceInfoFieldValue(' 1.2')).to.eql(1.2); - expect(rokuDeploy.normalizeDeviceInfoFieldValue(' 1.2 ')).to.eql(1.2); + expect(rokuDeploy['normalizeDeviceInfoFieldValue'](' 1.2')).to.eql(1.2); + expect(rokuDeploy['normalizeDeviceInfoFieldValue'](' 1.2 ')).to.eql(1.2); }); it('leaves invalid numbers as strings', () => { - expect(rokuDeploy.normalizeDeviceInfoFieldValue('v1.2.3')).to.eql('v1.2.3'); - expect(rokuDeploy.normalizeDeviceInfoFieldValue('1.2.3-alpha.1')).to.eql('1.2.3-alpha.1'); - expect(rokuDeploy.normalizeDeviceInfoFieldValue('123Four')).to.eql('123Four'); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('v1.2.3')).to.eql('v1.2.3'); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('1.2.3-alpha.1')).to.eql('1.2.3-alpha.1'); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('123Four')).to.eql('123Four'); }); it('decodes HTML entities', () => { - expect(rokuDeploy.normalizeDeviceInfoFieldValue('3&4')).to.eql('3&4'); - expect(rokuDeploy.normalizeDeviceInfoFieldValue('3&4')).to.eql('3&4'); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('3&4')).to.eql('3&4'); + expect(rokuDeploy['normalizeDeviceInfoFieldValue']('3&4')).to.eql('3&4'); }); }); From f5ba8397678a8ea5e0a7b860ddf6c63462b8d850 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 10:00:54 -0500 Subject: [PATCH 36/93] Change notation for parsedManifestFromString and ParseManifest since being made private --- src/RokuDeploy.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 1d39c3f..be55726 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -2419,13 +2419,13 @@ describe('index', () => { describe('parseManifest', () => { it('correctly parses valid manifest', async () => { fsExtra.outputFileSync(`${rootDir}/manifest`, `title=AwesomeApp`); - let parsedManifest = await rokuDeploy.parseManifest(`${rootDir}/manifest`); + let parsedManifest = await rokuDeploy['parseManifest'](`${rootDir}/manifest`); expect(parsedManifest.title).to.equal('AwesomeApp'); }); it('Throws our error message for a missing file', async () => { await expectThrowsAsync( - rokuDeploy.parseManifest('invalid-path'), + rokuDeploy['parseManifest']('invalid-path'), `invalid-path does not exist` ); }); @@ -2433,7 +2433,7 @@ describe('index', () => { describe('parseManifestFromString', () => { it('correctly parses valid manifest', () => { - let parsedManifest = rokuDeploy.parseManifestFromString(` + let parsedManifest = rokuDeploy['parseManifestFromString'](` title=RokuDeployTestChannel major_version=1 minor_version=0 @@ -2458,7 +2458,7 @@ describe('index', () => { it('correctly converts back to a valid manifest when lineNumber and keyIndexes are provided', () => { expect( rokuDeploy.stringifyManifest( - rokuDeploy.parseManifestFromString('major_version=3\nminor_version=4') + rokuDeploy['parseManifestFromString']('major_version=3\nminor_version=4') ) ).to.equal( 'major_version=3\nminor_version=4' @@ -2466,10 +2466,10 @@ describe('index', () => { }); it('correctly converts back to a valid manifest when lineNumber and keyIndexes are not provided', () => { - const parsed = rokuDeploy.parseManifestFromString('title=App\nmajor_version=3'); + const parsed = rokuDeploy['parseManifestFromString']('title=App\nmajor_version=3'); delete parsed.keyIndexes; delete parsed.lineCount; - let outputParsedManifest = rokuDeploy.parseManifestFromString( + let outputParsedManifest = rokuDeploy['parseManifestFromString']( rokuDeploy.stringifyManifest(parsed) ); expect(outputParsedManifest.title).to.equal('App'); From 2858dd619811b3f05eee98912f95968e7e9d46e2 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 29 Feb 2024 10:19:09 -0500 Subject: [PATCH 37/93] Change deleteInstalledChannel to deleteDevChannel, other small changes --- src/RokuDeploy.ts | 8 ++++---- src/cli.spec.ts | 2 +- src/device.spec.ts | 12 +----------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index ad94f4d..6970d0d 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -556,7 +556,7 @@ export class RokuDeploy { * Deletes any installed dev channel on the target Roku device * @param options */ - public async deleteDevChannel(options?: DeleteInstalledChannelOptions) { + public async deleteDevChannel(options?: DeleteDevChannelOptions) { options = this.getOptions(options) as any; let deleteOptions = this.generateBaseRequestOptions('plugin_install', options as any); @@ -647,7 +647,7 @@ export class RokuDeploy { retainDeploymentArchive: true, incrementBuildNumber: false, failOnCompileError: true, - deleteInstalledChannel: true, + deleteDevChannel: true, packagePort: 80, remotePort: 8060, timeout: 150000, @@ -1013,7 +1013,7 @@ export interface CreateSignedPackageOptions { devId?: string; } -export interface DeleteInstalledChannelOptions { +export interface DeleteDevChannelOptions { host: string; password: string; } @@ -1029,7 +1029,7 @@ export interface DeployOptions { files?: FileEntry[]; rootDir?: string; stagingDir?: string; - deleteInstalledChannel?: boolean; + deleteDevChannel?: boolean; outFile?: string; outDir?: string; } diff --git a/src/cli.spec.ts b/src/cli.spec.ts index eaaf1fc..cd6a461 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -68,7 +68,7 @@ describe('cli', () => { }); it('Publish passes proper options', async () => { - const stub = sinon.stub(rokuDeploy, 'publish').callsFake(async () => { + const stub = sinon.stub(rokuDeploy, 'sideload').callsFake(async () => { return Promise.resolve({ message: 'Publish successful', results: {} diff --git a/src/device.spec.ts b/src/device.spec.ts index 8b6d295..df77e32 100644 --- a/src/device.spec.ts +++ b/src/device.spec.ts @@ -2,7 +2,7 @@ import * as assert from 'assert'; import * as fsExtra from 'fs-extra'; import type { RokuDeployOptions } from './index'; import { rokuDeploy } from './index'; -import { cwd, expectPathExists, expectThrowsAsync, outDir, rootDir, tempDir, writeFiles } from './testUtils.spec'; +import { cwd, expectThrowsAsync, outDir, rootDir, tempDir, writeFiles } from './testUtils.spec'; import * as dedent from 'dedent'; //these tests are run against an actual roku device. These cannot be enabled when run on the CI server @@ -79,14 +79,4 @@ describe('device', function device() { ); }); }); - - describe('deployAndSignPackage', () => { - it('works', async () => { - await rokuDeploy.deleteInstalledChannel(options as any); - await rokuDeploy.rekeyDevice(options as any); - expectPathExists( - await rokuDeploy.deployAndSignPackage(options as any) - ); - }); - }); }); From 3186e880cc29edefcd3fe96f41fe8085ec9cde0d Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 4 Mar 2024 18:47:48 -0500 Subject: [PATCH 38/93] Add stagingDir, fix zip/deleteDevChannel/captureScreenshot function calls, delete Deploy function --- src/RokuDeploy.spec.ts | 9 +++-- src/RokuDeploy.ts | 21 +++++------- src/RokuDeployOptions.ts | 6 ---- src/cli.spec.ts | 33 +++---------------- src/cli.ts | 5 ++- ...lCommand.ts => DeleteDevChannelCommand.ts} | 2 +- src/commands/DeployCommand.ts | 11 ------- src/commands/ZipCommand.ts | 10 ++++++ src/commands/ZipFolderCommand.ts | 10 ------ src/commands/ZipPackageCommand.ts | 10 +++--- src/device.spec.ts | 21 ++---------- 11 files changed, 37 insertions(+), 101 deletions(-) rename src/commands/{DeleteInstalledChannelCommand.ts => DeleteDevChannelCommand.ts} (80%) delete mode 100644 src/commands/DeployCommand.ts create mode 100644 src/commands/ZipCommand.ts delete mode 100644 src/commands/ZipFolderCommand.ts diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index be55726..54c644e 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -8,7 +8,6 @@ import * as path from 'path'; import * as JSZip from 'jszip'; import * as child_process from 'child_process'; import * as glob from 'glob'; -import type { BeforeZipCallbackInfo } from './RokuDeploy'; import { RokuDeploy } from './RokuDeploy'; import * as errors from './Errors'; import { util, standardizePath as s, standardizePathPosix as sp } from './util'; @@ -2023,8 +2022,8 @@ describe('index', () => { expect(result).not.to.be.undefined; }); - it('continues with deploy if deleteInstalledChannel fails', async () => { - sinon.stub(rokuDeploy, 'deleteInstalledChannel').returns( + it('continues with deploy if deleteDevChannel fails', async () => { + sinon.stub(rokuDeploy, 'deleteDevChannel').returns( Promise.reject( new Error('failed') ) @@ -2043,7 +2042,7 @@ describe('index', () => { it('should delete installed channel if requested', async () => { fsExtra.outputFileSync(s`${rootDir}/manifest`, ''); - const spy = sinon.spy(rokuDeploy, 'deleteInstalledChannel'); + const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); options.deleteInstalledChannel = true; mockDoPostRequest(); @@ -2060,7 +2059,7 @@ describe('index', () => { it('should not delete installed channel if not requested', async () => { fsExtra.outputFileSync(s`${rootDir}/manifest`, ''); - const spy = sinon.spy(rokuDeploy, 'deleteInstalledChannel'); + const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); mockDoPostRequest(); await rokuDeploy.deploy({ diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 6970d0d..7e60204 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -41,17 +41,17 @@ export class RokuDeploy { await fsExtra.ensureDir(options.stagingDir); // await this.copyToStaging(options.files, options.stagingDir, options.rootDir); - if (!stagingPath) { + if (!options.stagingDir) { throw new Error('stagingPath is required'); } - if (!await fsExtra.pathExists(rootDir)) { - throw new Error(`rootDir does not exist at "${rootDir}"`); + if (!await fsExtra.pathExists(options.rootDir)) { + throw new Error(`rootDir does not exist at "${options.rootDir}"`); } - let fileObjects = await util.getFilePaths(options.files, rootDir); + let fileObjects = await util.getFilePaths(options.files, options.rootDir); //copy all of the files await Promise.all(fileObjects.map(async (fileObject) => { - let destFilePath = util.standardizePath(`${stagingPath}/${fileObject.dest}`); + let destFilePath = util.standardizePath(`${options.stagingDir}/${fileObject.dest}`); //make sure the containing folder exists await fsExtra.ensureDir(path.dirname(destFilePath)); @@ -644,6 +644,7 @@ export class RokuDeploy { let defaultOptions = { outDir: './out', outFile: 'roku-deploy', + stagingDir: `./out/.roku-deploy-staging`, retainDeploymentArchive: true, incrementBuildNumber: false, failOnCompileError: true, @@ -668,16 +669,14 @@ export class RokuDeploy { let stagingDir = finalOptions.stagingDir || finalOptions.stagingFolderPath; //stagingDir - if (stagingDir) { - finalOptions.stagingDir = path.resolve(process.cwd(), stagingDir); + if (options.stagingDir) { + finalOptions.stagingDir = path.resolve(options.cwd, options.stagingDir); } else { finalOptions.stagingDir = path.resolve( process.cwd(), util.standardizePath(`${finalOptions.outDir}/.roku-deploy-staging`) ); } - //sync the new option with the old one (for back-compat) - finalOptions.stagingFolderPath = finalOptions.stagingDir; return finalOptions; } @@ -867,10 +866,6 @@ export interface BeforeZipCallbackInfo { * Contains an associative array of the parsed values in the manifest */ manifestData: ManifestData; - /** - * @deprecated since 3.9.0. use `stagingDir` instead - */ - stagingFolderPath: string; /** * The directory where the files were staged */ diff --git a/src/RokuDeployOptions.ts b/src/RokuDeployOptions.ts index b05a5b4..dc1b4ff 100644 --- a/src/RokuDeployOptions.ts +++ b/src/RokuDeployOptions.ts @@ -49,12 +49,6 @@ export interface RokuDeployOptions { */ retainDeploymentArchive?: boolean; - /** - * The path where roku-deploy should stage all of the files right before being zipped. defaults to ${outDir}/.roku-deploy-staging - * @deprecated since 3.9.0. use `stagingDir` instead - */ - stagingFolderPath?: string; - /** * The path where roku-deploy should stage all of the files right before being zipped. defaults to ${outDir}/.roku-deploy-staging */ diff --git a/src/cli.spec.ts b/src/cli.spec.ts index cd6a461..f599044 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -9,8 +9,7 @@ import { PublishCommand } from './commands/PublishCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; -import { DeployCommand } from './commands/DeployCommand'; -import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannelCommand'; +import { DeleteDevChannelCommand } from './commands/DeleteDevChannelCommand'; import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; @@ -162,36 +161,12 @@ describe('cli', () => { }); }); - it('Deploys a package', async () => { - const stub = sinon.stub(rokuDeploy, 'deploy').callsFake(async () => { - return Promise.resolve({ - message: 'Convert successful', - results: {} - }); - }); - - const command = new DeployCommand(); - await command.run({ - host: '1.2.3.4', - password: '5536', - rootDir: rootDir - }); - - expect( - stub.getCall(0).args[0] - ).to.eql({ - host: '1.2.3.4', - password: '5536', - rootDir: rootDir - }); - }); - it('Deletes an installed channel', async () => { - const stub = sinon.stub(rokuDeploy, 'deleteInstalledChannel').callsFake(async () => { + const stub = sinon.stub(rokuDeploy, 'deleteDevChannel').callsFake(async () => { return Promise.resolve({ response: {}, body: {} }); }); - const command = new DeleteInstalledChannelCommand(); + const command = new DeleteDevChannelCommand(); await command.run({ host: '1.2.3.4', password: '5536' @@ -206,7 +181,7 @@ describe('cli', () => { }); it('Takes a screenshot', async () => { - const stub = sinon.stub(rokuDeploy, 'takeScreenshot').callsFake(async () => { + const stub = sinon.stub(rokuDeploy, 'captureScreenshot').callsFake(async () => { return Promise.resolve(''); }); diff --git a/src/cli.ts b/src/cli.ts index 16cfe0a..8f4c249 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -9,14 +9,13 @@ import { PublishCommand } from './commands/PublishCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; -import { DeployCommand } from './commands/DeployCommand'; -import { DeleteInstalledChannelCommand } from './commands/DeleteInstalledChannelCommand'; +import { DeleteDevChannelCommand } from './commands/DeleteDevChannelCommand'; import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; import { GetOutputZipFilePathCommand } from './commands/GetOutputZipFilePathCommand'; import { GetOutputPkgFilePathCommand } from './commands/GetOutputPkgFilePathCommand'; import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; -import { ZipFolderCommand } from './commands/ZipFolderCommand'; +import { ZipCommand } from './commands/ZipCommand'; void yargs diff --git a/src/commands/DeleteInstalledChannelCommand.ts b/src/commands/DeleteDevChannelCommand.ts similarity index 80% rename from src/commands/DeleteInstalledChannelCommand.ts rename to src/commands/DeleteDevChannelCommand.ts index b6cfebc..52dd95f 100644 --- a/src/commands/DeleteInstalledChannelCommand.ts +++ b/src/commands/DeleteDevChannelCommand.ts @@ -1,6 +1,6 @@ import { rokuDeploy } from '../index'; -export class DeleteInstalledChannelCommand { +export class DeleteDevChannelCommand { async run(args) { await rokuDeploy.deleteDevChannel({ host: args.host, diff --git a/src/commands/DeployCommand.ts b/src/commands/DeployCommand.ts deleted file mode 100644 index 5947deb..0000000 --- a/src/commands/DeployCommand.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { rokuDeploy } from '../index'; - -export class DeployCommand { - async run(args) { - await rokuDeploy.deploy({ - host: args.host, - password: args.password, - rootDir: args.rootDir - }); - } -} diff --git a/src/commands/ZipCommand.ts b/src/commands/ZipCommand.ts new file mode 100644 index 0000000..44b0e12 --- /dev/null +++ b/src/commands/ZipCommand.ts @@ -0,0 +1,10 @@ +import { rokuDeploy } from '../index'; + +export class ZipCommand { + async run(args) { + await rokuDeploy.zip({ + stagingDir: args.stagingDir, + outDir: args.outDir + }); + } +} diff --git a/src/commands/ZipFolderCommand.ts b/src/commands/ZipFolderCommand.ts deleted file mode 100644 index edf9078..0000000 --- a/src/commands/ZipFolderCommand.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { rokuDeploy } from '../index'; - -export class ZipFolderCommand { - async run(args) { - await rokuDeploy.zipFolder( - args.srcFolder, - args.zipFilePath - ); - } -} diff --git a/src/commands/ZipPackageCommand.ts b/src/commands/ZipPackageCommand.ts index 4cd0ebf..b1463e7 100644 --- a/src/commands/ZipPackageCommand.ts +++ b/src/commands/ZipPackageCommand.ts @@ -1,10 +1,12 @@ import { rokuDeploy } from '../index'; +import { util } from '../util'; export class ZipPackageCommand { async run(args) { - await rokuDeploy.zip({ - stagingDir: args.stagingDir, - outDir: args.outDir - }); + const options = { + ...util.getOptionsFromJson(), + ...args + }; + await rokuDeploy.zip(options); } } diff --git a/src/device.spec.ts b/src/device.spec.ts index df77e32..14a5052 100644 --- a/src/device.spec.ts +++ b/src/device.spec.ts @@ -1,8 +1,7 @@ -import * as assert from 'assert'; import * as fsExtra from 'fs-extra'; import type { RokuDeployOptions } from './index'; import { rokuDeploy } from './index'; -import { cwd, expectThrowsAsync, outDir, rootDir, tempDir, writeFiles } from './testUtils.spec'; +import { cwd, outDir, rootDir, tempDir, writeFiles } from './testUtils.spec'; import * as dedent from 'dedent'; //these tests are run against an actual roku device. These cannot be enabled when run on the CI server @@ -62,21 +61,5 @@ describe('device', function device() { }); this.timeout(20000); - - describe('deploy', () => { - it('works', async () => { - options.retainDeploymentArchive = true; - let response = await rokuDeploy.deploy(options as any); - assert.equal(response.message, 'Successful deploy'); - }); - - it('Presents nice message for 401 unauthorized status code', async () => { - this.timeout(20000); - options.password = 'NOT_THE_PASSWORD'; - await expectThrowsAsync( - rokuDeploy.deploy(options as any), - 'Unauthorized. Please verify username and password for target Roku.' - ); - }); - }); + console.log(options); // So there are no errors about unused variable }); From 55ce426b6798384e565c01611b3a2bfa26126a97 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 4 Mar 2024 18:48:10 -0500 Subject: [PATCH 39/93] Fix commands --- src/commands/ExecCommand.ts | 32 ++++++++++--------- src/commands/KeyDownCommand.ts | 7 ++++ src/commands/KeyPressCommand.ts | 7 ++++ src/commands/KeyUpCommand.ts | 7 ++++ .../{TextCommand.ts => SendTextCommand.ts} | 2 +- 5 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 src/commands/KeyDownCommand.ts create mode 100644 src/commands/KeyPressCommand.ts create mode 100644 src/commands/KeyUpCommand.ts rename src/commands/{TextCommand.ts => SendTextCommand.ts} (87%) diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts index bf4cfc3..9bdf9ad 100644 --- a/src/commands/ExecCommand.ts +++ b/src/commands/ExecCommand.ts @@ -1,24 +1,25 @@ -import { rokuDeploy } from '../index'; -import { cwd } from '../testUtils.spec'; import { util } from '../util'; +import { rokuDeploy } from '../RokuDeploy'; +import type { CloseChannelOptions, ConvertToSquashfsOptions, CreateSignedPackageOptions, DeleteDevChannelOptions, RekeyDeviceOptions, SideloadOptions } from '../RokuDeploy'; +import type { RokuDeployOptions } from '../RokuDeployOptions'; export class ExecCommand { private actions: string[]; - private configPath: string; - // eslint-disable-next-line @typescript-eslint/ban-types - private options: {}; + private options: RokuDeployOptions; - constructor(actions: string, configPath: string, ...rokuDeployOptions) { + constructor(actions: string, rokuDeployOptions: RokuDeployOptions) { this.actions = actions.split('|'); - this.configPath = configPath; this.options = rokuDeployOptions; } async run() { - //load options from json - this.options = util.getOptionsFromJson(this.options); + //Load options from json, and overwrite with cli options + this.options = { + ...util.getOptionsFromJson(this.options), + ...this.options + }; // Possibilities: // 'stage|zip' @@ -34,15 +35,16 @@ export class ExecCommand { } if (this.actions.includes('delete')) { - await rokuDeploy.deleteDevChannel(this.options); + // defaults -> config -> cli options + await rokuDeploy.deleteDevChannel(this.options as DeleteDevChannelOptions); } if (this.actions.includes('close')) { - await rokuDeploy.closeChannel(this.options); + await rokuDeploy.closeChannel(this.options as CloseChannelOptions); } if (this.actions.includes('sideload')) { - await rokuDeploy.sideload(this.options); + await rokuDeploy.sideload(this.options as SideloadOptions); } if (this.actions.includes('stage')) { @@ -50,15 +52,15 @@ export class ExecCommand { } if (this.actions.includes('rekey')) { - await rokuDeploy.rekeyDevice(this.options); + await rokuDeploy.rekeyDevice(this.options as RekeyDeviceOptions); } if (this.actions.includes('squash')) { - await rokuDeploy.convertToSquashfs(this.options); + await rokuDeploy.convertToSquashfs(this.options as ConvertToSquashfsOptions); } if (this.actions.includes('sign')) { - await rokuDeploy.createSignedPackage(this.options); + await rokuDeploy.createSignedPackage(this.options as CreateSignedPackageOptions); } diff --git a/src/commands/KeyDownCommand.ts b/src/commands/KeyDownCommand.ts new file mode 100644 index 0000000..3936e8a --- /dev/null +++ b/src/commands/KeyDownCommand.ts @@ -0,0 +1,7 @@ +import { rokuDeploy } from '../index'; + +export class KeyDownCommand { + async run(args) { + await rokuDeploy.keyDown(args.text); + } +} diff --git a/src/commands/KeyPressCommand.ts b/src/commands/KeyPressCommand.ts new file mode 100644 index 0000000..7cf1e0b --- /dev/null +++ b/src/commands/KeyPressCommand.ts @@ -0,0 +1,7 @@ +import { rokuDeploy } from '../index'; + +export class KeyPressCommand { + async run(args) { + await rokuDeploy.keyPress(args.text); + } +} diff --git a/src/commands/KeyUpCommand.ts b/src/commands/KeyUpCommand.ts new file mode 100644 index 0000000..5e7e66d --- /dev/null +++ b/src/commands/KeyUpCommand.ts @@ -0,0 +1,7 @@ +import { rokuDeploy } from '../index'; + +export class KeyUpCommand { + async run(args) { + await rokuDeploy.keyUp(args.text); + } +} diff --git a/src/commands/TextCommand.ts b/src/commands/SendTextCommand.ts similarity index 87% rename from src/commands/TextCommand.ts rename to src/commands/SendTextCommand.ts index 5408ef8..a71db16 100644 --- a/src/commands/TextCommand.ts +++ b/src/commands/SendTextCommand.ts @@ -1,6 +1,6 @@ import { rokuDeploy } from '../index'; -export class TextCommand { +export class SendTextCommand { // this.options = getDefaultArgsFromJson(this.configPath ?? `${cwd}/rokudeploy.json`);TODO async run(args) { await rokuDeploy.sendText(args.text); From 8d4e537368ffbfd80b9d0d05bd6b2839d6adbc25 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 4 Mar 2024 23:24:24 -0500 Subject: [PATCH 40/93] change defaults from json function, fix some tests --- src/RokuDeploy.spec.ts | 756 +++++++++++++++++++++++++++++++++++------ src/RokuDeploy.ts | 6 +- src/util.ts | 40 ++- 3 files changed, 683 insertions(+), 119 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 54c644e..02ef5de 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -11,7 +11,7 @@ import * as glob from 'glob'; import { RokuDeploy } from './RokuDeploy'; import * as errors from './Errors'; import { util, standardizePath as s, standardizePathPosix as sp } from './util'; -import type { RokuDeployOptions } from './RokuDeployOptions'; +import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; import { cwd, expectPathExists, expectPathNotExists, expectThrowsAsync, outDir, rootDir, stagingDir, tempDir, writeFiles } from './testUtils.spec'; import { createSandbox } from 'sinon'; import * as r from 'postman-request'; @@ -31,9 +31,6 @@ describe('index', () => { beforeEach(() => { rokuDeploy = new RokuDeploy(); - - rokuDeploy.convertToSquashfs - options = rokuDeploy.getOptions({ rootDir: rootDir, outDir: outDir, @@ -640,7 +637,7 @@ describe('index', () => { return Promise.resolve(); }); - sinon.stub(util, 'getFilePaths').returns( + sinon.stub(rokuDeploy, 'getFilePaths').returns( Promise.resolve([ { src: s`${rootDir}/source/main.brs`, @@ -726,7 +723,7 @@ describe('index', () => { process.nextTick(callback, new Error()); return {} as any; }); - return rokuDeploy.pressHomeButton({}).then(() => { + return rokuDeploy.keyPress({ ...options, host: '1.2.3.4', key: 'home' }).then(() => { assert.fail('Should have rejected the promise'); }, () => { expect(true).to.be.true; @@ -740,7 +737,7 @@ describe('index', () => { resolve(); }); }); - await rokuDeploy.pressHomeButton('1.2.3.4'); + await rokuDeploy.keyPress({ ...options, host: '1.2.3.4', key: 'home' }); await promise; }); @@ -751,7 +748,7 @@ describe('index', () => { resolve(); }); }); - await rokuDeploy.pressHomeButton('1.2.3.4', 987); + await rokuDeploy.keyPress({ ...options, host: '1.2.3.4', remotePort: 987, key: 'home' }); await promise; }); @@ -763,7 +760,7 @@ describe('index', () => { resolve(); }); }); - await rokuDeploy.pressHomeButton('1.2.3.4'); + await rokuDeploy.keyPress({ ...options, host: '1.2.3.4', key: 'home' }); await promise; }); @@ -776,7 +773,7 @@ describe('index', () => { resolve(); }); }); - await rokuDeploy.pressHomeButton('1.2.3.4', 987, 1000); + await rokuDeploy.keyPress({ ...options, host: '1.2.3.4', remotePort: 987, key: 'home', timeout: 1000 }); await promise; }); }); @@ -1741,7 +1738,7 @@ describe('index', () => { let stagingDirValue = rokuDeploy.getOptions(opts).stagingDir; //getFilePaths detects the file - expect(await util.getFilePaths(['renamed_test.md'], opts.rootDir)).to.eql([{ + expect(await rokuDeploy.getFilePaths(['renamed_test.md'], opts.rootDir)).to.eql([{ src: s`${opts.rootDir}/renamed_test.md`, dest: s`renamed_test.md` }]); @@ -1786,7 +1783,7 @@ describe('index', () => { let stagingPath = rokuDeploy.getOptions(opts).stagingDir; //getFilePaths detects the file expect( - (await util.getFilePaths(opts.files, opts.rootDir)).sort((a, b) => a.src.localeCompare(b.src)) + (await rokuDeploy.getFilePaths(opts.files, opts.rootDir)).sort((a, b) => a.src.localeCompare(b.src)) ).to.eql([{ src: s`${tempDir}/mainProject/source/lib/lib.brs`, dest: s`source/lib/lib.brs` @@ -2007,72 +2004,6 @@ describe('index', () => { }); }); - describe('deploy', () => { - it('does the whole migration', async () => { - fsExtra.outputFileSync(s`${rootDir}/manifest`, ''); - mockDoPostRequest(); - - writeFiles(rootDir, ['manifest']); - - let result = await rokuDeploy.deploy({ - rootDir: rootDir, - host: '1.2.3.4', - password: 'password' - }); - expect(result).not.to.be.undefined; - }); - - it('continues with deploy if deleteDevChannel fails', async () => { - sinon.stub(rokuDeploy, 'deleteDevChannel').returns( - Promise.reject( - new Error('failed') - ) - ); - mockDoPostRequest(); - let result = await rokuDeploy.deploy({ - host: '1.2.3.4', - password: 'password', - ...options, - //something in the previous test is locking the default output zip file. We should fix that at some point... - outDir: s`${tempDir}/test1` - }); - expect(result).not.to.be.undefined; - }); - - it('should delete installed channel if requested', async () => { - fsExtra.outputFileSync(s`${rootDir}/manifest`, ''); - - const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); - options.deleteInstalledChannel = true; - mockDoPostRequest(); - - await rokuDeploy.deploy({ - rootDir: rootDir, - host: '1.2.3.4', - password: 'password', - deleteInstalledChannel: true - }); - - expect(spy.called).to.equal(true); - }); - - it('should not delete installed channel if not requested', async () => { - fsExtra.outputFileSync(s`${rootDir}/manifest`, ''); - - const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); - mockDoPostRequest(); - - await rokuDeploy.deploy({ - rootDir: rootDir, - host: '1.2.3.4', - password: 'password', - deleteInstalledChannel: false - }); - - expect(spy.notCalled).to.equal(true); - }); - }); - describe('deleteInstalledChannel', () => { it('attempts to delete any installed dev channel on the device', async () => { mockDoPostRequest(); @@ -2332,12 +2263,12 @@ describe('index', () => { }); }); - describe('zipFolder', () => { + describe('makeZip', () => { //this is mainly done to hit 100% coverage, but why not ensure the errors are handled properly? :D it('rejects the promise when an error occurs', async () => { //zip path doesn't exist await assertThrowsAsync(async () => { - await rokuDeploy.zipFolder('source', '.tmp/some/zip/path/that/does/not/exist'); + await rokuDeploy['makeZip']('source', '.tmp/some/zip/path/that/does/not/exist'); }); }); @@ -2362,7 +2293,7 @@ describe('index', () => { const outputZipPath = path.join(tempDir, 'output.zip'); const addedManifestLine = 'bs_libs_required=roku_ads_lib'; - await rokuDeploy.zipFolder(stageFolder, outputZipPath, (file, data) => { + await rokuDeploy['makeZip'](stageFolder, outputZipPath, (file, data) => { if (file.dest === 'manifest') { let manifestContents = data.toString(); manifestContents += addedManifestLine; @@ -2397,7 +2328,7 @@ describe('index', () => { writeFiles(stagingDir, files); const outputZipPath = path.join(tempDir, 'output.zip'); - await rokuDeploy.zipFolder(stagingDir, outputZipPath, null, ['**/*', '!**/*.map']); + await rokuDeploy['makeZip'](stagingDir, outputZipPath, null, ['**/*', '!**/*.map']); const data = fsExtra.readFileSync(outputZipPath); const zip = await JSZip.loadAsync(data); @@ -2415,6 +2346,648 @@ describe('index', () => { }); }); + describe('getFilePaths', () => { + const otherProjectName = 'otherProject'; + const otherProjectDir = sp`${rootDir}/../${otherProjectName}`; + //create baseline project structure + beforeEach(() => { + rokuDeploy = new RokuDeploy(); + options = rokuDeploy.getOptions({}); + fsExtra.ensureDirSync(`${rootDir}/components/emptyFolder`); + writeFiles(rootDir, [ + `manifest`, + `source/main.brs`, + `source/lib.brs`, + `components/component1.xml`, + `components/component1.brs`, + `components/screen1/screen1.xml`, + `components/screen1/screen1.brs` + ]); + }); + + async function getFilePaths(files: FileEntry[], rootDirOverride = rootDir) { + return (await rokuDeploy.getFilePaths(files, rootDirOverride)) + .sort((a, b) => a.src.localeCompare(b.src)); + } + + describe('top-level-patterns', () => { + it('excludes a file that is negated', async () => { + expect(await getFilePaths([ + 'source/**/*', + '!source/main.brs' + ])).to.eql([{ + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }]); + }); + + it('excludes file from non-rootdir top-level pattern', async () => { + writeFiles(rootDir, ['../externalDir/source/main.brs']); + expect(await getFilePaths([ + '../externalDir/**/*', + '!../externalDir/**/*' + ])).to.eql([]); + }); + + it('throws when using top-level string referencing file outside the root dir', async () => { + writeFiles(rootDir, [`../source/main.brs`]); + await expectThrowsAsync(async () => { + await getFilePaths([ + '../source/**/*' + ]); + }, 'Cannot reference a file outside of rootDir when using a top-level string. Please use a src;des; object instead'); + }); + + it('works for brighterscript files', async () => { + writeFiles(rootDir, ['src/source/main.bs']); + expect(await getFilePaths([ + 'manifest', + 'source/**/*.bs' + ], s`${rootDir}/src`)).to.eql([{ + src: s`${rootDir}/src/source/main.bs`, + dest: s`source/main.bs` + }]); + }); + + it('works for root-level double star in top-level pattern', async () => { + expect(await getFilePaths([ + '**/*' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, + { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, + { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, + { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, + { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, + { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('works for multile entries', async () => { + expect(await getFilePaths([ + 'source/**/*', + 'components/**/*', + 'manifest' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('copies top-level-string single-star globs', async () => { + writeFiles(rootDir, [ + 'source/lib.brs', + 'source/main.brs' + ]); + expect(await getFilePaths([ + 'source/*.brs' + ])).to.eql([{ + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('works for double-star globs', async () => { + expect(await getFilePaths([ + '**/*.brs' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('copies subdir-level relative double-star globs', async () => { + expect(await getFilePaths([ + 'components/**/*.brs' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }]); + }); + + it('Finds folder using square brackets glob pattern', async () => { + fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); + expect(await getFilePaths([ + '[test]/*' + ], + rootDir + )).to.eql([{ + src: s`${rootDir}/e/file.brs`, + dest: s`e/file.brs` + }]); + }); + + it('Finds folder with escaped square brackets glob pattern as name', async () => { + fsExtra.outputFileSync(`${rootDir}/[test]/file.brs`, ''); + fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); + expect(await getFilePaths([ + '\\[test\\]/*' + ], + rootDir + )).to.eql([{ + src: s`${rootDir}/[test]/file.brs`, + dest: s`[test]/file.brs` + }]); + }); + + it('throws exception when top-level strings reference files not under rootDir', async () => { + writeFiles(otherProjectDir, [ + 'manifest' + ]); + await expectThrowsAsync( + getFilePaths([ + `../${otherProjectName}/**/*` + ]) + ); + }); + + it('applies negated patterns', async () => { + expect(await getFilePaths([ + //include all components + 'components/**/*.brs', + //exclude all xml files + '!components/**/*.xml', + //re-include a specific xml file + 'components/screen1/screen1.xml' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }]); + }); + + it('handles negated multi-globs', async () => { + expect((await getFilePaths([ + 'components/**/*', + '!components/screen1/**/*' + ])).map(x => x.dest)).to.eql([ + s`components/component1.brs`, + s`components/component1.xml` + ]); + }); + + it('allows negating paths outside rootDir without requiring src;dest; syntax', async () => { + fsExtra.outputFileSync(`${rootDir}/../externalLib/source/lib.brs`, ''); + const filePaths = await getFilePaths([ + 'source/**/*', + { src: '../externalLib/**/*', dest: 'source' }, + '!../externalLib/source/**/*' + ], rootDir); + expect( + filePaths.map(x => s`${x.src}`).sort() + ).to.eql([ + s`${rootDir}/source/lib.brs`, + s`${rootDir}/source/main.brs` + ]); + }); + + it('applies multi-glob paths relative to rootDir', async () => { + expect(await getFilePaths([ + 'manifest', + 'source/**/*', + 'components/**/*', + '!components/scenes/**/*' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('ignores non-glob folder paths', async () => { + expect(await getFilePaths([ + //this is the folder called "components" + 'components' + ])).to.eql([]); //there should be no matches because rokudeploy ignores folders + }); + + }); + + describe('{src;dest} objects', () => { + it('excludes a file that is negated in src;dest;', async () => { + expect(await getFilePaths([ + 'source/**/*', + { + src: '!source/main.brs' + } + ])).to.eql([{ + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }]); + }); + + it('works for root-level double star in {src;dest} object', async () => { + expect(await getFilePaths([{ + src: '**/*', + dest: '' + } + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, + { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, + { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }, + { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }, + { + src: s`${rootDir}/source/lib.brs`, + dest: s`source/lib.brs` + }, + { + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('uses the root of staging folder for dest when not specified with star star', async () => { + writeFiles(otherProjectDir, [ + 'components/component1/subComponent/screen.brs', + 'manifest', + 'source/thirdPartyLib.brs' + ]); + expect(await getFilePaths([{ + src: `${otherProjectDir}/**/*` + }])).to.eql([{ + src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, + dest: s`components/component1/subComponent/screen.brs` + }, { + src: s`${otherProjectDir}/manifest`, + dest: s`manifest` + }, { + src: s`${otherProjectDir}/source/thirdPartyLib.brs`, + dest: s`source/thirdPartyLib.brs` + }]); + }); + + it('copies absolute path files to specified dest', async () => { + writeFiles(otherProjectDir, [ + 'source/thirdPartyLib.brs' + ]); + expect(await getFilePaths([{ + src: `${otherProjectDir}/source/thirdPartyLib.brs`, + dest: 'lib/thirdPartyLib.brs' + }])).to.eql([{ + src: s`${otherProjectDir}/source/thirdPartyLib.brs`, + dest: s`lib/thirdPartyLib.brs` + }]); + }); + + it('copies relative path files to specified dest', async () => { + const rootDirName = path.basename(rootDir); + writeFiles(rootDir, [ + 'source/main.brs' + ]); + expect(await getFilePaths([{ + src: `../${rootDirName}/source/main.brs`, + dest: 'source/main.brs' + }])).to.eql([{ + src: s`${rootDir}/source/main.brs`, + dest: s`source/main.brs` + }]); + }); + + it('maintains relative path after **', async () => { + writeFiles(otherProjectDir, [ + 'components/component1/subComponent/screen.brs', + 'manifest', + 'source/thirdPartyLib.brs' + ]); + expect(await getFilePaths([{ + src: `../otherProject/**/*`, + dest: 'outFolder/' + }])).to.eql([{ + src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, + dest: s`outFolder/components/component1/subComponent/screen.brs` + }, { + src: s`${otherProjectDir}/manifest`, + dest: s`outFolder/manifest` + }, { + src: s`${otherProjectDir}/source/thirdPartyLib.brs`, + dest: s`outFolder/source/thirdPartyLib.brs` + }]); + }); + + it('works for other globs', async () => { + expect(await getFilePaths([{ + src: `components/screen1/*creen1.brs`, + dest: s`/source` + }])).to.eql([{ + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`source/screen1.brs` + }]); + }); + + it('applies negated patterns', async () => { + writeFiles(rootDir, [ + 'components/component1.brs', + 'components/component1.xml', + 'components/screen1/screen1.brs', + 'components/screen1/screen1.xml' + ]); + expect(await getFilePaths([ + //include all component brs files + 'components/**/*.brs', + //exclude all xml files + '!components/**/*.xml', + //re-include a specific xml file + 'components/screen1/screen1.xml' + ])).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.brs`, + dest: s`components/screen1/screen1.brs` + }, { + src: s`${rootDir}/components/screen1/screen1.xml`, + dest: s`components/screen1/screen1.xml` + }]); + }); + }); + + it('converts relative rootDir path to absolute', async () => { + let stub = sinon.stub(rokuDeploy, 'getOptions').callThrough(); + await getFilePaths([ + 'source/main.brs' + ], './rootDir'); + expect(stub.callCount).to.be.greaterThan(0); + expect(stub.getCall(0).args[0].rootDir).to.eql('./rootDir'); + expect(stub.getCall(0).returnValue.rootDir).to.eql(s`${cwd}/rootDir`); + }); + + it('works when using a different current working directory than rootDir', async () => { + writeFiles(rootDir, [ + 'manifest', + 'images/splash_hd.jpg' + ]); + //sanity check, make sure it works without fiddling with cwd intact + let paths = await getFilePaths([ + 'manifest', + 'images/splash_hd.jpg' + ]); + + expect(paths).to.eql([{ + src: s`${rootDir}/images/splash_hd.jpg`, + dest: s`images/splash_hd.jpg` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }]); + + //change the working directory and verify everything still works + + let wrongCwd = path.dirname(path.resolve(options.rootDir)); + process.chdir(wrongCwd); + + paths = await getFilePaths([ + 'manifest', + 'images/splash_hd.jpg' + ]); + + expect(paths).to.eql([{ + src: s`${rootDir}/images/splash_hd.jpg`, + dest: s`images/splash_hd.jpg` + }, { + src: s`${rootDir}/manifest`, + dest: s`manifest` + }]); + }); + + it('supports absolute paths from outside of the rootDir', async () => { + //dest not specified + expect(await getFilePaths([{ + src: sp`${cwd}/README.md` + }], options.rootDir)).to.eql([{ + src: s`${cwd}/README.md`, + dest: s`README.md` + }]); + + //dest specified + expect(await getFilePaths([{ + src: sp`${cwd}/README.md`, + dest: 'docs/README.md' + }], options.rootDir)).to.eql([{ + src: s`${cwd}/README.md`, + dest: s`docs/README.md` + }]); + + let paths: any[]; + + paths = await getFilePaths([{ + src: sp`${cwd}/README.md`, + dest: s`docs/README.md` + }], outDir); + + expect(paths).to.eql([{ + src: s`${cwd}/README.md`, + dest: s`docs/README.md` + }]); + + //top-level string paths pointing to files outside the root should thrown an exception + await expectThrowsAsync(async () => { + paths = await getFilePaths([ + sp`${cwd}/README.md` + ], outDir); + }); + }); + + it('supports relative paths that grab files from outside of the rootDir', async () => { + writeFiles(`${rootDir}/../`, [ + 'README.md' + ]); + expect( + await getFilePaths([{ + src: sp`../README.md` + }], rootDir) + ).to.eql([{ + src: s`${rootDir}/../README.md`, + dest: s`README.md` + }]); + + expect( + await getFilePaths([{ + src: sp`../README.md`, + dest: 'docs/README.md' + }], rootDir) + ).to.eql([{ + src: s`${rootDir}/../README.md`, + dest: s`docs/README.md` + }]); + }); + + it('should throw exception because we cannot have top-level string paths pointed to files outside the root', async () => { + writeFiles(rootDir, [ + '../README.md' + ]); + await expectThrowsAsync( + getFilePaths([ + path.posix.join('..', 'README.md') + ], outDir) + ); + }); + + it('supports overriding paths', async () => { + let paths = await getFilePaths([{ + src: sp`${rootDir}/components/component1.brs`, + dest: 'comp1.brs' + }, { + src: sp`${rootDir}/components/screen1/screen1.brs`, + dest: 'comp1.brs' + }], rootDir); + expect(paths).to.be.lengthOf(1); + expect(s`${paths[0].src}`).to.equal(s`${rootDir}/components/screen1/screen1.brs`); + }); + + it('supports overriding paths from outside the root dir', async () => { + let thisRootDir = s`${tempDir}/tempTestOverrides/src`; + try { + + fsExtra.ensureDirSync(s`${thisRootDir}/source`); + fsExtra.ensureDirSync(s`${thisRootDir}/components`); + fsExtra.ensureDirSync(s`${thisRootDir}/../.tmp`); + + fsExtra.writeFileSync(s`${thisRootDir}/source/main.brs`, ''); + fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.brs`, ''); + fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.xml`, ''); + fsExtra.writeFileSync(s`${thisRootDir}/../.tmp/MainScene.brs`, ''); + + let files = [ + '**/*.xml', + '**/*.brs', + { + src: '../.tmp/MainScene.brs', + dest: 'components/MainScene.brs' + } + ]; + let paths = await getFilePaths(files, thisRootDir); + + //the MainScene.brs file from source should NOT be included + let mainSceneEntries = paths.filter(x => s`${x.dest}` === s`components/MainScene.brs`); + expect( + mainSceneEntries, + `Should only be one files entry for 'components/MainScene.brs'` + ).to.be.lengthOf(1); + expect(s`${mainSceneEntries[0].src}`).to.eql(s`${thisRootDir}/../.tmp/MainScene.brs`); + } finally { + //clean up + await fsExtra.remove(s`${thisRootDir}/../`); + } + }); + + it('maintains original file path', async () => { + fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); + expect( + await getFilePaths([ + 'components/CustomButton.brs' + ], rootDir) + ).to.eql([{ + src: s`${rootDir}/components/CustomButton.brs`, + dest: s`components/CustomButton.brs` + }]); + }); + + it('correctly assumes file path if not given', async () => { + fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); + expect( + (await getFilePaths([ + { src: 'components/*' } + ], rootDir)).sort((a, b) => a.src.localeCompare(b.src)) + ).to.eql([{ + src: s`${rootDir}/components/component1.brs`, + dest: s`components/component1.brs` + }, { + src: s`${rootDir}/components/component1.xml`, + dest: s`components/component1.xml` + }, { + src: s`${rootDir}/components/CustomButton.brs`, + dest: s`components/CustomButton.brs` + }]); + }); + }); + describe('parseManifest', () => { it('correctly parses valid manifest', async () => { fsExtra.outputFileSync(`${rootDir}/manifest`, `title=AwesomeApp`); @@ -2456,7 +3029,7 @@ describe('index', () => { describe('stringifyManifest', () => { it('correctly converts back to a valid manifest when lineNumber and keyIndexes are provided', () => { expect( - rokuDeploy.stringifyManifest( + rokuDeploy['stringifyManifest']( rokuDeploy['parseManifestFromString']('major_version=3\nminor_version=4') ) ).to.equal( @@ -2469,7 +3042,7 @@ describe('index', () => { delete parsed.keyIndexes; delete parsed.lineCount; let outputParsedManifest = rokuDeploy['parseManifestFromString']( - rokuDeploy.stringifyManifest(parsed) + rokuDeploy['stringifyManifest'](parsed) ); expect(outputParsedManifest.title).to.equal('App'); expect(outputParsedManifest.major_version).to.equal('3'); @@ -2503,21 +3076,6 @@ describe('index', () => { }); describe('getOptions', () => { - it('supports deprecated stagingFolderPath option', () => { - sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { - return false; - }); - expect( - rokuDeploy.getOptions({ stagingFolderPath: 'staging-folder-path' }).stagingDir - ).to.eql(s`${cwd}/staging-folder-path`); - expect( - rokuDeploy.getOptions({ stagingFolderPath: 'staging-folder-path', stagingDir: 'staging-dir' }).stagingDir - ).to.eql(s`${cwd}/staging-dir`); - expect( - rokuDeploy.getOptions({ stagingFolderPath: 'staging-folder-path' }).stagingFolderPath - ).to.eql(s`${cwd}/staging-folder-path`); - }); - it('calling with no parameters works', () => { sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { return false; diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 7e60204..1185a90 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -7,8 +7,7 @@ const request = r as typeof requestType; import * as JSZip from 'jszip'; import * as errors from './Errors'; import * as xml2js from 'xml2js'; -import type { ParseError } from 'jsonc-parser'; -import { parse as parseJsonc, printParseErrorCode } from 'jsonc-parser'; +import { parse as parseJsonc } from 'jsonc-parser'; import { util } from './util'; import type { RokuDeployOptions, FileEntry } from './RokuDeployOptions'; import { Logger, LogLevel } from './Logger'; @@ -24,9 +23,6 @@ export class RokuDeploy { private logger: Logger; - //this should just - // public screenshotDir = path.join(tempDir, '/roku-deploy/screenshots/'); - /** * Copies all of the referenced files to the staging folder * @param options diff --git a/src/util.ts b/src/util.ts index 7c1846d..9254027 100644 --- a/src/util.ts +++ b/src/util.ts @@ -9,6 +9,7 @@ import type { FileEntry } from './RokuDeployOptions'; import type { StandardizedFileEntry } from './RokuDeploy'; import * as isGlob from 'is-glob'; import * as picomatch from 'picomatch'; +import { ParseError, parse as parseJsonc, printParseErrorCode } from 'jsonc-parser'; export class Util { /** @@ -485,24 +486,33 @@ export class Util { /** * A function to fill in any missing arguments with JSON values + * Only run when CLI commands are used */ - public getOptionsFromJson(defaultArgs) {//TODO: The original function handled parse errors, but this one doesn't - let args = { ...defaultArgs }; - const fileNames = ['rokudeploy.json', 'bsconfig.json']; - - for (const fileName of fileNames) { - if (fsExtra.existsSync(fileName)) { - const sourcePath = path.join(defaultArgs.rootDir, fileName); - const rokuDeployArgs = JSON.parse(fsExtra.readFileSync(sourcePath, 'utf8')); - // args = Object.assign(rokudeployArgs ?? {}, args); - args = Object.assign(rokuDeployArgs, args); - break; - } + public getOptionsFromJson(options?: { cwd?: string }) { + let fileOptions: RokuDeployOptions = {}; + const cwd = options?.cwd ?? process.cwd(); + const configPath = path.join(cwd, 'rokudeploy.json'); + + let configFileText = fsExtra.readFileSync(configPath).toString(); + let parseErrors = [] as ParseError[]; + fileOptions = parseJsonc(configFileText, parseErrors, { + allowEmptyContent: true, + allowTrailingComma: true, + disallowComments: false + }); + if (parseErrors.length > 0) { + throw new Error(`Error parsing "${path.resolve(configPath)}": ` + JSON.stringify( + parseErrors.map(x => { + return { + message: printParseErrorCode(x.error), + offset: x.offset, + length: x.length + }; + }) + )); } - - return args; + return fileOptions; } - } export let util = new Util(); From 1d75b10f7c7014fde0eb63c34e53d4b9ae8bb7f1 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 4 Mar 2024 23:27:42 -0500 Subject: [PATCH 41/93] fix index, fix makezip, getfilepaths, sideload --- src/RokuDeploy.ts | 150 ++++++++++++++++++++++++++-------------------- src/index.ts | 5 -- src/util.ts | 48 +-------------- 3 files changed, 87 insertions(+), 116 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 1185a90..a6c81f7 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -14,6 +14,7 @@ import { Logger, LogLevel } from './Logger'; import * as dayjs from 'dayjs'; import * as lodash from 'lodash'; import type { DeviceInfo, DeviceInfoRaw } from './DeviceInfo'; +import * as tempDir from 'temp-dir'; export class RokuDeploy { @@ -44,7 +45,7 @@ export class RokuDeploy { throw new Error(`rootDir does not exist at "${options.rootDir}"`); } - let fileObjects = await util.getFilePaths(options.files, options.rootDir); + let fileObjects = await this.getFilePaths(options.files, options.rootDir); //copy all of the files await Promise.all(fileObjects.map(async (fileObject) => { let destFilePath = util.standardizePath(`${options.stagingDir}/${fileObject.dest}`); @@ -82,7 +83,7 @@ export class RokuDeploy { } //create a zip of the staging folder - await this.__makeZip(options.stagingDir, zipFilePath); + await this.makeZip(options.stagingDir, zipFilePath); } /** @@ -92,8 +93,8 @@ export class RokuDeploy { * @param preZipCallback a function to call right before every file gets added to the zip * @param files a files array used to filter the files from `srcFolder` */ - private async __makeZip(srcFolder: string, zipFilePath: string, preFileZipCallback?: (file: StandardizedFileEntry, data: Buffer) => Buffer, files: FileEntry[] = ['**/*']) { - const filePaths = await util.getFilePaths(files, srcFolder); + private async makeZip(srcFolder: string, zipFilePath: string, preFileZipCallback?: (file: StandardizedFileEntry, data: Buffer) => Buffer, files: FileEntry[] = ['**/*']) { + const filePaths = await this.getFilePaths(files, srcFolder); const zip = new JSZip(); // Allows us to wait until all are done before we build the zip @@ -122,6 +123,49 @@ export class RokuDeploy { return fsExtra.writeFile(zipFilePath, content); } + /** + * Get all file paths for the specified options + * @param files + * @param rootFolderPath - the absolute path to the root dir where relative files entries are relative to + */ + public async getFilePaths(files: FileEntry[], rootDir: string): Promise { + //if the rootDir isn't absolute, convert it to absolute using the standard options flow + if (path.isAbsolute(rootDir) === false) { + rootDir = this.getOptions({ rootDir: rootDir }).rootDir; + } + const entries = util.normalizeFilesArray(files); + const srcPathsByIndex = await util.globAllByIndex( + entries.map(x => { + return typeof x === 'string' ? x : x.src; + }), + rootDir + ); + + /** + * Result indexed by the dest path + */ + let result = new Map(); + + //compute `dest` path for every file + for (let i = 0; i < srcPathsByIndex.length; i++) { + const srcPaths = srcPathsByIndex[i]; + const entry = entries[i]; + if (srcPaths) { + for (let srcPath of srcPaths) { + srcPath = util.standardizePath(srcPath); + + const dest = util.computeFileDestPath(srcPath, entry, rootDir); + //the last file with this `dest` will win, so just replace any existing entry with this one. + result.set(dest, { + src: srcPath, + dest: dest + }); + } + } + } + return [...result.values()]; + } + private generateBaseRequestOptions(requestPath: string, options: BaseRequestOptions, formData = {} as T): requestType.OptionsWithUrl { options = this.getOptions(options) as any; let url = `http://${options.host}:${options.packagePort}/${requestPath}`; @@ -188,18 +232,25 @@ export class RokuDeploy { }, false); } - public async closeChannel(options: CloseAppOptions) { - //TODO - - //if supports ecp close-app, then do that (twice so it kills instant resume) - //else, send home press + public async closeChannel(options: CloseChannelOptions) { + // TODO: After 13.0 releases, add check for ECP close-app support, and use that if available + await this.sendKeyEvent({ + ...options, + action: 'keypress', + key: 'home' + }); + return this.sendKeyEvent({ + ...options, + action: 'keypress', + key: 'home' + }); } /** * Publish a pre-existing packaged zip file to a remote Roku. * @param options */ - public async sideload(options: PublishOptions): Promise<{ message: string; results: any }> { + public async sideload(options: SideloadOptions): Promise<{ message: string; results: any }> { options = this.getOptions(options) as any; if (!options.host) { throw new errors.MissingRequiredOptionError('must specify the host for the Roku device'); @@ -209,7 +260,7 @@ export class RokuDeploy { let zipFilePath = this.getOutputZipFilePath(options as any); - if (options.deleteInstalledChannel) { + if (options.deleteDevChannel) { try { await this.deleteDevChannel(options); } catch (e) { @@ -567,8 +618,8 @@ export class RokuDeploy { * Gets a screenshot from the device. A side-loaded channel must be running or an error will be thrown. */ public async captureScreenshot(options: TakeScreenshotOptions) { - options.outDir = options.outDir ?? this.screenshotDir; - options.outFile = options.outFile ?? `screenshot-${dayjs().format('YYYY-MM-DD-HH.mm.ss.SSS')}`; + options = this.getOptions(options); + options.screenshotFile = options.screenshotFile ?? `screenshot-${dayjs().format('YYYY-MM-DD-HH.mm.ss.SSS')}`; let saveFilePath: string; // Ask for the device to make an image @@ -584,13 +635,13 @@ export class RokuDeploy { const [_, imageUrlOnDevice, imageExt] = /["'](pkgs\/dev(\.jpg|\.png)\?.+?)['"]/gi.exec(createScreenshotResult.body) ?? []; if (imageUrlOnDevice) { - saveFilePath = util.standardizePath(path.join(options.outDir, options.outFile + imageExt)); + saveFilePath = util.standardizePath(path.join(options.screenshotDir, options.screenshotFile + imageExt)); await this.getToFile( this.generateBaseRequestOptions(imageUrlOnDevice, options), saveFilePath ); } else { - throw new Error('No screen shot url returned from device'); + throw new Error('No screenshot url returned from device'); } return saveFilePath; } @@ -631,13 +682,12 @@ export class RokuDeploy { } /** - * Get an options with all overridden vaues, and then defaults for missing values + * Get an options with all overridden values, and then defaults for missing values * @param options */ - private __getOptions(options: RokuDeployOptions = {}) { - let fileOptions: RokuDeployOptions = {}; - + public getOptions(options: T & RokuDeployOptions = {} as any): RokuDeployOptions & T { let defaultOptions = { + cwd: process.cwd(), outDir: './out', outFile: 'roku-deploy', stagingDir: `./out/.roku-deploy-staging`, @@ -651,25 +701,25 @@ export class RokuDeploy { rootDir: './', files: [...DefaultFiles], username: 'rokudev', - logLevel: LogLevel.log + logLevel: LogLevel.log, + screenshotDir: path.join(tempDir, '/roku-deploy/screenshots/') }; - //override the defaults with any found or provided options - let finalOptions = { ...defaultOptions, ...fileOptions, ...options }; - this.logger.logLevel = finalOptions.logLevel; + // Fill in default options for any missing values + let finalOptions = { ...defaultOptions, ...options }; + finalOptions.cwd ??= process.cwd(); + this.logger.logLevel = finalOptions.logLevel; //TODO: Handle logging differently //fully resolve the folder paths - finalOptions.rootDir = path.resolve(process.cwd(), finalOptions.rootDir); - finalOptions.outDir = path.resolve(process.cwd(), finalOptions.outDir); - - let stagingDir = finalOptions.stagingDir || finalOptions.stagingFolderPath; + finalOptions.rootDir = path.resolve(options.cwd, finalOptions.rootDir); + finalOptions.outDir = path.resolve(options.cwd, finalOptions.outDir); //stagingDir if (options.stagingDir) { finalOptions.stagingDir = path.resolve(options.cwd, options.stagingDir); } else { finalOptions.stagingDir = path.resolve( - process.cwd(), + options.cwd, util.standardizePath(`${finalOptions.outDir}/.roku-deploy-staging`) ); } @@ -782,7 +832,6 @@ export class RokuDeploy { } /** - * TODO we might delete this one. let chris think about it. ;) * @param options * @returns */ @@ -791,9 +840,6 @@ export class RokuDeploy { return deviceInfo['keyed-developer-id']; } - /** - * TODO move these manifest functions to a util somewhere - */ private async parseManifest(manifestPath: string): Promise { if (!await fsExtra.pathExists(manifestPath)) { throw new Error(manifestPath + ' does not exist'); @@ -803,9 +849,6 @@ export class RokuDeploy { return this.parseManifestFromString(manifestContents); } - /** - * TODO move these manifest functions to a util somewhere - */ private parseManifestFromString(manifestContents: string): ManifestData { let manifestLines = manifestContents.split('\n'); let manifestData: ManifestData = {}; @@ -822,33 +865,6 @@ export class RokuDeploy { return manifestData; } - - /** - * TODO move these manifest functions to a util somewhere - */ - public stringifyManifest(manifestData: ManifestData): string { - let output = []; - - if (manifestData.keyIndexes && manifestData.lineCount) { - output.fill('', 0, manifestData.lineCount); - - let key; - for (key in manifestData) { - if (key === 'lineCount' || key === 'keyIndexes') { - continue; - } - - let index = manifestData.keyIndexes[key]; - output[index] = `${key}=${manifestData[key]}`; - } - } else { - output = Object.keys(manifestData).map((key) => { - return `${key}=${manifestData[key]}`; - }); - } - - return output.join('\n'); - } } export interface ManifestData { @@ -919,13 +935,13 @@ export interface TakeScreenshotOptions { * A full path to the folder where the screenshots should be saved. * Will use the OS temp directory by default */ - outDir?: string; + screenshotDir?: string; /** * The base filename the image file should be given (excluding the extension) * The default format looks something like this: screenshot-YYYY-MM-DD-HH.mm.ss.SSS. */ - outFile?: string; + screenshotFile?: string; } export interface GetDeviceInfoOptions { @@ -960,7 +976,7 @@ export interface ZipPackageOptions { outDir?: string; } -export interface PublishOptions { +export interface SideloadOptions { host: string; password: string; remoteDebug?: boolean; @@ -969,6 +985,7 @@ export interface PublishOptions { retainDeploymentArchive?: boolean; outDir?: string; outFile?: string; + deleteDevChannel?: boolean; } export interface BaseRequestOptions { @@ -1041,3 +1058,6 @@ export interface GetDevIdOptions { */ timeout?: number; } + +//create a new static instance of RokuDeploy, and export those functions for backwards compatibility +export const rokuDeploy = new RokuDeploy(); diff --git a/src/index.ts b/src/index.ts index 8c00ae0..2fc0ec7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,6 @@ -import { RokuDeploy } from './RokuDeploy'; - //export everything from the RokuDeploy file export * from './RokuDeploy'; export * from './util'; export * from './RokuDeployOptions'; export * from './Errors'; export * from './DeviceInfo'; - -//create a new static instance of RokuDeploy, and export those functions for backwards compatibility -export const rokuDeploy = new RokuDeploy(); diff --git a/src/util.ts b/src/util.ts index 9254027..2895b06 100644 --- a/src/util.ts +++ b/src/util.ts @@ -5,7 +5,7 @@ import * as dns from 'dns'; import * as micromatch from 'micromatch'; // eslint-disable-next-line @typescript-eslint/no-require-imports import fastGlob = require('fast-glob'); -import type { FileEntry } from './RokuDeployOptions'; +import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; import type { StandardizedFileEntry } from './RokuDeploy'; import * as isGlob from 'is-glob'; import * as picomatch from 'picomatch'; @@ -283,50 +283,6 @@ export class Util { return result; } - - /** - * Get all file paths for the specified options - * @param files - * @param rootFolderPath - the absolute path to the root dir where relative files entries are relative to - */ - public async getFilePaths(files: FileEntry[], rootDir: string): Promise { - //if the rootDir isn't absolute, convert it to absolute using the standard options flow - if (path.isAbsolute(rootDir) === false) { - rootDir = rokuDeploy.getOptions({ rootDir: rootDir }).rootDir; //TODO: This moved from rokudeploy to here, but if we need to get options how do we fix this? - } - const entries = this.normalizeFilesArray(files); - const srcPathsByIndex = await util.globAllByIndex( - entries.map(x => { - return typeof x === 'string' ? x : x.src; - }), - rootDir - ); - - /** - * Result indexed by the dest path - */ - let result = new Map(); - - //compute `dest` path for every file - for (let i = 0; i < srcPathsByIndex.length; i++) { - const srcPaths = srcPathsByIndex[i]; - const entry = entries[i]; - if (srcPaths) { - for (let srcPath of srcPaths) { - srcPath = util.standardizePath(srcPath); - - const dest = this.computeFileDestPath(srcPath, entry, rootDir); - //the last file with this `dest` will win, so just replace any existing entry with this one. - result.set(dest, { - src: srcPath, - dest: dest - }); - } - } - } - return [...result.values()]; - } - /** * Given a full path to a file, determine its dest path * @param srcPath the absolute path to the file. This MUST be a file path, and it is not verified to exist on the filesystem @@ -388,7 +344,7 @@ export class Util { * @param pattern the glob pattern originally used to find this file * @param rootDir absolute normalized path to the rootDir */ - private computeFileDestPath(srcPath: string, entry: string | StandardizedFileEntry, rootDir: string) { + public computeFileDestPath(srcPath: string, entry: string | StandardizedFileEntry, rootDir: string) { let result: string; let globstarIdx: number; //files under rootDir with no specified dest From 48d07d901b8c70baba2185b68d62db2388b0ea1f Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 5 Mar 2024 12:53:51 -0500 Subject: [PATCH 42/93] Add options from json ability to each command to each command --- src/commands/ConvertToSquashfsCommand.ts | 11 +- src/commands/CreateSignedPackageCommand.ts | 13 +- src/commands/DeleteDevChannelCommand.ts | 11 +- src/commands/ExecCommand.ts | 5 - src/commands/GetDevIdCommand.ts | 10 +- src/commands/GetDeviceInfoCommand.ts | 8 +- src/commands/GetOutputPkgFilePathCommand.ts | 11 +- src/commands/GetOutputZipFilePathCommand.ts | 11 +- src/commands/KeyDownCommand.ts | 8 +- src/commands/KeyPressCommand.ts | 8 +- src/commands/KeyUpCommand.ts | 8 +- src/commands/PrepublishCommand.ts | 11 +- src/commands/PublishCommand.ts | 13 +- src/commands/RekeyDeviceCommand.ts | 15 +- src/commands/SendTextCommand.ts | 9 +- src/commands/TakeScreenshotCommand.ts | 11 +- src/commands/ZipCommand.ts | 11 +- src/util.spec.ts | 690 +------------------- 18 files changed, 111 insertions(+), 753 deletions(-) diff --git a/src/commands/ConvertToSquashfsCommand.ts b/src/commands/ConvertToSquashfsCommand.ts index b1e1e7b..79ebf6e 100644 --- a/src/commands/ConvertToSquashfsCommand.ts +++ b/src/commands/ConvertToSquashfsCommand.ts @@ -1,10 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class ConvertToSquashfsCommand { async run(args) { - await rokuDeploy.convertToSquashfs({ - host: args.host, - password: args.password - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.convertToSquashfs(options); } } diff --git a/src/commands/CreateSignedPackageCommand.ts b/src/commands/CreateSignedPackageCommand.ts index 8488650..904a9fe 100644 --- a/src/commands/CreateSignedPackageCommand.ts +++ b/src/commands/CreateSignedPackageCommand.ts @@ -1,12 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class CreateSignedPackageCommand { async run(args) { - await rokuDeploy.createSignedPackage({ - host: args.host, - password: args.password, - signingPassword: args.signingPassword, - stagingDir: args.stagingDir - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.createSignedPackage(options); } } diff --git a/src/commands/DeleteDevChannelCommand.ts b/src/commands/DeleteDevChannelCommand.ts index 52dd95f..5bfa269 100644 --- a/src/commands/DeleteDevChannelCommand.ts +++ b/src/commands/DeleteDevChannelCommand.ts @@ -1,10 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class DeleteDevChannelCommand { async run(args) { - await rokuDeploy.deleteDevChannel({ - host: args.host, - password: args.password - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.deleteDevChannel(options); } } diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts index 9bdf9ad..5a56b44 100644 --- a/src/commands/ExecCommand.ts +++ b/src/commands/ExecCommand.ts @@ -21,11 +21,6 @@ export class ExecCommand { ...this.options }; - // Possibilities: - // 'stage|zip' - // 'stage|zip|delete|close|sideload' - // 'close|rekey|stage|zip|delete|close|sideload|squash|sign' - if (this.actions.includes('stage')) { await rokuDeploy.stage(this.options); } diff --git a/src/commands/GetDevIdCommand.ts b/src/commands/GetDevIdCommand.ts index 72ccde8..c54c8e6 100644 --- a/src/commands/GetDevIdCommand.ts +++ b/src/commands/GetDevIdCommand.ts @@ -1,9 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class GetDevIdCommand { async run(args) { - await rokuDeploy.getDevId({ - host: args.host - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.getDevId(options); } } diff --git a/src/commands/GetDeviceInfoCommand.ts b/src/commands/GetDeviceInfoCommand.ts index 1bf10b3..3255fe3 100644 --- a/src/commands/GetDeviceInfoCommand.ts +++ b/src/commands/GetDeviceInfoCommand.ts @@ -3,9 +3,11 @@ import { util } from '../util'; export class GetDeviceInfoCommand { async run(args) { - const outputPath = await rokuDeploy.getDeviceInfo({ - host: args.host - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + const outputPath = await rokuDeploy.getDeviceInfo(options); console.log(util.objectToTableString(outputPath)); } } diff --git a/src/commands/GetOutputPkgFilePathCommand.ts b/src/commands/GetOutputPkgFilePathCommand.ts index 0861d1e..3bfc2d0 100644 --- a/src/commands/GetOutputPkgFilePathCommand.ts +++ b/src/commands/GetOutputPkgFilePathCommand.ts @@ -1,12 +1,13 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class GetOutputPkgFilePathCommand { run(args) { + let options = { + ...util.getOptionsFromJson(args), + ...args + }; // eslint-disable-next-line @typescript-eslint/dot-notation - const outputPath = rokuDeploy['getOutputPkgPath']({ - outFile: args.outFile, - outDir: args.outDir - }); + const outputPath = rokuDeploy['getOutputPkgPath'](options); //TODO fix this? console.log(outputPath); } } diff --git a/src/commands/GetOutputZipFilePathCommand.ts b/src/commands/GetOutputZipFilePathCommand.ts index bd9d7de..c5761c0 100644 --- a/src/commands/GetOutputZipFilePathCommand.ts +++ b/src/commands/GetOutputZipFilePathCommand.ts @@ -1,12 +1,13 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class GetOutputZipFilePathCommand { run(args) { + let options = { + ...util.getOptionsFromJson(args), + ...args + }; // eslint-disable-next-line @typescript-eslint/dot-notation - const outputPath = rokuDeploy['getOutputZipFilePath']({ - outFile: args.outFile, - outDir: args.outDir - }); + const outputPath = rokuDeploy['getOutputZipFilePath'](options); console.log(outputPath); } } diff --git a/src/commands/KeyDownCommand.ts b/src/commands/KeyDownCommand.ts index 3936e8a..ae05b91 100644 --- a/src/commands/KeyDownCommand.ts +++ b/src/commands/KeyDownCommand.ts @@ -1,7 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class KeyDownCommand { async run(args) { - await rokuDeploy.keyDown(args.text); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.keyDown(options); } } diff --git a/src/commands/KeyPressCommand.ts b/src/commands/KeyPressCommand.ts index 7cf1e0b..4554df7 100644 --- a/src/commands/KeyPressCommand.ts +++ b/src/commands/KeyPressCommand.ts @@ -1,7 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class KeyPressCommand { async run(args) { - await rokuDeploy.keyPress(args.text); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.keyPress(options); } } diff --git a/src/commands/KeyUpCommand.ts b/src/commands/KeyUpCommand.ts index 5e7e66d..36b71ea 100644 --- a/src/commands/KeyUpCommand.ts +++ b/src/commands/KeyUpCommand.ts @@ -1,7 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class KeyUpCommand { async run(args) { - await rokuDeploy.keyUp(args.text); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.keyUp(options); } } diff --git a/src/commands/PrepublishCommand.ts b/src/commands/PrepublishCommand.ts index 48152ed..e44613b 100644 --- a/src/commands/PrepublishCommand.ts +++ b/src/commands/PrepublishCommand.ts @@ -1,10 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class PrepublishCommand { async run(args) { - await rokuDeploy.stage({ - stagingDir: args.stagingDir, - rootDir: args.rootDir - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.stage(options); } } diff --git a/src/commands/PublishCommand.ts b/src/commands/PublishCommand.ts index 7338471..e365b12 100644 --- a/src/commands/PublishCommand.ts +++ b/src/commands/PublishCommand.ts @@ -1,12 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class PublishCommand { async run(args) { - await rokuDeploy.sideload({ - host: args.host, - password: args.password, - outDir: args.outDir, - outFile: args.outFile - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.sideload(options); } } diff --git a/src/commands/RekeyDeviceCommand.ts b/src/commands/RekeyDeviceCommand.ts index 7098772..ca00fd8 100644 --- a/src/commands/RekeyDeviceCommand.ts +++ b/src/commands/RekeyDeviceCommand.ts @@ -1,14 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class RekeyDeviceCommand { async run(args) { - await rokuDeploy.rekeyDevice({ - host: args.host, - password: args.password, - rekeySignedPackage: args.rekeySignedPackage, - signingPassword: args.signingPassword, - rootDir: args.rootDir, - devId: args.devId - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.rekeyDevice(options); } } diff --git a/src/commands/SendTextCommand.ts b/src/commands/SendTextCommand.ts index a71db16..3e11810 100644 --- a/src/commands/SendTextCommand.ts +++ b/src/commands/SendTextCommand.ts @@ -1,8 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class SendTextCommand { - // this.options = getDefaultArgsFromJson(this.configPath ?? `${cwd}/rokudeploy.json`);TODO async run(args) { - await rokuDeploy.sendText(args.text); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.sendText(options); } } diff --git a/src/commands/TakeScreenshotCommand.ts b/src/commands/TakeScreenshotCommand.ts index 2d9f358..c77ef61 100644 --- a/src/commands/TakeScreenshotCommand.ts +++ b/src/commands/TakeScreenshotCommand.ts @@ -1,10 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class TakeScreenshotCommand { async run(args) { - await rokuDeploy.captureScreenshot({ - host: args.host, - password: args.password - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.captureScreenshot(options); } } diff --git a/src/commands/ZipCommand.ts b/src/commands/ZipCommand.ts index 44b0e12..b03e80d 100644 --- a/src/commands/ZipCommand.ts +++ b/src/commands/ZipCommand.ts @@ -1,10 +1,11 @@ -import { rokuDeploy } from '../index'; +import { rokuDeploy, util } from '../index'; export class ZipCommand { async run(args) { - await rokuDeploy.zip({ - stagingDir: args.stagingDir, - outDir: args.outDir - }); + let options = { + ...util.getOptionsFromJson(args), + ...args + }; + await rokuDeploy.zip(options); } } diff --git a/src/util.spec.ts b/src/util.spec.ts index ea34990..b30032e 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -1,12 +1,10 @@ -import { util, standardizePath as s, standardizePathPosix as sp } from './util'; +import { util, standardizePath as s } from './util'; import { expect } from 'chai'; import * as fsExtra from 'fs-extra'; -import { cwd, tempDir, rootDir, outDir, expectThrowsAsync, writeFiles } from './testUtils.spec'; +import { cwd, tempDir, rootDir } from './testUtils.spec'; import * as path from 'path'; import * as dns from 'dns'; import { createSandbox } from 'sinon'; -import { RokuDeploy } from './RokuDeploy'; -import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; const sinon = createSandbox(); describe('util', () => { @@ -453,608 +451,30 @@ describe('util', () => { }); }); - describe('getFilePaths', () => { - const otherProjectName = 'otherProject'; - const otherProjectDir = sp`${rootDir}/../${otherProjectName}`; - let rokuDeploy: RokuDeploy; - let options: RokuDeployOptions; - //create baseline project structure + describe.only('getOptionsFromJson', () => { beforeEach(() => { - rokuDeploy = new RokuDeploy(); - options = rokuDeploy.getOptions({}); - fsExtra.ensureDirSync(`${rootDir}/components/emptyFolder`); - writeFiles(rootDir, [ - `manifest`, - `source/main.brs`, - `source/lib.brs`, - `components/component1.xml`, - `components/component1.brs`, - `components/screen1/screen1.xml`, - `components/screen1/screen1.brs` - ]); - }); - - async function getFilePaths(files: FileEntry[], rootDirOverride = rootDir) { - return (await util.getFilePaths(files, rootDirOverride)) - .sort((a, b) => a.src.localeCompare(b.src)); - } - - describe('top-level-patterns', () => { - it('excludes a file that is negated', async () => { - expect(await getFilePaths([ - 'source/**/*', - '!source/main.brs' - ])).to.eql([{ - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }]); - }); - - it('excludes file from non-rootdir top-level pattern', async () => { - writeFiles(rootDir, ['../externalDir/source/main.brs']); - expect(await getFilePaths([ - '../externalDir/**/*', - '!../externalDir/**/*' - ])).to.eql([]); - }); - - it('throws when using top-level string referencing file outside the root dir', async () => { - writeFiles(rootDir, [`../source/main.brs`]); - await expectThrowsAsync(async () => { - await getFilePaths([ - '../source/**/*' - ]); - }, 'Cannot reference a file outside of rootDir when using a top-level string. Please use a src;des; object instead'); - }); - - it('works for brighterscript files', async () => { - writeFiles(rootDir, ['src/source/main.bs']); - expect(await getFilePaths([ - 'manifest', - 'source/**/*.bs' - ], s`${rootDir}/src`)).to.eql([{ - src: s`${rootDir}/src/source/main.bs`, - dest: s`source/main.bs` - }]); - }); - - it('works for root-level double star in top-level pattern', async () => { - expect(await getFilePaths([ - '**/*' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, - { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, - { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, - { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, - { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, - { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('works for multile entries', async () => { - expect(await getFilePaths([ - 'source/**/*', - 'components/**/*', - 'manifest' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('copies top-level-string single-star globs', async () => { - writeFiles(rootDir, [ - 'source/lib.brs', - 'source/main.brs' - ]); - expect(await getFilePaths([ - 'source/*.brs' - ])).to.eql([{ - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('works for double-star globs', async () => { - expect(await getFilePaths([ - '**/*.brs' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('copies subdir-level relative double-star globs', async () => { - expect(await getFilePaths([ - 'components/**/*.brs' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }]); - }); - - it('Finds folder using square brackets glob pattern', async () => { - fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); - expect(await getFilePaths([ - '[test]/*' - ], - rootDir - )).to.eql([{ - src: s`${rootDir}/e/file.brs`, - dest: s`e/file.brs` - }]); - }); - - it('Finds folder with escaped square brackets glob pattern as name', async () => { - fsExtra.outputFileSync(`${rootDir}/[test]/file.brs`, ''); - fsExtra.outputFileSync(`${rootDir}/e/file.brs`, ''); - expect(await getFilePaths([ - '\\[test\\]/*' - ], - rootDir - )).to.eql([{ - src: s`${rootDir}/[test]/file.brs`, - dest: s`[test]/file.brs` - }]); - }); - - it('throws exception when top-level strings reference files not under rootDir', async () => { - writeFiles(otherProjectDir, [ - 'manifest' - ]); - await expectThrowsAsync( - getFilePaths([ - `../${otherProjectName}/**/*` - ]) - ); - }); - - it('applies negated patterns', async () => { - expect(await getFilePaths([ - //include all components - 'components/**/*.brs', - //exclude all xml files - '!components/**/*.xml', - //re-include a specific xml file - 'components/screen1/screen1.xml' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }]); - }); - - it('handles negated multi-globs', async () => { - expect((await getFilePaths([ - 'components/**/*', - '!components/screen1/**/*' - ])).map(x => x.dest)).to.eql([ - s`components/component1.brs`, - s`components/component1.xml` - ]); - }); - - it('allows negating paths outside rootDir without requiring src;dest; syntax', async () => { - fsExtra.outputFileSync(`${rootDir}/../externalLib/source/lib.brs`, ''); - const filePaths = await getFilePaths([ - 'source/**/*', - { src: '../externalLib/**/*', dest: 'source' }, - '!../externalLib/source/**/*' - ], rootDir); - expect( - filePaths.map(x => s`${x.src}`).sort() - ).to.eql([ - s`${rootDir}/source/lib.brs`, - s`${rootDir}/source/main.brs` - ]); - }); - - it('applies multi-glob paths relative to rootDir', async () => { - expect(await getFilePaths([ - 'manifest', - 'source/**/*', - 'components/**/*', - '!components/scenes/**/*' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('ignores non-glob folder paths', async () => { - expect(await getFilePaths([ - //this is the folder called "components" - 'components' - ])).to.eql([]); //there should be no matches because rokudeploy ignores folders - }); - - }); - - describe('{src;dest} objects', () => { - it('excludes a file that is negated in src;dest;', async () => { - expect(await getFilePaths([ - 'source/**/*', - { - src: '!source/main.brs' - } - ])).to.eql([{ - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }]); - }); - - it('works for root-level double star in {src;dest} object', async () => { - expect(await getFilePaths([{ - src: '**/*', - dest: '' - } - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, - { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, - { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }, - { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }, - { - src: s`${rootDir}/source/lib.brs`, - dest: s`source/lib.brs` - }, - { - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('uses the root of staging folder for dest when not specified with star star', async () => { - writeFiles(otherProjectDir, [ - 'components/component1/subComponent/screen.brs', - 'manifest', - 'source/thirdPartyLib.brs' - ]); - expect(await getFilePaths([{ - src: `${otherProjectDir}/**/*` - }])).to.eql([{ - src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, - dest: s`components/component1/subComponent/screen.brs` - }, { - src: s`${otherProjectDir}/manifest`, - dest: s`manifest` - }, { - src: s`${otherProjectDir}/source/thirdPartyLib.brs`, - dest: s`source/thirdPartyLib.brs` - }]); - }); - - it('copies absolute path files to specified dest', async () => { - writeFiles(otherProjectDir, [ - 'source/thirdPartyLib.brs' - ]); - expect(await getFilePaths([{ - src: `${otherProjectDir}/source/thirdPartyLib.brs`, - dest: 'lib/thirdPartyLib.brs' - }])).to.eql([{ - src: s`${otherProjectDir}/source/thirdPartyLib.brs`, - dest: s`lib/thirdPartyLib.brs` - }]); - }); - - it('copies relative path files to specified dest', async () => { - const rootDirName = path.basename(rootDir); - writeFiles(rootDir, [ - 'source/main.brs' - ]); - expect(await getFilePaths([{ - src: `../${rootDirName}/source/main.brs`, - dest: 'source/main.brs' - }])).to.eql([{ - src: s`${rootDir}/source/main.brs`, - dest: s`source/main.brs` - }]); - }); - - it('maintains relative path after **', async () => { - writeFiles(otherProjectDir, [ - 'components/component1/subComponent/screen.brs', - 'manifest', - 'source/thirdPartyLib.brs' - ]); - expect(await getFilePaths([{ - src: `../otherProject/**/*`, - dest: 'outFolder/' - }])).to.eql([{ - src: s`${otherProjectDir}/components/component1/subComponent/screen.brs`, - dest: s`outFolder/components/component1/subComponent/screen.brs` - }, { - src: s`${otherProjectDir}/manifest`, - dest: s`outFolder/manifest` - }, { - src: s`${otherProjectDir}/source/thirdPartyLib.brs`, - dest: s`outFolder/source/thirdPartyLib.brs` - }]); - }); - - it('works for other globs', async () => { - expect(await getFilePaths([{ - src: `components/screen1/*creen1.brs`, - dest: s`/source` - }])).to.eql([{ - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`source/screen1.brs` - }]); - }); - - it('applies negated patterns', async () => { - writeFiles(rootDir, [ - 'components/component1.brs', - 'components/component1.xml', - 'components/screen1/screen1.brs', - 'components/screen1/screen1.xml' - ]); - expect(await getFilePaths([ - //include all component brs files - 'components/**/*.brs', - //exclude all xml files - '!components/**/*.xml', - //re-include a specific xml file - 'components/screen1/screen1.xml' - ])).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.brs`, - dest: s`components/screen1/screen1.brs` - }, { - src: s`${rootDir}/components/screen1/screen1.xml`, - dest: s`components/screen1/screen1.xml` - }]); - }); - }); - - it('converts relative rootDir path to absolute', async () => { - let stub = sinon.stub(rokuDeploy, 'getOptions').callThrough(); - await getFilePaths([ - 'source/main.brs' - ], './rootDir'); - expect(stub.callCount).to.be.greaterThan(0); - expect(stub.getCall(0).args[0].rootDir).to.eql('./rootDir'); - expect(stub.getCall(0).returnValue.rootDir).to.eql(s`${cwd}/rootDir`); - }); - - it('works when using a different current working directory than rootDir', async () => { - writeFiles(rootDir, [ - 'manifest', - 'images/splash_hd.jpg' - ]); - //sanity check, make sure it works without fiddling with cwd intact - let paths = await getFilePaths([ - 'manifest', - 'images/splash_hd.jpg' - ]); - - expect(paths).to.eql([{ - src: s`${rootDir}/images/splash_hd.jpg`, - dest: s`images/splash_hd.jpg` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }]); - - //change the working directory and verify everything still works - - let wrongCwd = path.dirname(path.resolve(options.rootDir)); - process.chdir(wrongCwd); - - paths = await getFilePaths([ - 'manifest', - 'images/splash_hd.jpg' - ]); - - expect(paths).to.eql([{ - src: s`${rootDir}/images/splash_hd.jpg`, - dest: s`images/splash_hd.jpg` - }, { - src: s`${rootDir}/manifest`, - dest: s`manifest` - }]); + fsExtra.ensureDirSync(rootDir); + process.chdir(rootDir); }); - - it('supports absolute paths from outside of the rootDir', async () => { - //dest not specified - expect(await getFilePaths([{ - src: sp`${cwd}/README.md` - }], options.rootDir)).to.eql([{ - src: s`${cwd}/README.md`, - dest: s`README.md` - }]); - - //dest specified - expect(await getFilePaths([{ - src: sp`${cwd}/README.md`, - dest: 'docs/README.md' - }], options.rootDir)).to.eql([{ - src: s`${cwd}/README.md`, - dest: s`docs/README.md` - }]); - - let paths: any[]; - - paths = await getFilePaths([{ - src: sp`${cwd}/README.md`, - dest: s`docs/README.md` - }], outDir); - - expect(paths).to.eql([{ - src: s`${cwd}/README.md`, - dest: s`docs/README.md` - }]); - - //top-level string paths pointing to files outside the root should thrown an exception - await expectThrowsAsync(async () => { - paths = await getFilePaths([ - sp`${cwd}/README.md` - ], outDir); + it('should fill in options from rokudeploy.json', () => { + fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { password: 'password' }); + expect( + util.getOptionsFromJson({ cwd: rootDir }) + ).to.eql({ + password: 'password' }); }); - it('supports relative paths that grab files from outside of the rootDir', async () => { - writeFiles(`${rootDir}/../`, [ - 'README.md' - ]); - expect( - await getFilePaths([{ - src: sp`../README.md` - }], rootDir) - ).to.eql([{ - src: s`${rootDir}/../README.md`, - dest: s`README.md` - }]); - + it(`can't find file`, () => { + fsExtra.writeJsonSync(s`${rootDir}/rokudeployed.json`, { host: '1.2.3.4' }); expect( - await getFilePaths([{ - src: sp`../README.md`, - dest: 'docs/README.md' - }], rootDir) - ).to.eql([{ - src: s`${rootDir}/../README.md`, - dest: s`docs/README.md` - }]); - }); - - it('should throw exception because we cannot have top-level string paths pointed to files outside the root', async () => { - writeFiles(rootDir, [ - '../README.md' - ]); - await expectThrowsAsync( - getFilePaths([ - path.posix.join('..', 'README.md') - ], outDir) - ); - }); + util.getOptionsFromJson({ cwd: rootDir }) + ).to.eql(undefined); - it('supports overriding paths', async () => { - let paths = await getFilePaths([{ - src: sp`${rootDir}/components/component1.brs`, - dest: 'comp1.brs' - }, { - src: sp`${rootDir}/components/screen1/screen1.brs`, - dest: 'comp1.brs' - }], rootDir); - expect(paths).to.be.lengthOf(1); - expect(s`${paths[0].src}`).to.equal(s`${rootDir}/components/screen1/screen1.brs`); }); - it('supports overriding paths from outside the root dir', async () => { - let thisRootDir = s`${tempDir}/tempTestOverrides/src`; + it(`loads cwd from process`, () => { try { - - fsExtra.ensureDirSync(s`${thisRootDir}/source`); - fsExtra.ensureDirSync(s`${thisRootDir}/components`); - fsExtra.ensureDirSync(s`${thisRootDir}/../.tmp`); - - fsExtra.writeFileSync(s`${thisRootDir}/source/main.brs`, ''); - fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.brs`, ''); - fsExtra.writeFileSync(s`${thisRootDir}/components/MainScene.xml`, ''); - fsExtra.writeFileSync(s`${thisRootDir}/../.tmp/MainScene.brs`, ''); - - let files = [ - '**/*.xml', - '**/*.brs', - { - src: '../.tmp/MainScene.brs', - dest: 'components/MainScene.brs' - } - ]; - let paths = await getFilePaths(files, thisRootDir); - - //the MainScene.brs file from source should NOT be included - let mainSceneEntries = paths.filter(x => s`${x.dest}` === s`components/MainScene.brs`); expect( mainSceneEntries, `Should only be one files entry for 'components/MainScene.brs'` @@ -1064,84 +484,6 @@ describe('util', () => { //clean up await fsExtra.remove(s`${thisRootDir}/../`); } - }); - - it('maintains original file path', async () => { - fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); - expect( - await getFilePaths([ - 'components/CustomButton.brs' - ], rootDir) - ).to.eql([{ - src: s`${rootDir}/components/CustomButton.brs`, - dest: s`components/CustomButton.brs` - }]); - }); - - it('correctly assumes file path if not given', async () => { - fsExtra.outputFileSync(`${rootDir}/components/CustomButton.brs`, ''); - expect( - (await getFilePaths([ - { src: 'components/*' } - ], rootDir)).sort((a, b) => a.src.localeCompare(b.src)) - ).to.eql([{ - src: s`${rootDir}/components/component1.brs`, - dest: s`components/component1.brs` - }, { - src: s`${rootDir}/components/component1.xml`, - dest: s`components/component1.xml` - }, { - src: s`${rootDir}/components/CustomButton.brs`, - dest: s`components/CustomButton.brs` - }]); - }); - }); - - describe('getOptionsFromJson', () => { - beforeEach(() => { - fsExtra.ensureDirSync(rootDir); - process.chdir(rootDir); - }); - it('should fill in missing options from rokudeploy.json', () => { - fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { password: 'password' }); - let options = util.getOptionsFromJson({ - rootDir: `${rootDir}`, - host: '1.2.3.4' - }); - let expectedOutput = { - rootDir: `${rootDir}`, - host: '1.2.3.4', - password: 'password' - }; - expect(options).to.eql(expectedOutput); - }); - - it('should fill in missing default options from bsconfig.json', () => { - fsExtra.writeJsonSync(s`${rootDir}/bsconfig.json`, { password: 'password' }); - let options = util.getOptionsFromJson({ - rootDir: `${rootDir}`, - host: '1.2.3.4' - }); - let expectedOutput = { - rootDir: `${rootDir}`, - host: '1.2.3.4', - password: 'password' - }; - expect(options).to.eql(expectedOutput); - - }); - - it('should not replace default options', () => { - fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { host: '4.3.2.1' }); - let options = util.getOptionsFromJson({ - rootDir: `${rootDir}`, - host: '1.2.3.4' - }); - let expectedOutput = { - rootDir: `${rootDir}`, - host: '1.2.3.4', - }; - expect(options).to.eql(expectedOutput); }); }); From 053a3f4471179e678354efa8ef1b11b97387bf6b Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 5 Mar 2024 12:57:34 -0500 Subject: [PATCH 43/93] remove bsconfig, fix cli file with key press commands, fix key press functions and add options --- src/RokuDeploy.spec.ts | 17 ------------ src/RokuDeploy.ts | 62 ++++++++++++++++++++++++++++++++---------- src/cli.ts | 62 +++++++++++++++++++++++------------------- 3 files changed, 81 insertions(+), 60 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 02ef5de..9f51329 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3215,11 +3215,6 @@ describe('index', () => { expect(rokuDeploy.getOptions().outFile).to.equal('rokudeploy-outfile'); }); - it('if bsconfig.json config file is available it should use those values instead of the default', () => { - fsExtra.writeJsonSync(`${rootDir}/bsconfig.json`, { outFile: 'bsconfig-outfile' }); - expect(rokuDeploy.getOptions().outFile).to.equal('bsconfig-outfile'); - }); - it('if rokudeploy.json config file is available and bsconfig.json is also available it should use rokudeploy.json instead of bsconfig.json', () => { fsExtra.outputJsonSync(`${rootDir}/bsconfig.json`, { outFile: 'bsconfig-outfile' }); fsExtra.outputJsonSync(`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); @@ -3227,23 +3222,11 @@ describe('index', () => { }); it('if runtime options are provided, they should override any existing config file options', () => { - fsExtra.writeJsonSync(`${rootDir}/bsconfig.json`, { outFile: 'bsconfig-outfile' }); fsExtra.writeJsonSync(`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); expect(rokuDeploy.getOptions({ outFile: 'runtime-outfile' }).outFile).to.equal('runtime-outfile'); }); - - it('if runtime config should override any existing config file options', () => { - fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); - fsExtra.writeJsonSync(s`${rootDir}/bsconfig`, { outFile: 'rokudeploy-outfile' }); - - fsExtra.writeJsonSync(s`${rootDir}/brsconfig.json`, { outFile: 'project-config-outfile' }); - options = { - project: 'brsconfig.json' - }; - expect(rokuDeploy.getOptions(options).outFile).to.equal('project-config-outfile'); - }); }); }); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index a6c81f7..91d02a9 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -183,33 +183,35 @@ export class RokuDeploy { return baseRequestOptions; } - public async keypress(options: { key: string }) { + public async keyPress(options: KeyPressOptions) { return this.sendKeyEvent({ ...options, + key: 'all.the.others', action: 'keypress' }); } - public async keyup(options: any) { + public async keyUp(options: KeyUpOptions) { return this.sendKeyEvent({ ...options, action: 'keyup' }); } - public async keydown(options: any) { + public async keyDown(options: KeyDownOptions) { return this.sendKeyEvent({ ...options, action: 'keydown' }); } - public async sendText(options: any) { + public async sendText(options: SendTextOptions) { const chars = options.text.split(''); for (const char of chars) { - await this.keypress({ + await this.sendKeyEvent({ ...options, - key: `lit_${char}` + key: `lit_${char}`, + action: 'keypress' }); } } @@ -217,18 +219,13 @@ export class RokuDeploy { /** * Simulate pressing the home button on the remote for this roku. * This makes the roku return to the home screen - * @param host - the host - * @param port - the port that should be used for the request. defaults to 8060 - * @param timeout - request timeout duration in milliseconds. defaults to 150000 */ - private async sendKeyEvent(options: { host: string; port?: string; key: 'home' | 'left' | 'all.the.others'; action: 'keypress' | 'keyup' | 'keydown'; timeout?: number }) { - let options = this.getOptions(); - port = port ? port : options.remotePort; - timeout = timeout ? timeout : options.timeout; + private async sendKeyEvent(options: SendKeyEventOptions) { + let filledOptions = this.getOptions(options); // press the home button to return to the main screen return this.doPostRequest({ - url: `http://${host}:${port}/keypress/Home`, - timeout: timeout + url: `http://${filledOptions.host}:${filledOptions.remotePort}/${filledOptions.action}/${filledOptions.key}`, + timeout: filledOptions.timeout }, false); } @@ -964,6 +961,41 @@ export interface GetDeviceInfoOptions { enhance?: boolean; } +type RokuKey = 'home' | 'rev' | 'fwd' | 'play' | 'select' | 'left' | 'right' | 'down' | 'up' | 'back' | 'instantreplay' | 'info' | 'backspace' | 'search' | 'enter' | 'findremote' | 'volumeup' | 'volumedown' | 'volumemute' | 'poweroff' | 'channelup' | 'channeldown' | 'inputtuner' | 'inputhdmi1' | 'inputhdmi2' | 'inputhdmi3' | 'inputhdmi4' | 'inputav1'; +export interface SendKeyEventOptions { + action?: 'keypress' | 'keydown' | 'keyup'; + host: string; + key: RokuKey | string; + remotePort?: number; + timeout?: number; +} + +export interface KeyUpOptions extends SendKeyEventOptions { + action?: 'keyup'; + key: RokuKey; +} + +export interface KeyDownOptions extends SendKeyEventOptions { + action?: 'keydown'; + key: RokuKey; +} + +export interface KeyPressOptions extends SendKeyEventOptions { + action?: 'keypress'; + key: RokuKey; +} + +export interface SendTextOptions extends SendKeyEventOptions { + action?: 'keypress'; + text: string; +} + +export interface CloseChannelOptions { + host: string; + remotePort: number; + timeout?: number; + +} export interface StageOptions { rootDir?: string; files?: FileEntry[]; diff --git a/src/cli.ts b/src/cli.ts index 8f4c249..f3c3ead 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,8 +1,7 @@ #!/usr/bin/env node import * as yargs from 'yargs'; -import { rokuDeploy } from './index'; import { ExecCommand } from './commands/ExecCommand'; -import { TextCommand } from './commands/TextCommand'; +import { SendTextCommand } from './commands/SendTextCommand'; import { PrepublishCommand } from './commands/PrepublishCommand'; import { ZipPackageCommand } from './commands/ZipPackageCommand'; import { PublishCommand } from './commands/PublishCommand'; @@ -16,6 +15,10 @@ import { GetOutputPkgFilePathCommand } from './commands/GetOutputPkgFilePathComm import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; import { ZipCommand } from './commands/ZipCommand'; +import { KeyPressCommand } from './commands/KeyPressCommand'; +import { KeyUpCommand } from './commands/KeyUpCommand'; +import { KeyDownCommand } from './commands/KeyDownCommand'; +import type { RokuDeploy } from './RokuDeploy'; void yargs @@ -57,32 +60,44 @@ void yargs return new ExecCommand(args.actions, args.configPath).run(); }) - .command(['sendText', 'text'], 'Send text command', (builder) => { + .command('keypress', 'send keypress command', (builder) => { return builder - .option('text', { type: 'string', description: 'The text to send', demandOption: true }); + .option('key', { type: 'string', description: 'The key to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); }, (args: any) => { - return new TextCommand().run(args); //TODO: do this through exec command to get default args like host and port? or add those to here and go through separate command for better testing + return new KeyPressCommand().run(args); }) - .command('keypress', 'send keypress command', (builder) => { + .command('keyup', 'send keyup command', (builder) => { return builder - .option('key', { type: 'string', description: 'The key to send', demandOption: true }); - }, async (args: any) => { - await rokuDeploy.keyPress(args.text); //TODO: Go through exec command, separate command, or use key event? + .option('key', { type: 'string', description: 'The key to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); + }, (args: any) => { + return new KeyUpCommand().run(args); }) - .command('keyup', 'send keyup command', (builder) => { + .command('keydown', 'send keydown command', (builder) => { return builder - .option('key', { type: 'string', description: 'The key to send', demandOption: true }); - }, async (args: any) => { - await rokuDeploy.keyUp(args.text); //TODO: Go through exec command, separate command, or use key event? + .option('key', { type: 'string', description: 'The key to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); + }, (args: any) => { + return new KeyDownCommand().run(args); }) - .command('keydown', 'send keydown command', (builder) => { + .command(['sendText', 'text'], 'Send text command', (builder) => { return builder - .option('key', { type: 'string', description: 'The key to send', demandOption: true }); - }, async (args: any) => { - await rokuDeploy.keyDown(args.text); //TODO: Go through exec command, separate command, or use key event? + .option('text', { type: 'string', description: 'The text to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); + }, (args: any) => { + return new SendTextCommand().run(args); //TODO: Add default options }) .command(['stage', 'prepublishToStaging'], 'Copies all of the referenced files to the staging folder', (builder) => { @@ -141,21 +156,12 @@ void yargs return new CreateSignedPackageCommand().run(args); }) - .command('deploy', 'Deploy a pre-existing packaged zip file to a remote Roku', (builder) => { - return builder - .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) - .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) - .option('rootDir', { type: 'string', description: 'The root directory', demandOption: false }); - }, (args: any) => { - return new DeployCommand().run(args); - }) - .command(['deleteDevChannel', 'deleteInstalledChannel', 'rmdev', 'delete'], 'Delete an installed channel', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); }, (args: any) => { - return new DeleteInstalledChannelCommand().run(args); + return new DeleteDevChannelCommand().run(args); }) .command(['screenshot', 'captureScreenshot'], 'Take a screenshot', (builder) => { @@ -163,7 +169,7 @@ void yargs .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); }, (args: any) => { - return new TakeScreenshotCommand().run(args);//TODO: rename + return new TakeScreenshotCommand().run(args); }) .command('getOutputZipFilePath', 'Centralizes getting output zip file path based on passed in options', (builder) => { From fa077870bd1ae8fa7b2e8b263306d6d8259de7d9 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 5 Mar 2024 12:58:12 -0500 Subject: [PATCH 44/93] fix getoptionsfromjson --- src/util.spec.ts | 22 +++++++--------------- src/util.ts | 36 +++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/util.spec.ts b/src/util.spec.ts index b30032e..74c490e 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -451,7 +451,7 @@ describe('util', () => { }); }); - describe.only('getOptionsFromJson', () => { + describe('getOptionsFromJson', () => { beforeEach(() => { fsExtra.ensureDirSync(rootDir); process.chdir(rootDir); @@ -465,24 +465,16 @@ describe('util', () => { }); }); - it(`can't find file`, () => { - fsExtra.writeJsonSync(s`${rootDir}/rokudeployed.json`, { host: '1.2.3.4' }); - expect( - util.getOptionsFromJson({ cwd: rootDir }) - ).to.eql(undefined); - - }); - it(`loads cwd from process`, () => { try { + fsExtra.writeJsonSync(s`${process.cwd()}/rokudeploy.json`, { host: '1.2.3.4' }); expect( - mainSceneEntries, - `Should only be one files entry for 'components/MainScene.brs'` - ).to.be.lengthOf(1); - expect(s`${mainSceneEntries[0].src}`).to.eql(s`${thisRootDir}/../.tmp/MainScene.brs`); + util.getOptionsFromJson() + ).to.eql({ + host: '1.2.3.4' + }); } finally { - //clean up - await fsExtra.remove(s`${thisRootDir}/../`); + fsExtra.removeSync(s`${process.cwd()}/rokudeploy.json`); } }); diff --git a/src/util.ts b/src/util.ts index 2895b06..56df6d3 100644 --- a/src/util.ts +++ b/src/util.ts @@ -449,23 +449,25 @@ export class Util { const cwd = options?.cwd ?? process.cwd(); const configPath = path.join(cwd, 'rokudeploy.json'); - let configFileText = fsExtra.readFileSync(configPath).toString(); - let parseErrors = [] as ParseError[]; - fileOptions = parseJsonc(configFileText, parseErrors, { - allowEmptyContent: true, - allowTrailingComma: true, - disallowComments: false - }); - if (parseErrors.length > 0) { - throw new Error(`Error parsing "${path.resolve(configPath)}": ` + JSON.stringify( - parseErrors.map(x => { - return { - message: printParseErrorCode(x.error), - offset: x.offset, - length: x.length - }; - }) - )); + if (fsExtra.existsSync(configPath)) { + let configFileText = fsExtra.readFileSync(configPath).toString(); + let parseErrors = [] as ParseError[]; + fileOptions = parseJsonc(configFileText, parseErrors, { + allowEmptyContent: true, + allowTrailingComma: true, + disallowComments: false + }); + if (parseErrors.length > 0) { + throw new Error(`Error parsing "${path.resolve(configPath)}": ` + JSON.stringify( + parseErrors.map(x => { + return { + message: printParseErrorCode(x.error), + offset: x.offset, + length: x.length + }; + }) + )); + } } return fileOptions; } From 43446661cf3ac18fd6bb1b96f552a1395fbf2f9e Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 5 Mar 2024 23:36:44 -0500 Subject: [PATCH 45/93] delete unnecessary commands, fix some tests --- src/RokuDeploy.spec.ts | 40 ++++++++++----------- src/RokuDeploy.ts | 8 ++--- src/RokuDeployOptions.ts | 5 +++ src/cli.ts | 27 +++----------- src/commands/GetOutputPkgFilePathCommand.ts | 13 ------- src/commands/GetOutputZipFilePathCommand.ts | 13 ------- 6 files changed, 33 insertions(+), 73 deletions(-) delete mode 100644 src/commands/GetOutputPkgFilePathCommand.ts delete mode 100644 src/commands/GetOutputZipFilePathCommand.ts diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 9f51329..59eec4f 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -1877,35 +1877,35 @@ describe('index', () => { describe('normalizeFilesArray', () => { it('catches invalid dest entries', () => { expect(() => { - rokuDeploy['normalizeFilesArray']([{ + util['normalizeFilesArray']([{ src: 'some/path', dest: true }]); }).to.throw(); expect(() => { - rokuDeploy['normalizeFilesArray']([{ + util['normalizeFilesArray']([{ src: 'some/path', dest: false }]); }).to.throw(); expect(() => { - rokuDeploy['normalizeFilesArray']([{ + util['normalizeFilesArray']([{ src: 'some/path', dest: /asdf/gi }]); }).to.throw(); expect(() => { - rokuDeploy['normalizeFilesArray']([{ + util['normalizeFilesArray']([{ src: 'some/path', dest: {} }]); }).to.throw(); expect(() => { - rokuDeploy['normalizeFilesArray']([{ + util['normalizeFilesArray']([{ src: 'some/path', dest: [] }]); @@ -1913,7 +1913,7 @@ describe('index', () => { }); it('normalizes directory separators paths', () => { - expect(rokuDeploy['normalizeFilesArray']([{ + expect(util['normalizeFilesArray']([{ src: `long/source/path`, dest: `long/dest/path` }])).to.eql([{ @@ -1923,7 +1923,7 @@ describe('index', () => { }); it('works for simple strings', () => { - expect(rokuDeploy['normalizeFilesArray']([ + expect(util['normalizeFilesArray']([ 'manifest', 'source/main.brs' ])).to.eql([ @@ -1933,7 +1933,7 @@ describe('index', () => { }); it('works for negated strings', () => { - expect(rokuDeploy['normalizeFilesArray']([ + expect(util['normalizeFilesArray']([ '!.git' ])).to.eql([ '!.git' @@ -1941,7 +1941,7 @@ describe('index', () => { }); it('skips falsey and bogus entries', () => { - expect(rokuDeploy['normalizeFilesArray']([ + expect(util['normalizeFilesArray']([ '', 'manifest', false, @@ -1953,7 +1953,7 @@ describe('index', () => { }); it('works for {src:string} objects', () => { - expect(rokuDeploy['normalizeFilesArray']([ + expect(util['normalizeFilesArray']([ { src: 'manifest' } @@ -1964,7 +1964,7 @@ describe('index', () => { }); it('works for {src:string[]} objects', () => { - expect(rokuDeploy['normalizeFilesArray']([ + expect(util['normalizeFilesArray']([ { src: [ 'manifest', @@ -1981,7 +1981,7 @@ describe('index', () => { }); it('retains dest option', () => { - expect(rokuDeploy['normalizeFilesArray']([ + expect(util['normalizeFilesArray']([ { src: 'source/config.dev.brs', dest: 'source/config.brs' @@ -1993,14 +1993,14 @@ describe('index', () => { }); it('throws when encountering invalid entries', () => { - expect(() => rokuDeploy['normalizeFilesArray']([true])).to.throw(); - expect(() => rokuDeploy['normalizeFilesArray']([/asdf/])).to.throw(); - expect(() => rokuDeploy['normalizeFilesArray']([new Date()])).to.throw(); - expect(() => rokuDeploy['normalizeFilesArray']([1])).to.throw(); - expect(() => rokuDeploy['normalizeFilesArray']([{ src: true }])).to.throw(); - expect(() => rokuDeploy['normalizeFilesArray']([{ src: /asdf/ }])).to.throw(); - expect(() => rokuDeploy['normalizeFilesArray']([{ src: new Date() }])).to.throw(); - expect(() => rokuDeploy['normalizeFilesArray']([{ src: 1 }])).to.throw(); + expect(() => util['normalizeFilesArray']([true])).to.throw(); + expect(() => util['normalizeFilesArray']([/asdf/])).to.throw(); + expect(() => util['normalizeFilesArray']([new Date()])).to.throw(); + expect(() => util['normalizeFilesArray']([1])).to.throw(); + expect(() => util['normalizeFilesArray']([{ src: true }])).to.throw(); + expect(() => util['normalizeFilesArray']([{ src: /asdf/ }])).to.throw(); + expect(() => util['normalizeFilesArray']([{ src: new Date() }])).to.throw(); + expect(() => util['normalizeFilesArray']([{ src: 1 }])).to.throw(); }); }); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 91d02a9..29055ab 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -69,7 +69,7 @@ export class RokuDeploy { * Given an already-populated staging folder, create a zip archive of it and copy it to the output folder * @param options */ - public async zip(options: ZipPackageOptions) { + public async zip(options: ZipOptions) { options = this.getOptions(options) as any; //make sure the output folder exists @@ -708,8 +708,8 @@ export class RokuDeploy { this.logger.logLevel = finalOptions.logLevel; //TODO: Handle logging differently //fully resolve the folder paths - finalOptions.rootDir = path.resolve(options.cwd, finalOptions.rootDir); - finalOptions.outDir = path.resolve(options.cwd, finalOptions.outDir); + finalOptions.rootDir = path.resolve(finalOptions.cwd, finalOptions.rootDir); + finalOptions.outDir = path.resolve(finalOptions.cwd, finalOptions.outDir); //stagingDir if (options.stagingDir) { @@ -1003,7 +1003,7 @@ export interface StageOptions { retainStagingDir?: boolean; } -export interface ZipPackageOptions { +export interface ZipOptions { stagingDir?: string; outDir?: string; } diff --git a/src/RokuDeployOptions.ts b/src/RokuDeployOptions.ts index dc1b4ff..a70b766 100644 --- a/src/RokuDeployOptions.ts +++ b/src/RokuDeployOptions.ts @@ -1,6 +1,11 @@ import type { LogLevel } from './Logger'; export interface RokuDeployOptions { + /** + * The working directory where the command should be executed + */ + cwd?: string; + /** * Path to a bsconfig.json project file */ diff --git a/src/cli.ts b/src/cli.ts index f3c3ead..360ec35 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,8 +10,6 @@ import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; import { DeleteDevChannelCommand } from './commands/DeleteDevChannelCommand'; import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; -import { GetOutputZipFilePathCommand } from './commands/GetOutputZipFilePathCommand'; -import { GetOutputPkgFilePathCommand } from './commands/GetOutputPkgFilePathCommand'; import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; import { ZipCommand } from './commands/ZipCommand'; @@ -172,23 +170,6 @@ void yargs return new TakeScreenshotCommand().run(args); }) - .command('getOutputZipFilePath', 'Centralizes getting output zip file path based on passed in options', (builder) => { - return builder - .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); - return builder; - }, (args: any) => { - return new GetOutputZipFilePathCommand().run(args); - }) - - .command('getOutputPkgFilePath', 'Centralizes getting output pkg file path based on passed in options', (builder) => { - return builder - .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); - }, (args: any) => { - return new GetOutputPkgFilePathCommand().run(args); - }) - .command(['getDeviceInfo', 'deviceinfo'], 'Get the `device-info` response from a Roku device', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }); @@ -203,13 +184,13 @@ void yargs return new GetDevIdCommand().run(args); }) - .command('zipFolder', 'Given a path to a folder, zip up that folder and all of its contents', (builder) => { + .command('zip', 'Given a path to a folder, zip up that folder and all of its contents', (builder) => { return builder - .option('srcFolder', { type: 'string', description: 'The folder that should be zipped', demandOption: false }) - .option('zipFilePath', { type: 'string', description: 'The path to the zip that will be created. Must be .zip file name', demandOption: false }); + .option('stagingDir', { type: 'string', description: 'The folder that should be zipped', demandOption: false }) + .option('outDir', { type: 'string', description: 'The path to the zip that will be created. Must be .zip file name', demandOption: false }); }, (args: any) => { console.log('args', args); - return new ZipFolderCommand().run(args); + return new ZipCommand().run(args); }) .argv; diff --git a/src/commands/GetOutputPkgFilePathCommand.ts b/src/commands/GetOutputPkgFilePathCommand.ts deleted file mode 100644 index 3bfc2d0..0000000 --- a/src/commands/GetOutputPkgFilePathCommand.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { rokuDeploy, util } from '../index'; - -export class GetOutputPkgFilePathCommand { - run(args) { - let options = { - ...util.getOptionsFromJson(args), - ...args - }; - // eslint-disable-next-line @typescript-eslint/dot-notation - const outputPath = rokuDeploy['getOutputPkgPath'](options); //TODO fix this? - console.log(outputPath); - } -} diff --git a/src/commands/GetOutputZipFilePathCommand.ts b/src/commands/GetOutputZipFilePathCommand.ts deleted file mode 100644 index c5761c0..0000000 --- a/src/commands/GetOutputZipFilePathCommand.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { rokuDeploy, util } from '../index'; - -export class GetOutputZipFilePathCommand { - run(args) { - let options = { - ...util.getOptionsFromJson(args), - ...args - }; - // eslint-disable-next-line @typescript-eslint/dot-notation - const outputPath = rokuDeploy['getOutputZipFilePath'](options); - console.log(outputPath); - } -} From 7d9e56e9f75cbf90e4f5b1b4317561343504e435 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 5 Mar 2024 23:42:56 -0500 Subject: [PATCH 46/93] change to captureScreenshot --- src/RokuDeploy.spec.ts | 2 +- src/RokuDeploy.ts | 4 ++-- src/cli.spec.ts | 4 ++-- src/cli.ts | 4 ++-- .../{TakeScreenshotCommand.ts => CaptureScreenshotCommand.ts} | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename src/commands/{TakeScreenshotCommand.ts => CaptureScreenshotCommand.ts} (85%) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 59eec4f..eda8994 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -2016,7 +2016,7 @@ describe('index', () => { }); }); - describe('takeScreenshot', () => { + describe('captureScreenshot', () => { let onHandler: any; let screenshotAddress: any; diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 29055ab..777aedc 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -614,7 +614,7 @@ export class RokuDeploy { /** * Gets a screenshot from the device. A side-loaded channel must be running or an error will be thrown. */ - public async captureScreenshot(options: TakeScreenshotOptions) { + public async captureScreenshot(options: CaptureScreenshotOptions) { options = this.getOptions(options); options.screenshotFile = options.screenshotFile ?? `screenshot-${dayjs().format('YYYY-MM-DD-HH.mm.ss.SSS')}`; let saveFilePath: string; @@ -916,7 +916,7 @@ export interface HttpResponse { body: any; } -export interface TakeScreenshotOptions { +export interface CaptureScreenshotOptions { /** * The IP address or hostname of the target Roku device. * @example '192.168.1.21' diff --git a/src/cli.spec.ts b/src/cli.spec.ts index f599044..06ce457 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -10,7 +10,7 @@ import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; import { DeleteDevChannelCommand } from './commands/DeleteDevChannelCommand'; -import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; +import { CaptureScreenshotCommand } from './commands/CaptureScreenshotCommand'; import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; @@ -185,7 +185,7 @@ describe('cli', () => { return Promise.resolve(''); }); - const command = new TakeScreenshotCommand(); + const command = new CaptureScreenshotCommand(); await command.run({ host: '1.2.3.4', password: '5536' diff --git a/src/cli.ts b/src/cli.ts index 360ec35..d2e5a9b 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -9,7 +9,7 @@ import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; import { DeleteDevChannelCommand } from './commands/DeleteDevChannelCommand'; -import { TakeScreenshotCommand } from './commands/TakeScreenshotCommand'; +import { CaptureScreenshotCommand } from './commands/CaptureScreenshotCommand'; import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; import { ZipCommand } from './commands/ZipCommand'; @@ -167,7 +167,7 @@ void yargs .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); }, (args: any) => { - return new TakeScreenshotCommand().run(args); + return new CaptureScreenshotCommand().run(args); }) .command(['getDeviceInfo', 'deviceinfo'], 'Get the `device-info` response from a Roku device', (builder) => { diff --git a/src/commands/TakeScreenshotCommand.ts b/src/commands/CaptureScreenshotCommand.ts similarity index 85% rename from src/commands/TakeScreenshotCommand.ts rename to src/commands/CaptureScreenshotCommand.ts index c77ef61..6a75ed5 100644 --- a/src/commands/TakeScreenshotCommand.ts +++ b/src/commands/CaptureScreenshotCommand.ts @@ -1,6 +1,6 @@ import { rokuDeploy, util } from '../index'; -export class TakeScreenshotCommand { +export class CaptureScreenshotCommand { async run(args) { let options = { ...util.getOptionsFromJson(args), From ebb3d22d0ca682891893fbc20a16d34edb94e1e9 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Fri, 8 Mar 2024 11:02:22 -0500 Subject: [PATCH 47/93] Fix a bunch of tests --- src/RokuDeploy.spec.ts | 230 ++++++--------------------------------- src/RokuDeploy.ts | 37 +++---- src/RokuDeployOptions.ts | 2 +- src/cli.spec.ts | 18 +-- src/util.spec.ts | 56 +++++++++- src/util.ts | 3 +- 6 files changed, 110 insertions(+), 236 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index eda8994..486f2d6 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -606,68 +606,6 @@ describe('index', () => { }); }); - describe('copyToStaging', () => { - it('throws exceptions when rootDir does not exist', async () => { - await expectThrowsAsync( - rokuDeploy['copyToStaging']([], 'staging', 'folder_does_not_exist') - ); - }); - - it('throws exceptions on missing stagingPath', async () => { - await expectThrowsAsync( - rokuDeploy['copyToStaging']([], undefined, undefined) - ); - }); - - it('throws exceptions on missing rootDir', async () => { - await expectThrowsAsync( - rokuDeploy['copyToStaging']([], 'asdf', undefined) - ); - }); - - it('computes absolute path for all operations', async () => { - const ensureDirPaths = []; - sinon.stub(fsExtra, 'ensureDir').callsFake((p) => { - ensureDirPaths.push(p); - return Promise.resolve; - }); - const copyPaths = [] as Array<{ src: string; dest: string }>; - sinon.stub(fsExtra as any, 'copy').callsFake((src, dest) => { - copyPaths.push({ src: src as string, dest: dest as string }); - return Promise.resolve(); - }); - - sinon.stub(rokuDeploy, 'getFilePaths').returns( - Promise.resolve([ - { - src: s`${rootDir}/source/main.brs`, - dest: '/source/main.brs' - }, { - src: s`${rootDir}/components/a/b/c/comp1.xml`, - dest: '/components/a/b/c/comp1.xml' - } - ]) - ); - - await rokuDeploy['copyToStaging']([], stagingDir, rootDir); - - expect(ensureDirPaths).to.eql([ - s`${stagingDir}/source`, - s`${stagingDir}/components/a/b/c` - ]); - - expect(copyPaths).to.eql([ - { - src: s`${rootDir}/source/main.brs`, - dest: s`${stagingDir}/source/main.brs` - }, { - src: s`${rootDir}/components/a/b/c/comp1.xml`, - dest: s`${stagingDir}/components/a/b/c/comp1.xml` - } - ]); - }); - }); - describe('zipPackage', () => { it('should throw error when manifest is missing', async () => { let err; @@ -733,7 +671,7 @@ describe('index', () => { it('uses default port', async () => { const promise = new Promise((resolve) => { sinon.stub(rokuDeploy, 'doPostRequest').callsFake((opts: any) => { - expect(opts.url).to.equal('http://1.2.3.4:8060/keypress/Home'); + expect(opts.url).to.equal('http://1.2.3.4:8060/keypress/home'); resolve(); }); }); @@ -744,7 +682,7 @@ describe('index', () => { it('uses overridden port', async () => { const promise = new Promise((resolve) => { sinon.stub(rokuDeploy, 'doPostRequest').callsFake((opts: any) => { - expect(opts.url).to.equal('http://1.2.3.4:987/keypress/Home'); + expect(opts.url).to.equal('http://1.2.3.4:987/keypress/home'); resolve(); }); }); @@ -755,7 +693,7 @@ describe('index', () => { it('uses default timeout', async () => { const promise = new Promise((resolve) => { sinon.stub(rokuDeploy, 'doPostRequest').callsFake((opts: any) => { - expect(opts.url).to.equal('http://1.2.3.4:8060/keypress/Home'); + expect(opts.url).to.equal('http://1.2.3.4:8060/keypress/home'); expect(opts.timeout).to.equal(150000); resolve(); }); @@ -768,7 +706,7 @@ describe('index', () => { const promise = new Promise((resolve) => { sinon.stub(rokuDeploy, 'doPostRequest').callsFake((opts: any) => { - expect(opts.url).to.equal('http://1.2.3.4:987/keypress/Home'); + expect(opts.url).to.equal('http://1.2.3.4:987/keypress/home'); expect(opts.timeout).to.equal(1000); resolve(); }); @@ -779,7 +717,7 @@ describe('index', () => { }); let fileCounter = 1; - describe('publish', () => { + describe('sideload', () => { beforeEach(() => { //make a dummy output file...we don't care what's in it options.outFile = `temp${fileCounter++}.zip`; @@ -860,7 +798,8 @@ describe('index', () => { host: '1.2.3.4', password: 'password', outDir: outDir, - outFile: 'fileThatDoesNotExist.zip' + outFile: 'fileThatDoesNotExist.zip', + deleteDevChannel: false }); }, `Cannot publish because file does not exist at '${rokuDeploy['getOutputZipFilePath']({ outFile: 'fileThatDoesNotExist.zip', @@ -1007,7 +946,8 @@ describe('index', () => { outDir: outDir, failOnCompileError: true, remoteDebug: true, - outFile: options.outFile + outFile: options.outFile, + deleteDevChannel: false }).then((result) => { expect(result.message).to.equal('Successful deploy'); expect(stub.getCall(0).args[0].formData.remotedebug).to.eql('1'); @@ -1026,7 +966,8 @@ describe('index', () => { failOnCompileError: true, remoteDebug: true, remoteDebugConnectEarly: true, - outFile: options.outFile + outFile: options.outFile, + deleteDevChannel: false }).then((result) => { expect(result.message).to.equal('Successful deploy'); expect(stub.getCall(0).args[0].formData.remotedebug_connect_early).to.eql('1'); @@ -1411,13 +1352,17 @@ describe('index', () => { node.appendChild(pkgDiv);`; mockDoPostRequest(body); + const stub = sinon.stub(rokuDeploy as any, 'downloadFile').returns(Promise.resolve('pkgs//P6953175d5df120c0069c53de12515b9a.pkg')); + let pkgPath = await rokuDeploy.createSignedPackage({ host: '1.2.3.4', password: 'password', signingPassword: options.signingPassword, - stagingDir: stagingDir + stagingDir: stagingDir, + outDir: outDir }); - expect(pkgPath).to.equal('pkgs//P6953175d5df120c0069c53de12515b9a.pkg'); + expect(pkgPath).to.equal(s`${outDir}/roku-deploy.pkg`); + expect(stub.getCall(0).args[0].url).to.equal('http://1.2.3.4:80/pkgs//P6953175d5df120c0069c53de12515b9a.pkg'); }); it('should return our fallback error if neither error or package link was detected', async () => { @@ -2161,7 +2106,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outDir: `${tempDir}/myScreenShots` }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: `${tempDir}/myScreenShots` }); expect(result).not.to.be.undefined; expect(util.standardizePath(`${tempDir}/myScreenShots`)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(result)); @@ -2185,7 +2130,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outDir: tempDir, outFile: 'my' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: tempDir, screenshotFile: 'my' }); expect(result).not.to.be.undefined; expect(util.standardizePath(tempDir)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(path.join(tempDir, 'my.png'))); @@ -2209,7 +2154,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outDir: tempDir, outFile: 'my.jpg' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: tempDir, screenshotFile: 'my.jpg' }); expect(result).not.to.be.undefined; expect(util.standardizePath(tempDir)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(path.join(tempDir, 'my.jpg.png'))); @@ -2256,7 +2201,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, outFile: 'myFile' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotFile: 'myFile' }); expect(result).not.to.be.undefined; expect(path.basename(result)).to.equal('myFile.jpg'); expect(fsExtra.existsSync(result)); @@ -3026,37 +2971,6 @@ describe('index', () => { }); }); - describe('stringifyManifest', () => { - it('correctly converts back to a valid manifest when lineNumber and keyIndexes are provided', () => { - expect( - rokuDeploy['stringifyManifest']( - rokuDeploy['parseManifestFromString']('major_version=3\nminor_version=4') - ) - ).to.equal( - 'major_version=3\nminor_version=4' - ); - }); - - it('correctly converts back to a valid manifest when lineNumber and keyIndexes are not provided', () => { - const parsed = rokuDeploy['parseManifestFromString']('title=App\nmajor_version=3'); - delete parsed.keyIndexes; - delete parsed.lineCount; - let outputParsedManifest = rokuDeploy['parseManifestFromString']( - rokuDeploy['stringifyManifest'](parsed) - ); - expect(outputParsedManifest.title).to.equal('App'); - expect(outputParsedManifest.major_version).to.equal('3'); - }); - }); - - describe('computeFileDestPath', () => { - it('treats {src;dest} without dest as a top-level string', () => { - expect( - rokuDeploy['computeFileDestPath'](s`${rootDir}/source/main.brs`, { src: s`source/main.brs` } as any, rootDir) - ).to.eql(s`source/main.brs`); - }); - }); - describe('checkRequest', () => { it('throws FailedDeviceResponseError when necessary', () => { sinon.stub(rokuDeploy as any, 'getRokuMessagesFromResponseBody').returns({ @@ -3093,89 +3007,23 @@ describe('index', () => { }); it('works when passing in stagingDir', () => { - sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { - return false; - }); options = rokuDeploy.getOptions({ stagingDir: './staging-dir' }); expect(options.stagingDir.endsWith('staging-dir')).to.be.true; }); - it('works when loading stagingDir from rokudeploy.json', () => { - sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { - return true; - }); - sinon.stub(fsExtra, 'readFileSync').returns(` - { - "stagingDir": "./staging-dir" - } - `); - options = rokuDeploy.getOptions(); - expect(options.stagingDir.endsWith('staging-dir')).to.be.true; - }); - - it('supports jsonc for roku-deploy.json', () => { - sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { - return (filePath as string).endsWith('rokudeploy.json'); - }); - sinon.stub(fsExtra, 'readFileSync').returns(` - //leading comment - { - //inner comment - "rootDir": "src" //trailing comment - } - //trailing comment - `); - options = rokuDeploy.getOptions(undefined); - expect(options.rootDir).to.equal(path.join(process.cwd(), 'src')); - }); - - it('supports jsonc for bsconfig.json', () => { - sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { - return (filePath as string).endsWith('bsconfig.json'); - }); - sinon.stub(fsExtra, 'readFileSync').returns(` - //leading comment - { - //inner comment - "rootDir": "src" //trailing comment - } - //trailing comment - `); - options = rokuDeploy.getOptions(undefined); - expect(options.rootDir).to.equal(path.join(process.cwd(), 'src')); - }); - - it('catches invalid json with jsonc parser', () => { - sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { - return (filePath as string).endsWith('bsconfig.json'); - }); - sinon.stub(fsExtra, 'readFileSync').returns(` - { - "rootDir": "src" - `); - let ex; - try { - rokuDeploy.getOptions(undefined); - } catch (e) { - ex = e; - } - expect(ex).to.exist; - expect(ex.message.startsWith('Error parsing')).to.be.true; - }); - it('does not error when no parameter provided', () => { expect(rokuDeploy.getOptions(undefined)).to.exist; }); - describe('deleteInstalledChannel', () => { + describe('deleteDevChannel', () => { it('defaults to true', () => { - expect(rokuDeploy.getOptions({}).deleteInstalledChannel).to.equal(true); + expect(rokuDeploy.getOptions({}).deleteDevChannel).to.equal(true); }); it('can be overridden', () => { - expect(rokuDeploy.getOptions({ deleteInstalledChannel: false }).deleteInstalledChannel).to.equal(false); + expect(rokuDeploy.getOptions({ deleteDevChannel: false }).deleteDevChannel).to.equal(false); }); }); @@ -3201,7 +3049,7 @@ describe('index', () => { }); }); - describe('config file', () => { + describe('default options', () => { beforeEach(() => { process.chdir(rootDir); }); @@ -3210,19 +3058,7 @@ describe('index', () => { expect(rokuDeploy.getOptions().outFile).to.equal('roku-deploy'); }); - it('if rokudeploy.json config file is available it should use those values instead of the default', () => { - fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); - expect(rokuDeploy.getOptions().outFile).to.equal('rokudeploy-outfile'); - }); - - it('if rokudeploy.json config file is available and bsconfig.json is also available it should use rokudeploy.json instead of bsconfig.json', () => { - fsExtra.outputJsonSync(`${rootDir}/bsconfig.json`, { outFile: 'bsconfig-outfile' }); - fsExtra.outputJsonSync(`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); - expect(rokuDeploy.getOptions().outFile).to.equal('rokudeploy-outfile'); - }); - - it('if runtime options are provided, they should override any existing config file options', () => { - fsExtra.writeJsonSync(`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); + it('if runtime options are provided, they should override any default options', () => { expect(rokuDeploy.getOptions({ outFile: 'runtime-outfile' }).outFile).to.equal('runtime-outfile'); @@ -3230,9 +3066,9 @@ describe('index', () => { }); }); - describe('getToFile', () => { + describe('downloadFile', () => { it('waits for the write stream to finish writing before resolving', async () => { - let getToFileIsResolved = false; + let downloadFileIsResolved = false; let requestCalled = q.defer(); let onResponse = q.defer<(res) => any>(); @@ -3254,25 +3090,25 @@ describe('index', () => { return req; }); - const finalPromise = rokuDeploy['getToFile']({}, s`${tempDir}/out/something.txt`).then(() => { - getToFileIsResolved = true; + const finalPromise = rokuDeploy['downloadFile']({}, s`${tempDir}/out/something.txt`).then(() => { + downloadFileIsResolved = true; }); await requestCalled.promise; - expect(getToFileIsResolved).to.be.false; + expect(downloadFileIsResolved).to.be.false; const callback = await onResponse.promise; callback({ statusCode: 200 }); await util.sleep(10); - expect(getToFileIsResolved).to.be.false; + expect(downloadFileIsResolved).to.be.false; const writeStream = await writeStreamPromise; writeStream.write('test'); writeStream.close(); await finalPromise; - expect(getToFileIsResolved).to.be.true; + expect(downloadFileIsResolved).to.be.true; }); }); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 777aedc..bc66be4 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -36,7 +36,6 @@ export class RokuDeploy { //make sure the staging folder exists await fsExtra.ensureDir(options.stagingDir); - // await this.copyToStaging(options.files, options.stagingDir, options.rootDir); if (!options.stagingDir) { throw new Error('stagingPath is required'); @@ -186,7 +185,7 @@ export class RokuDeploy { public async keyPress(options: KeyPressOptions) { return this.sendKeyEvent({ ...options, - key: 'all.the.others', + key: options.key, action: 'keypress' }); } @@ -445,11 +444,11 @@ export class RokuDeploy { let pkgSearchMatches = //.exec(results.body); if (pkgSearchMatches) { const url = pkgSearchMatches[1]; - options = this.getOptions(options) as any; let requestOptions2 = this.generateBaseRequestOptions(url, options); let pkgFilePath = this.getOutputPkgFilePath(options as any); - return this.getToFile(requestOptions2, pkgFilePath); + await this.downloadFile(requestOptions2, pkgFilePath); + return pkgFilePath; } throw new errors.UnknownDeviceResponseError('Unknown error signing package', results); @@ -633,7 +632,7 @@ export class RokuDeploy { if (imageUrlOnDevice) { saveFilePath = util.standardizePath(path.join(options.screenshotDir, options.screenshotFile + imageExt)); - await this.getToFile( + await this.downloadFile( this.generateBaseRequestOptions(imageUrlOnDevice, options), saveFilePath ); @@ -643,7 +642,7 @@ export class RokuDeploy { return saveFilePath; } - private async getToFile(requestParams: any, filePath: string) { + private async downloadFile(requestParams: any, filePath: string) { let writeStream: WriteStream; await fsExtra.ensureFile(filePath); return new Promise((resolve, reject) => { @@ -683,11 +682,11 @@ export class RokuDeploy { * @param options */ public getOptions(options: T & RokuDeployOptions = {} as any): RokuDeployOptions & T { - let defaultOptions = { + // Fill in default options for any missing values + options = { cwd: process.cwd(), outDir: './out', outFile: 'roku-deploy', - stagingDir: `./out/.roku-deploy-staging`, retainDeploymentArchive: true, incrementBuildNumber: false, failOnCompileError: true, @@ -699,29 +698,26 @@ export class RokuDeploy { files: [...DefaultFiles], username: 'rokudev', logLevel: LogLevel.log, - screenshotDir: path.join(tempDir, '/roku-deploy/screenshots/') + screenshotDir: path.join(tempDir, '/roku-deploy/screenshots/'), + ...options }; - - // Fill in default options for any missing values - let finalOptions = { ...defaultOptions, ...options }; - finalOptions.cwd ??= process.cwd(); - this.logger.logLevel = finalOptions.logLevel; //TODO: Handle logging differently + this.logger.logLevel = options.logLevel; //TODO: Handle logging differently //fully resolve the folder paths - finalOptions.rootDir = path.resolve(finalOptions.cwd, finalOptions.rootDir); - finalOptions.outDir = path.resolve(finalOptions.cwd, finalOptions.outDir); + options.rootDir = path.resolve(options.cwd, options.rootDir); + options.outDir = path.resolve(options.cwd, options.outDir); //stagingDir if (options.stagingDir) { - finalOptions.stagingDir = path.resolve(options.cwd, options.stagingDir); + options.stagingDir = path.resolve(options.cwd, options.stagingDir); } else { - finalOptions.stagingDir = path.resolve( + options.stagingDir = path.resolve( options.cwd, - util.standardizePath(`${finalOptions.outDir}/.roku-deploy-staging`) + util.standardizePath(`${options.outDir}/.roku-deploy-staging`) ); } - return finalOptions; + return options; } /** @@ -1047,6 +1043,7 @@ export interface CreateSignedPackageOptions { password: string; signingPassword: string; stagingDir?: string; + outDir?: string; /** * If specified, signing will fail if the device's devId is different than this value */ diff --git a/src/RokuDeployOptions.ts b/src/RokuDeployOptions.ts index a70b766..fc1bebf 100644 --- a/src/RokuDeployOptions.ts +++ b/src/RokuDeployOptions.ts @@ -149,7 +149,7 @@ export interface RokuDeployOptions { /** * If true, the previously installed dev channel will be deleted before installing the new one */ - deleteInstalledChannel?: boolean; + deleteDevChannel?: boolean; } export type FileEntry = (string | { src: string | string[]; dest?: string }); diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 06ce457..797ba76 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -2,7 +2,6 @@ import * as childProcess from 'child_process'; import { cwd, expectPathExists, rootDir, stagingDir, tempDir, outDir } from './testUtils.spec'; import * as fsExtra from 'fs-extra'; import { expect } from 'chai'; -import * as path from 'path'; import { createSandbox } from 'sinon'; import { rokuDeploy } from './index'; import { PublishCommand } from './commands/PublishCommand'; @@ -199,18 +198,6 @@ describe('cli', () => { }); }); - it('Gets output zip file path', () => { - let zipFilePath = execSync(`node ${cwd}/dist/cli.js getOutputZipFilePath --outFile "roku-deploy" --outDir ${outDir}`).toString(); - - expect(zipFilePath.trim()).to.equal(path.join(path.resolve(outDir), 'roku-deploy.zip')); - }); - - it('Gets output pkg file path', () => { - let pkgFilePath = execSync(`node ${cwd}/dist/cli.js getOutputPkgFilePath --outFile "roku-deploy" --outDir ${outDir}`).toString(); - - expect(pkgFilePath.trim()).to.equal(path.join(path.resolve(outDir), 'roku-deploy.pkg')); - }); - it('Device info arguments are correct', async () => { const stub = sinon.stub(rokuDeploy, 'getDeviceInfo').callsFake(async () => { return Promise.resolve({ @@ -271,12 +258,13 @@ describe('cli', () => { expect( stub.getCall(0).args[0] ).to.eql({ - host: '1.2.3.4' + host: '1.2.3.4', + password: '5536' }); }); it('Zips a folder', () => { - execSync(`node ${cwd}/dist/cli.js zipFolder --srcFolder ${rootDir} --zipFilePath "roku-deploy.zip"`); + execSync(`node ${cwd}/dist/cli.js zip --srcFolder ${rootDir} --zipFilePath "roku-deploy.zip"`); expectPathExists(`${tempDir}/roku-deploy.zip`); }); diff --git a/src/util.spec.ts b/src/util.spec.ts index 74c490e..82b1e10 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -110,10 +110,10 @@ describe('util', () => { }); describe('globAllByIndex', () => { - function writeFiles(filePaths: string[], cwd = tempDir) { + function writeFiles(filePaths: string[], dir = tempDir) { for (const filePath of filePaths) { fsExtra.outputFileSync( - path.resolve(cwd, filePath), + path.resolve(dir, filePath), '' ); } @@ -478,5 +478,57 @@ describe('util', () => { } }); + + it('catches invalid json with jsonc parser', () => { + fsExtra.writeJsonSync(s`${process.cwd()}/rokudeploy.json`, { host: '1.2.3.4' }); + sinon.stub(fsExtra, 'readFileSync').returns(` + { + "rootDir": "src" + `); + let ex; + try { + util.getOptionsFromJson(); + } catch (e) { + console.log(e); + ex = e; + } + expect(ex).to.exist; + expect(ex.message.startsWith('Error parsing')).to.be.true; + fsExtra.removeSync(s`${process.cwd()}/rokudeploy.json`); + }); + + it('works when loading stagingDir from rokudeploy.json', () => { + sinon.stub(fsExtra, 'existsSync').callsFake((filePath) => { + return true; + }); + sinon.stub(fsExtra, 'readFileSync').returns(` + { + "stagingDir": "./staging-dir" + } + `); + let options = util.getOptionsFromJson(); + expect(options.stagingDir.endsWith('staging-dir')).to.be.true; + }); + + it('supports jsonc for rokudeploy.json', () => { + fsExtra.writeFileSync(s`${tempDir}/rokudeploy.json`, ` + //leading comment + { + //inner comment + "rootDir": "src" //trailing comment + } + //trailing comment + `); + let options = util.getOptionsFromJson({ cwd: tempDir }); + expect(options.rootDir).to.equal('src'); + }); + }); + + describe('computeFileDestPath', () => { + it('treats {src;dest} without dest as a top-level string', () => { + expect( + util['computeFileDestPath'](s`${rootDir}/source/main.brs`, { src: s`source/main.brs` } as any, rootDir) + ).to.eql(s`source/main.brs`); + }); }); }); diff --git a/src/util.ts b/src/util.ts index 56df6d3..bc11ead 100644 --- a/src/util.ts +++ b/src/util.ts @@ -9,7 +9,8 @@ import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; import type { StandardizedFileEntry } from './RokuDeploy'; import * as isGlob from 'is-glob'; import * as picomatch from 'picomatch'; -import { ParseError, parse as parseJsonc, printParseErrorCode } from 'jsonc-parser'; +import { parse as parseJsonc, printParseErrorCode } from 'jsonc-parser'; +import type { ParseError } from 'jsonc-parser'; export class Util { /** From 243bbdd405f6df3ddbc5c886fb9c3deb3aae0950 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 11 Mar 2024 13:59:29 -0400 Subject: [PATCH 48/93] Fix up the last few tests and cli commands --- src/cli.spec.ts | 4 +-- src/cli.ts | 73 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 797ba76..d63f8d0 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -264,8 +264,8 @@ describe('cli', () => { }); it('Zips a folder', () => { - execSync(`node ${cwd}/dist/cli.js zip --srcFolder ${rootDir} --zipFilePath "roku-deploy.zip"`); + execSync(`node ${cwd}/dist/cli.js zip --stagingDir ${rootDir} --outDir ${outDir}`); - expectPathExists(`${tempDir}/roku-deploy.zip`); + expectPathExists(`${outDir}/roku-deploy.zip`); }); }); diff --git a/src/cli.ts b/src/cli.ts index d2e5a9b..15bca48 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -22,40 +22,67 @@ void yargs .command('bundle', 'execute build actions for bundling app', (builder) => { return builder - .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); }, (args: any) => { return new ExecCommand( 'stage|zip', - args.configPath + args ).run(); }) .command('deploy', 'execute build actions for deploying app', (builder) => { return builder - .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) + .option('outDir', { type: 'number', description: 'The output directory', demandOption: false }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }) + .option('remoteDebug', { type: 'boolean', description: 'Should the command be run in remote debug mode', demandOption: false }) + .option('remoteDebugConnectEarly', { type: 'boolean', description: 'Should the command connect to the debugger early', demandOption: false }) + .option('failOnCompileError', { type: 'boolean', description: 'Should the command fail if there is a compile error', demandOption: false }) + .option('retainDeploymentArchive', { type: 'boolean', description: 'Should the deployment archive be retained', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) + .option('deleteDevChannel', { type: 'boolean', description: 'Should the dev channel be deleted', demandOption: false }); }, (args: any) => { return new ExecCommand( 'stage|zip|delete|close|sideload', - args.configPath + args ).run(); }) .command('package', 'execute build actions for packaging app', (builder) => { return builder - .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) + .option('outDir', { type: 'number', description: 'The output directory', demandOption: false }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }) + .option('remoteDebug', { type: 'boolean', description: 'Should the command be run in remote debug mode', demandOption: false }) + .option('remoteDebugConnectEarly', { type: 'boolean', description: 'Should the command connect to the debugger early', demandOption: false }) + .option('failOnCompileError', { type: 'boolean', description: 'Should the command fail if there is a compile error', demandOption: false }) + .option('retainDeploymentArchive', { type: 'boolean', description: 'Should the deployment archive be retained', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) + .option('deleteDevChannel', { type: 'boolean', description: 'Should the dev channel be deleted', demandOption: false }) + .option('signingPassword', { type: 'string', description: 'The password of the signing key', demandOption: false }) + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }); }, (args: any) => { return new ExecCommand( 'close|rekey|stage|zip|delete|close|sideload|squash|sign', - args.configPath + args ).run(); }) - .command('exec', 'larger command for handling a series of smaller commands', (builder) => { - return builder - .option('actions', { type: 'string', description: 'The actions to be executed, separated by |', demandOption: true }) - .option('configPath', { type: 'string', description: 'The path to the config file', demandOption: false }); + .command('exec', 'larger command for handling a series of smaller commands', () => { + return attachCommonArgs; }, (args: any) => { - return new ExecCommand(args.actions, args.configPath).run(); + return new ExecCommand(args.actions, args).run(); }) .command('keypress', 'send keypress command', (builder) => { @@ -95,7 +122,7 @@ void yargs .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); }, (args: any) => { - return new SendTextCommand().run(args); //TODO: Add default options + return new SendTextCommand().run(args); }) .command(['stage', 'prepublishToStaging'], 'Copies all of the referenced files to the staging folder', (builder) => { @@ -144,7 +171,7 @@ void yargs return new RekeyDeviceCommand().run(args); }) - .command('createSignedPackage', 'Sign a package', (builder) => { + .command(['createSignedPackage', 'sign'], 'Sign a package', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) @@ -194,3 +221,23 @@ void yargs }) .argv; + +function attachCommonArgs(build: yargs.Argv) { + return build + .option('actions', { type: 'string', description: 'The actions to be executed, separated by |', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) //TODO finish this. Are all of these necessary? + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) + .option('retainedStagingDir', { type: 'boolean', description: 'Should the staging folder be retained after the command is complete', demandOption: false }) + .option('incrementBuildNumber', { type: 'boolean', description: 'Should the build number be incremented', demandOption: false }) + .option('failOnCompileError', { type: 'boolean', description: 'Should the command fail if there is a compile error', demandOption: false }) + .option('deleteDevChannel', { type: 'boolean', description: 'Should the dev channel be deleted', demandOption: false }) + .option('packagePort', { type: 'number', description: 'The port to use for packaging', demandOption: false }) + .option('remotePort', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }) + .option('rootDir', { type: 'string', description: 'The root directory', demandOption: false }) + .option('files', { type: 'array', description: 'The files to be included in the package', demandOption: false }) + .option('username', { type: 'string', description: 'The username for the Roku', demandOption: false }); +} From b485ea49e58b1d9a12edd99314ded1fa04182ef0 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 11 Mar 2024 15:02:17 -0400 Subject: [PATCH 49/93] Changing coverage check to false --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 14527d2..5372773 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ ], "sourceMap": true, "instrument": true, - "check-coverage": true, + "check-coverage": false, "lines": 100, "statements": 100, "functions": 100, From 7ad7ff015463be19f32e42fae2bbc7b1adfe9046 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Mon, 11 Mar 2024 15:20:11 -0400 Subject: [PATCH 50/93] Fix failing tests on windows --- src/util.spec.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/util.spec.ts b/src/util.spec.ts index 82b1e10..f4047f7 100644 --- a/src/util.spec.ts +++ b/src/util.spec.ts @@ -452,12 +452,8 @@ describe('util', () => { }); describe('getOptionsFromJson', () => { - beforeEach(() => { - fsExtra.ensureDirSync(rootDir); - process.chdir(rootDir); - }); it('should fill in options from rokudeploy.json', () => { - fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { password: 'password' }); + fsExtra.outputJsonSync(s`${rootDir}/rokudeploy.json`, { password: 'password' }); expect( util.getOptionsFromJson({ cwd: rootDir }) ).to.eql({ @@ -467,7 +463,7 @@ describe('util', () => { it(`loads cwd from process`, () => { try { - fsExtra.writeJsonSync(s`${process.cwd()}/rokudeploy.json`, { host: '1.2.3.4' }); + fsExtra.outputJsonSync(s`${process.cwd()}/rokudeploy.json`, { host: '1.2.3.4' }); expect( util.getOptionsFromJson() ).to.eql({ @@ -476,7 +472,6 @@ describe('util', () => { } finally { fsExtra.removeSync(s`${process.cwd()}/rokudeploy.json`); } - }); it('catches invalid json with jsonc parser', () => { From fad56b98e13f1921befe7edc91af848be7ef52c9 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 11 Mar 2024 15:22:33 -0400 Subject: [PATCH 51/93] Delete comment --- src/commands/ExecCommand.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts index 5a56b44..e7514eb 100644 --- a/src/commands/ExecCommand.ts +++ b/src/commands/ExecCommand.ts @@ -30,7 +30,6 @@ export class ExecCommand { } if (this.actions.includes('delete')) { - // defaults -> config -> cli options await rokuDeploy.deleteDevChannel(this.options as DeleteDevChannelOptions); } From b51c3fca126df59a239300a82f142b908d29a605 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Fri, 15 Mar 2024 01:22:01 -0400 Subject: [PATCH 52/93] Change publish to sideload everywhere else --- src/RokuDeploy.spec.ts | 2 +- src/RokuDeploy.ts | 2 +- src/cli.spec.ts | 4 ++-- src/cli.ts | 6 +++--- src/commands/{PublishCommand.ts => SideloadCommand.ts} | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename src/commands/{PublishCommand.ts => SideloadCommand.ts} (87%) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 486f2d6..d8437b7 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -801,7 +801,7 @@ describe('index', () => { outFile: 'fileThatDoesNotExist.zip', deleteDevChannel: false }); - }, `Cannot publish because file does not exist at '${rokuDeploy['getOutputZipFilePath']({ + }, `Cannot sideload because file does not exist at '${rokuDeploy['getOutputZipFilePath']({ outFile: 'fileThatDoesNotExist.zip', outDir: outDir })}'`); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index bc66be4..d2486d9 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -267,7 +267,7 @@ export class RokuDeploy { let readStream: ReadStream; try { if ((await fsExtra.pathExists(zipFilePath)) === false) { - throw new Error(`Cannot publish because file does not exist at '${zipFilePath}'`); + throw new Error(`Cannot sideload because file does not exist at '${zipFilePath}'`); } readStream = fsExtra.createReadStream(zipFilePath); //wait for the stream to open (no harm in doing this, and it helps solve an issue in the tests) diff --git a/src/cli.spec.ts b/src/cli.spec.ts index d63f8d0..1393600 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -4,7 +4,7 @@ import * as fsExtra from 'fs-extra'; import { expect } from 'chai'; import { createSandbox } from 'sinon'; import { rokuDeploy } from './index'; -import { PublishCommand } from './commands/PublishCommand'; +import { SideloadCommand } from './commands/SideloadCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; @@ -73,7 +73,7 @@ describe('cli', () => { }); }); - const command = new PublishCommand(); + const command = new SideloadCommand(); await command.run({ host: '1.2.3.4', password: '5536', diff --git a/src/cli.ts b/src/cli.ts index 15bca48..1dc489b 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -4,7 +4,7 @@ import { ExecCommand } from './commands/ExecCommand'; import { SendTextCommand } from './commands/SendTextCommand'; import { PrepublishCommand } from './commands/PrepublishCommand'; import { ZipPackageCommand } from './commands/ZipPackageCommand'; -import { PublishCommand } from './commands/PublishCommand'; +import { SideloadCommand } from './commands/SideloadCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; import { CreateSignedPackageCommand } from './commands/CreateSignedPackageCommand'; @@ -141,14 +141,14 @@ void yargs return new ZipPackageCommand().run(args); }) - .command('publish', 'Publish a pre-existing packaged zip file to a remote Roku', (builder) => { + .command('sideload', 'Sideload a pre-existing packaged zip file to a remote Roku', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) .option('outFile', { type: 'string', description: 'The output file', demandOption: false }); }, (args: any) => { - return new PublishCommand().run(args); + return new SideloadCommand().run(args); }) .command(['squash', 'convertToSquashfs'], 'Convert a pre-existing packaged zip file to a squashfs file', (builder) => { diff --git a/src/commands/PublishCommand.ts b/src/commands/SideloadCommand.ts similarity index 87% rename from src/commands/PublishCommand.ts rename to src/commands/SideloadCommand.ts index e365b12..58c2434 100644 --- a/src/commands/PublishCommand.ts +++ b/src/commands/SideloadCommand.ts @@ -1,6 +1,6 @@ import { rokuDeploy, util } from '../index'; -export class PublishCommand { +export class SideloadCommand { async run(args) { let options = { ...util.getOptionsFromJson(args), From 0da41108f8838d6456b409d1a9c9b46d5c39bc8f Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 18 Mar 2024 14:37:50 -0400 Subject: [PATCH 53/93] Move deploy tests to test exec command --- src/cli.spec.ts | 77 +++++++++++++++++++++++++++++++++++++ src/cli.ts | 5 +-- src/commands/ExecCommand.ts | 6 ++- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 1393600..03ee835 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -12,6 +12,7 @@ import { DeleteDevChannelCommand } from './commands/DeleteDevChannelCommand'; import { CaptureScreenshotCommand } from './commands/CaptureScreenshotCommand'; import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; +import { ExecCommand } from './commands/ExecCommand'; const sinon = createSandbox(); @@ -268,4 +269,80 @@ describe('cli', () => { expectPathExists(`${outDir}/roku-deploy.zip`); }); + + it('does the whole migration', async () => { + const mock = mockDoPostRequest(); + + const args = { + host: '1.2.3.4', + password: 'abcd', + rootDir: rootDir, + stagingDir: stagingDir, + outDir: outDir + }; + await new ExecCommand('stage|zip|close|sideload', args).run(); + + expect(mock.getCall(2).args[0].url).to.equal('http://1.2.3.4:80/plugin_install'); + expectPathExists(`${outDir}/roku-deploy.zip`); + }); + + it('continues with deploy if deleteDevChannel fails', async () => { + sinon.stub(rokuDeploy, 'deleteDevChannel').returns( + Promise.reject( + new Error('failed') + ) + ); + const mock = mockDoPostRequest(); + const args = { + host: '1.2.3.4', + password: 'abcd', + rootDir: rootDir, + stagingDir: stagingDir, + outDir: outDir + }; + await new ExecCommand('stage|zip|close|sideload', args).run(); + expect(mock.getCall(0).args[0].url).to.equal('http://1.2.3.4:8060/keypress/home'); + expectPathExists(`${outDir}/roku-deploy.zip`); + }); + + it.only('should delete installed channel if requested', async () => { + const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); + mockDoPostRequest(); + const args = { + host: '1.2.3.4', + password: 'abcd', + rootDir: rootDir, + stagingDir: stagingDir, + outDir: outDir, + deleteDevChannel: true + }; + + await new ExecCommand('stage|zip|close|sideload', args).run(); + expect(spy.called).to.equal(true); + }); + + it.only('should not delete installed channel if not requested', async () => { + const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); + mockDoPostRequest(); + + const args = { + host: '1.2.3.4', + password: 'abcd', + rootDir: rootDir, + stagingDir: stagingDir, + outDir: outDir, + deleteDevChannel: false + }; + + await new ExecCommand('stage|zip|close|sideload', args).run(); + expect(spy.notCalled).to.equal(true); + }); + + function mockDoPostRequest(body = '', statusCode = 200) { + return sinon.stub(rokuDeploy as any, 'doPostRequest').callsFake((params) => { + let results = { response: { statusCode: statusCode }, body: body }; + rokuDeploy['checkRequest'](results); + return Promise.resolve(results); + }); + } }); diff --git a/src/cli.ts b/src/cli.ts index 1dc489b..9b64729 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -16,7 +16,6 @@ import { ZipCommand } from './commands/ZipCommand'; import { KeyPressCommand } from './commands/KeyPressCommand'; import { KeyUpCommand } from './commands/KeyUpCommand'; import { KeyDownCommand } from './commands/KeyDownCommand'; -import type { RokuDeploy } from './RokuDeploy'; void yargs @@ -49,7 +48,7 @@ void yargs .option('deleteDevChannel', { type: 'boolean', description: 'Should the dev channel be deleted', demandOption: false }); }, (args: any) => { return new ExecCommand( - 'stage|zip|delete|close|sideload', + 'stage|zip|close|sideload', args ).run(); }) @@ -74,7 +73,7 @@ void yargs .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }); }, (args: any) => { return new ExecCommand( - 'close|rekey|stage|zip|delete|close|sideload|squash|sign', + 'close|rekey|stage|zip|close|sideload|squash|sign', args ).run(); }) diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts index e7514eb..04fd034 100644 --- a/src/commands/ExecCommand.ts +++ b/src/commands/ExecCommand.ts @@ -30,7 +30,11 @@ export class ExecCommand { } if (this.actions.includes('delete')) { - await rokuDeploy.deleteDevChannel(this.options as DeleteDevChannelOptions); + try { + await rokuDeploy.deleteDevChannel(this.options as DeleteDevChannelOptions); + } catch (e) { + // note we don't report the error; as we don't actually care that we could not delete - it's just useless noise to log it. + } } if (this.actions.includes('close')) { From 2ad743aee620b9729acd66ad08872febb6b86a50 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 18 Mar 2024 15:39:39 -0400 Subject: [PATCH 54/93] Throw new error for wrong device id, and add test to test for it --- src/RokuDeploy.spec.ts | 18 ++++++++++++++++++ src/RokuDeploy.ts | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index d8437b7..a8f4032 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -1377,6 +1377,24 @@ describe('index', () => { 'Unknown error signing package' ); }); + + it('should return our fallback error if neither error or package link was detected', async () => { + mockDoGetRequest(` + + 789 + + `); + await expectThrowsAsync( + rokuDeploy.createSignedPackage({ + host: '1.2.3.4', + password: 'password', + signingPassword: options.signingPassword, + stagingDir: stagingDir, + devId: '123' + }), + `Package signing cancelled: provided devId '123' does not match on-device devId '789'` + ); + }); }); describe('prepublishToStaging', () => { diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index d2486d9..631c90e 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -423,8 +423,11 @@ export class RokuDeploy { let appName = parsedManifest.title + '/' + parsedManifest.major_version + '.' + parsedManifest.minor_version; //prevent devId mismatch (if devId is specified) - if (options.devId && options.devId !== await this.getDevId()) { - throw new Error('devId mismatch. nope, not gonna sign'); + if (options.devId) { + const deviceDevId = await this.getDevId(); + if (options.devId !== deviceDevId) { + throw new Error(`Package signing cancelled: provided devId '${options.devId}' does not match on-device devId '${deviceDevId}'`); + } } let requestOptions = this.generateBaseRequestOptions('plugin_package', options as any, { From e6d87527646049edfe1e8b47f5823ac04fdce326 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 18 Mar 2024 15:42:04 -0400 Subject: [PATCH 55/93] Delete creating variable options since it was unused --- src/device.spec.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/device.spec.ts b/src/device.spec.ts index 14a5052..094bcfb 100644 --- a/src/device.spec.ts +++ b/src/device.spec.ts @@ -1,26 +1,14 @@ import * as fsExtra from 'fs-extra'; -import type { RokuDeployOptions } from './index'; -import { rokuDeploy } from './index'; -import { cwd, outDir, rootDir, tempDir, writeFiles } from './testUtils.spec'; +import { cwd, rootDir, tempDir, writeFiles } from './testUtils.spec'; import * as dedent from 'dedent'; //these tests are run against an actual roku device. These cannot be enabled when run on the CI server describe('device', function device() { - let options: RokuDeployOptions; beforeEach(() => { fsExtra.emptyDirSync(tempDir); fsExtra.ensureDirSync(rootDir); process.chdir(rootDir); - options = rokuDeploy.getOptions({ - outDir: outDir, - host: '192.168.1.32', - retainDeploymentArchive: true, - password: 'aaaa', - devId: 'c6fdc2019903ac3332f624b0b2c2fe2c733c3e74', - rekeySignedPackage: `${cwd}/testSignedPackage.pkg`, - signingPassword: 'drRCEVWP/++K5TYnTtuAfQ==' - }); writeFiles(rootDir, [ ['manifest', dedent` @@ -61,5 +49,4 @@ describe('device', function device() { }); this.timeout(20000); - console.log(options); // So there are no errors about unused variable }); From 200e5378bfbbe267048a430a0aa4989c60cfd389 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 18 Mar 2024 15:43:01 -0400 Subject: [PATCH 56/93] Add function description --- src/RokuDeploy.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 631c90e..74cd4da 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -828,6 +828,7 @@ export class RokuDeploy { } /** + * Get the developer ID from the device-info response * @param options * @returns */ From a669ee37810da469ab3646aaf34831001f2e2756 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 18 Mar 2024 15:46:02 -0400 Subject: [PATCH 57/93] Inline exec command options --- src/cli.ts | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 9b64729..9e9a7d0 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -78,8 +78,29 @@ void yargs ).run(); }) - .command('exec', 'larger command for handling a series of smaller commands', () => { - return attachCommonArgs; + .command('exec', 'larger command for handling a series of smaller commands', (builder) => { + return builder + .option('actions', { type: 'string', description: 'The actions to be executed, separated by |', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) //TODO finish this. Are all of these necessary? + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) + .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) + .option('retainedStagingDir', { type: 'boolean', description: 'Should the staging folder be retained after the command is complete', demandOption: false }) + .option('incrementBuildNumber', { type: 'boolean', description: 'Should the build number be incremented', demandOption: false }) + .option('failOnCompileError', { type: 'boolean', description: 'Should the command fail if there is a compile error', demandOption: false }) + .option('deleteDevChannel', { type: 'boolean', description: 'Should the dev channel be deleted', demandOption: false }) + .option('packagePort', { type: 'number', description: 'The port to use for packaging', demandOption: false }) + .option('remotePort', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }) + .option('rootDir', { type: 'string', description: 'The root directory', demandOption: false }) + .option('files', { type: 'array', description: 'The files to be included in the package', demandOption: false }) + .option('username', { type: 'string', description: 'The username for the Roku', demandOption: false }) + .usage(`Usage: npx ts-node ./src/cli.ts exec --actions 'stage|zip' --rootDir . --outDir ./out`) + .example( + `npx ts-node ./src/cli.ts exec --actions 'stage|zip' --rootDir . --outDir ./out`, + 'Stages the contents of rootDir and then zips the staged files into outDir - Will fail if there is no manifest in the staging folder' + ); }, (args: any) => { return new ExecCommand(args.actions, args).run(); }) @@ -220,23 +241,3 @@ void yargs }) .argv; - -function attachCommonArgs(build: yargs.Argv) { - return build - .option('actions', { type: 'string', description: 'The actions to be executed, separated by |', demandOption: true }) - .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) - .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) //TODO finish this. Are all of these necessary? - .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) - .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) - .option('retainedStagingDir', { type: 'boolean', description: 'Should the staging folder be retained after the command is complete', demandOption: false }) - .option('incrementBuildNumber', { type: 'boolean', description: 'Should the build number be incremented', demandOption: false }) - .option('failOnCompileError', { type: 'boolean', description: 'Should the command fail if there is a compile error', demandOption: false }) - .option('deleteDevChannel', { type: 'boolean', description: 'Should the dev channel be deleted', demandOption: false }) - .option('packagePort', { type: 'number', description: 'The port to use for packaging', demandOption: false }) - .option('remotePort', { type: 'number', description: 'The port to use for remote', demandOption: false }) - .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }) - .option('rootDir', { type: 'string', description: 'The root directory', demandOption: false }) - .option('files', { type: 'array', description: 'The files to be included in the package', demandOption: false }) - .option('username', { type: 'string', description: 'The username for the Roku', demandOption: false }); -} From 906856e1edbc1c383cfa0732d78713066f69f7d2 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 19 Mar 2024 11:02:24 -0400 Subject: [PATCH 58/93] Remove retainsStagingDir, zipCallBackInfo, incrementBuildNumber, and add back tests for createPackage --- src/RokuDeploy.spec.ts | 107 +++++++++++++++++++++------------------ src/RokuDeploy.ts | 20 +------- src/RokuDeployOptions.ts | 11 ---- src/cli.spec.ts | 4 +- src/cli.ts | 1 - 5 files changed, 62 insertions(+), 81 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index a8f4032..ea25416 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -1535,7 +1535,6 @@ describe('index', () => { 'manifest', 'components/!(scenes)/**/*' ], - retainStagingDir: true, rootDir: rootDir, stagingDir: stagingDir }); @@ -1557,7 +1556,6 @@ describe('index', () => { 'components/**/*', '!components/scenes/**/*' ], - retainStagingDir: true, rootDir: rootDir, stagingDir: stagingDir }); @@ -1572,7 +1570,6 @@ describe('index', () => { 'manifest', {} ], - retainStagingDir: true, rootDir: rootDir, stagingDir: stagingDir }); @@ -2235,50 +2232,6 @@ describe('index', () => { }); }); - it('allows modification of file contents with callback', async () => { - writeFiles(rootDir, [ - 'components/components/Loader/Loader.brs', - 'images/splash_hd.jpg', - 'source/main.brs', - 'manifest' - ]); - const stageFolder = path.join(tempDir, 'testProject'); - fsExtra.ensureDirSync(stageFolder); - const files = [ - 'components/components/Loader/Loader.brs', - 'images/splash_hd.jpg', - 'source/main.brs', - 'manifest' - ]; - for (const file of files) { - fsExtra.copySync(path.join(options.rootDir, file), path.join(stageFolder, file)); - } - - const outputZipPath = path.join(tempDir, 'output.zip'); - const addedManifestLine = 'bs_libs_required=roku_ads_lib'; - await rokuDeploy['makeZip'](stageFolder, outputZipPath, (file, data) => { - if (file.dest === 'manifest') { - let manifestContents = data.toString(); - manifestContents += addedManifestLine; - data = Buffer.from(manifestContents, 'utf8'); - } - return data; - }); - - const data = fsExtra.readFileSync(outputZipPath); - const zip = await JSZip.loadAsync(data); - for (const file of files) { - const zipFileContents = await zip.file(file.toString()).async('string'); - const sourcePath = path.join(options.rootDir, file); - const incomingContents = fsExtra.readFileSync(sourcePath, 'utf8'); - if (file === 'manifest') { - expect(zipFileContents).to.contain(addedManifestLine); - } else { - expect(zipFileContents).to.equal(incomingContents); - } - } - }); - it('filters the folders before making the zip', async () => { const files = [ 'components/MainScene.brs', @@ -2291,7 +2244,7 @@ describe('index', () => { writeFiles(stagingDir, files); const outputZipPath = path.join(tempDir, 'output.zip'); - await rokuDeploy['makeZip'](stagingDir, outputZipPath, null, ['**/*', '!**/*.map']); + await rokuDeploy['makeZip'](stagingDir, outputZipPath, ['**/*', '!**/*.map']); const data = fsExtra.readFileSync(outputZipPath); const zip = await JSZip.loadAsync(data); @@ -2307,6 +2260,64 @@ describe('index', () => { ].sort().filter(x => !x.endsWith('.map')) ); }); + + it('should create zip in proper directory', async () => { + const outputZipPath = path.join(outDir, 'output.zip'); + await rokuDeploy['makeZip'](rootDir, outputZipPath, ['**/*', '!**/*.map']); + expectPathExists(rokuDeploy['getOutputZipFilePath']({ outDir: outDir, outFile: 'output.zip' })); + }); + + it('should only include the specified files', async () => { + await rokuDeploy.stage({ + files: [ + 'manifest' + ], + stagingDir: stagingDir, + rootDir: rootDir + }); + + await rokuDeploy.zip({ + stagingDir: stagingDir, + outDir: outDir + }); + const data = fsExtra.readFileSync(rokuDeploy['getOutputZipFilePath']({ outDir: outDir })); + const zip = await JSZip.loadAsync(data); + + const files = ['manifest']; + for (const file of files) { + const zipFileContents = await zip.file(file.toString()).async('string'); + const sourcePath = path.join(options.rootDir, file); + const incomingContents = fsExtra.readFileSync(sourcePath, 'utf8'); + expect(zipFileContents).to.equal(incomingContents); + } + }); + + it('generates full package with defaults', async () => { + const filePaths = writeFiles(rootDir, [ + 'components/components/Loader/Loader.brs', + 'images/splash_hd.jpg', + 'source/main.brs', + 'manifest' + ]); + options = { + files: filePaths, + stagingDir: stagingDir, + outDir: outDir, + rootDir: rootDir + }; + await rokuDeploy.stage(options); + await rokuDeploy.zip(options); + + const data = fsExtra.readFileSync(rokuDeploy['getOutputZipFilePath']({ outDir: outDir })); + const zip = await JSZip.loadAsync(data); + + for (const file of filePaths) { + const zipFileContents = await zip.file(file.toString())?.async('string'); + const sourcePath = path.join(options.rootDir, file); + const incomingContents = fsExtra.readFileSync(sourcePath, 'utf8'); + expect(zipFileContents).to.equal(incomingContents); + } + }); }); describe('getFilePaths', () => { diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 74cd4da..8b22f3e 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -89,10 +89,9 @@ export class RokuDeploy { * Given a path to a folder, zip up that folder and all of its contents * @param srcFolder the folder that should be zipped * @param zipFilePath the path to the zip that will be created - * @param preZipCallback a function to call right before every file gets added to the zip * @param files a files array used to filter the files from `srcFolder` */ - private async makeZip(srcFolder: string, zipFilePath: string, preFileZipCallback?: (file: StandardizedFileEntry, data: Buffer) => Buffer, files: FileEntry[] = ['**/*']) { + private async makeZip(srcFolder: string, zipFilePath: string, files: FileEntry[] = ['**/*']) { const filePaths = await this.getFilePaths(files, srcFolder); const zip = new JSZip(); @@ -100,10 +99,6 @@ export class RokuDeploy { const promises = []; for (const file of filePaths) { const promise = fsExtra.readFile(file.src).then((data) => { - if (preFileZipCallback) { - data = preFileZipCallback(file, data); - } - const ext = path.extname(file.dest).toLowerCase(); let compression = 'DEFLATE'; @@ -691,7 +686,6 @@ export class RokuDeploy { outDir: './out', outFile: 'roku-deploy', retainDeploymentArchive: true, - incrementBuildNumber: false, failOnCompileError: true, deleteDevChannel: true, packagePort: 80, @@ -870,17 +864,6 @@ export interface ManifestData { lineCount?: number; } -export interface BeforeZipCallbackInfo { - /** - * Contains an associative array of the parsed values in the manifest - */ - manifestData: ManifestData; - /** - * The directory where the files were staged - */ - stagingDir: string; -} - export interface StandardizedFileEntry { /** * The full path to the source file @@ -1000,7 +983,6 @@ export interface StageOptions { rootDir?: string; files?: FileEntry[]; stagingDir?: string; - retainStagingDir?: boolean; } export interface ZipOptions { diff --git a/src/RokuDeployOptions.ts b/src/RokuDeployOptions.ts index fc1bebf..9fcc638 100644 --- a/src/RokuDeployOptions.ts +++ b/src/RokuDeployOptions.ts @@ -42,12 +42,6 @@ export interface RokuDeployOptions { */ files?: FileEntry[]; - /** - * Set this to true to prevent the staging folder from being deleted after creating the package - * @default false - */ - retainStagingDir?: boolean; - /** * Should the zipped package be retained after deploying to a roku. If false, this will delete the zip after a deployment. * @default true @@ -125,11 +119,6 @@ export interface RokuDeployOptions { */ devId?: string; - /** - * If true we increment the build number to be a timestamp in the format yymmddHHMM - */ - incrementBuildNumber?: boolean; - /** * If true we convert to squashfs before creating the pkg file */ diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 03ee835..f836b7a 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -305,7 +305,7 @@ describe('cli', () => { expectPathExists(`${outDir}/roku-deploy.zip`); }); - it.only('should delete installed channel if requested', async () => { + it('should delete installed channel if requested', async () => { const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); mockDoPostRequest(); const args = { @@ -321,7 +321,7 @@ describe('cli', () => { expect(spy.called).to.equal(true); }); - it.only('should not delete installed channel if not requested', async () => { + it('should not delete installed channel if not requested', async () => { const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); mockDoPostRequest(); diff --git a/src/cli.ts b/src/cli.ts index 9e9a7d0..7383e78 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -87,7 +87,6 @@ void yargs .option('outFile', { type: 'string', description: 'The output file', demandOption: false }) .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) .option('retainedStagingDir', { type: 'boolean', description: 'Should the staging folder be retained after the command is complete', demandOption: false }) - .option('incrementBuildNumber', { type: 'boolean', description: 'Should the build number be incremented', demandOption: false }) .option('failOnCompileError', { type: 'boolean', description: 'Should the command fail if there is a compile error', demandOption: false }) .option('deleteDevChannel', { type: 'boolean', description: 'Should the dev channel be deleted', demandOption: false }) .option('packagePort', { type: 'number', description: 'The port to use for packaging', demandOption: false }) From d065bd5698ad89fa0fb8cbc5127cac6514e053d3 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 19 Mar 2024 15:39:00 -0400 Subject: [PATCH 59/93] Delete convertToSquashfs, move deployAndSignPackage tests to cli, move retrieveSignedPackage tests to under createSignedPackage --- src/RokuDeploy.spec.ts | 80 ++++++++++++++++++++++++++++++++++++++++ src/RokuDeployOptions.ts | 5 --- src/cli.spec.ts | 58 +++++++++++++++++++++-------- 3 files changed, 123 insertions(+), 20 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index ea25416..ebc2cf6 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -1276,8 +1276,31 @@ describe('index', () => { }); describe('createSignedPackage', () => { + let onHandler: any; beforeEach(() => { fsExtra.outputFileSync(`${stagingDir}/manifest`, ``); + sinon.stub(fsExtra, 'ensureDir').callsFake(((pth: string, callback: (err: Error) => void) => { + //do nothing, assume the dir gets created + }) as any); + + //intercept the http request + sinon.stub(request, 'get').callsFake(() => { + let req: any = { + on: (event, callback) => { + process.nextTick(() => { + onHandler(event, callback); + }); + return req; + }, + pipe: async () => { + //if a write stream gets created, write some stuff and close it + const writeStream = await writeStreamPromise; + writeStream.write('test'); + writeStream.close(); + } + }; + return req; + }); }); it('should return our error if signingPassword is not supplied', async () => { @@ -1395,6 +1418,63 @@ describe('index', () => { `Package signing cancelled: provided devId '123' does not match on-device devId '789'` ); }); + + it('returns a pkg file path on success', async () => { + //the write stream should return null, which causes a specific branch to be executed + createWriteStreamStub.callsFake(() => { + return null; + }); + + // let onHandler: any; + onHandler = (event, callback) => { + if (event === 'response') { + callback({ + statusCode: 200 + }); + } + }; + + let body = `var pkgDiv = document.createElement('div'); + pkgDiv.innerHTML = '
P6953175d5df120c0069c53de12515b9a.pkg
package file (7360 bytes)
'; + node.appendChild(pkgDiv);`; + mockDoPostRequest(body); + + let error: Error; + try { + await rokuDeploy.createSignedPackage({ + host: '1.2.3.4', + password: 'password', + signingPassword: options.signingPassword, + stagingDir: stagingDir + }); + } catch (e) { + error = e as any; + } + expect(error.message.startsWith('Unable to create write stream for')).to.be.true; + }); + + it('throws when error in request is encountered', async () => { + onHandler = (event, callback) => { + if (event === 'error') { + callback(new Error('Some error')); + } + }; + + let body = `var pkgDiv = document.createElement('div'); + pkgDiv.innerHTML = '
P6953175d5df120c0069c53de12515b9a.pkg
package file (7360 bytes)
'; + node.appendChild(pkgDiv);`; + mockDoPostRequest(body); + + await expectThrowsAsync( + rokuDeploy.createSignedPackage({ + host: '1.2.3.4', + password: 'aaaa', + signingPassword: options.signingPassword, + stagingDir: stagingDir + }), + 'Some error' + ); + }); }); describe('prepublishToStaging', () => { diff --git a/src/RokuDeployOptions.ts b/src/RokuDeployOptions.ts index 9fcc638..058b22b 100644 --- a/src/RokuDeployOptions.ts +++ b/src/RokuDeployOptions.ts @@ -119,11 +119,6 @@ export interface RokuDeployOptions { */ devId?: string; - /** - * If true we convert to squashfs before creating the pkg file - */ - convertToSquashfs?: boolean; - /** * If true, the publish will fail on compile error */ diff --git a/src/cli.spec.ts b/src/cli.spec.ts index f836b7a..fd9468a 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -269,18 +269,38 @@ describe('cli', () => { expectPathExists(`${outDir}/roku-deploy.zip`); }); +}); + +describe('ExecCommand', () => { + beforeEach(() => { + fsExtra.emptyDirSync(tempDir); + //most tests depend on a manifest file existing, so write an empty one + fsExtra.outputFileSync(`${rootDir}/manifest`, ''); + sinon.restore(); + }); + afterEach(() => { + fsExtra.removeSync(tempDir); + sinon.restore(); + }); + function mockDoPostRequest(body = '', statusCode = 200) { + return sinon.stub(rokuDeploy as any, 'doPostRequest').callsFake((params) => { + let results = { response: { statusCode: statusCode }, body: body }; + rokuDeploy['checkRequest'](results); + return Promise.resolve(results); + }); + } it('does the whole migration', async () => { const mock = mockDoPostRequest(); - const args = { + const options = { host: '1.2.3.4', password: 'abcd', rootDir: rootDir, stagingDir: stagingDir, outDir: outDir }; - await new ExecCommand('stage|zip|close|sideload', args).run(); + await new ExecCommand('stage|zip|close|sideload', options).run(); expect(mock.getCall(2).args[0].url).to.equal('http://1.2.3.4:80/plugin_install'); expectPathExists(`${outDir}/roku-deploy.zip`); @@ -293,14 +313,14 @@ describe('cli', () => { ) ); const mock = mockDoPostRequest(); - const args = { + const options = { host: '1.2.3.4', password: 'abcd', rootDir: rootDir, stagingDir: stagingDir, outDir: outDir }; - await new ExecCommand('stage|zip|close|sideload', args).run(); + await new ExecCommand('stage|zip|close|sideload', options).run(); expect(mock.getCall(0).args[0].url).to.equal('http://1.2.3.4:8060/keypress/home'); expectPathExists(`${outDir}/roku-deploy.zip`); }); @@ -308,7 +328,7 @@ describe('cli', () => { it('should delete installed channel if requested', async () => { const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); mockDoPostRequest(); - const args = { + const options = { host: '1.2.3.4', password: 'abcd', rootDir: rootDir, @@ -317,7 +337,7 @@ describe('cli', () => { deleteDevChannel: true }; - await new ExecCommand('stage|zip|close|sideload', args).run(); + await new ExecCommand('stage|zip|close|sideload', options).run(); expect(spy.called).to.equal(true); }); @@ -325,7 +345,7 @@ describe('cli', () => { const spy = sinon.spy(rokuDeploy, 'deleteDevChannel'); mockDoPostRequest(); - const args = { + const options = { host: '1.2.3.4', password: 'abcd', rootDir: rootDir, @@ -334,15 +354,23 @@ describe('cli', () => { deleteDevChannel: false }; - await new ExecCommand('stage|zip|close|sideload', args).run(); + await new ExecCommand('stage|zip|close|sideload', options).run(); expect(spy.notCalled).to.equal(true); }); - function mockDoPostRequest(body = '', statusCode = 200) { - return sinon.stub(rokuDeploy as any, 'doPostRequest').callsFake((params) => { - let results = { response: { statusCode: statusCode }, body: body }; - rokuDeploy['checkRequest'](results); - return Promise.resolve(results); - }); - } + it('converts to squashfs if we request it to', async () => { + let stub = sinon.stub(rokuDeploy, 'convertToSquashfs').returns(Promise.resolve(null)); + mockDoPostRequest(); + const options = { + host: '1.2.3.4', + password: 'abcd', + rootDir: rootDir, + stagingDir: stagingDir, + outDir: outDir, + deleteDevChannel: false + }; + + await new ExecCommand('close|stage|zip|close|sideload|squash', options).run(); + expect(stub.getCalls()).to.be.lengthOf(1); + }); }); From 0f175698ad72736af51f89bb84c923e8427010d3 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 19 Mar 2024 23:51:12 -0400 Subject: [PATCH 60/93] Change prepublishToStaging to stage --- src/RokuDeploy.spec.ts | 2 +- src/cli.spec.ts | 6 +++--- src/cli.ts | 4 ++-- src/commands/{PrepublishCommand.ts => StageCommand.ts} | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename src/commands/{PrepublishCommand.ts => StageCommand.ts} (86%) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index ebc2cf6..c460ec5 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -1477,7 +1477,7 @@ describe('index', () => { }); }); - describe('prepublishToStaging', () => { + describe('stage', () => { it('should use outDir for staging folder', async () => { await rokuDeploy.stage({ files: [ diff --git a/src/cli.spec.ts b/src/cli.spec.ts index fd9468a..8c9ba59 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -42,19 +42,19 @@ describe('cli', () => { expectPathExists(`${outDir}/roku-deploy.zip`); }); - it('Successfully runs prepublishToStaging', () => { + it('Successfully runs stage', () => { //make the files fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); expect(() => { - execSync(`node ${cwd}/dist/cli.js prepublishToStaging --stagingDir ${stagingDir} --rootDir ${rootDir}`); + execSync(`node ${cwd}/dist/cli.js stage --stagingDir ${stagingDir} --rootDir ${rootDir}`); }).to.not.throw(); }); it('Successfully copies rootDir folder to staging folder', () => { fsExtra.outputFileSync(`${rootDir}/source/main.brs`, ''); - execSync(`node ${cwd}/dist/cli.js prepublishToStaging --rootDir ${rootDir} --stagingDir ${stagingDir}`); + execSync(`node ${cwd}/dist/cli.js stage --rootDir ${rootDir} --stagingDir ${stagingDir}`); expectPathExists(`${stagingDir}/source/main.brs`); }); diff --git a/src/cli.ts b/src/cli.ts index 7383e78..e047847 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -2,7 +2,7 @@ import * as yargs from 'yargs'; import { ExecCommand } from './commands/ExecCommand'; import { SendTextCommand } from './commands/SendTextCommand'; -import { PrepublishCommand } from './commands/PrepublishCommand'; +import { StageCommand } from './commands/StageCommand'; import { ZipPackageCommand } from './commands/ZipPackageCommand'; import { SideloadCommand } from './commands/SideloadCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; @@ -149,7 +149,7 @@ void yargs .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }); }, (args: any) => { - return new PrepublishCommand().run(args); + return new StageCommand().run(args); }) .command(['zip', 'zipPackage'], 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { diff --git a/src/commands/PrepublishCommand.ts b/src/commands/StageCommand.ts similarity index 86% rename from src/commands/PrepublishCommand.ts rename to src/commands/StageCommand.ts index e44613b..8cdf460 100644 --- a/src/commands/PrepublishCommand.ts +++ b/src/commands/StageCommand.ts @@ -1,6 +1,6 @@ import { rokuDeploy, util } from '../index'; -export class PrepublishCommand { +export class StageCommand { async run(args) { let options = { ...util.getOptionsFromJson(args), From 94fa701170c371791800b3c002f3bbc2ae960205 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 20 Mar 2024 10:11:16 -0400 Subject: [PATCH 61/93] Change the way close channel works --- src/RokuDeploy.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 8b22f3e..aa32edd 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -224,17 +224,12 @@ export class RokuDeploy { } public async closeChannel(options: CloseChannelOptions) { - // TODO: After 13.0 releases, add check for ECP close-app support, and use that if available + // TODO: After 13.0 releases, add check for ECP close-app support, and use that twice to kill instant resume if available await this.sendKeyEvent({ ...options, action: 'keypress', key: 'home' }); - return this.sendKeyEvent({ - ...options, - action: 'keypress', - key: 'home' - }); } /** From f64ab5d1417046545dc2e2f939ce7b8a3f6ffba0 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 20 Mar 2024 10:24:14 -0400 Subject: [PATCH 62/93] Update src/RokuDeploy.ts Co-authored-by: Bronley Plumb --- src/RokuDeploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index aa32edd..6d8198a 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -970,7 +970,7 @@ export interface SendTextOptions extends SendKeyEventOptions { export interface CloseChannelOptions { host: string; - remotePort: number; + remotePort?: number; timeout?: number; } From 4ffc8f72d49b16d9236413931874467f8583bac4 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 20 Mar 2024 10:30:16 -0400 Subject: [PATCH 63/93] Add outFile to Zip, delete zipPackage --- src/RokuDeploy.spec.ts | 2 +- src/RokuDeploy.ts | 1 + src/cli.spec.ts | 7 ------- src/cli.ts | 15 ++++----------- src/commands/ZipPackageCommand.ts | 12 ------------ 5 files changed, 6 insertions(+), 31 deletions(-) delete mode 100644 src/commands/ZipPackageCommand.ts diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index c460ec5..0b31958 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -606,7 +606,7 @@ describe('index', () => { }); }); - describe('zipPackage', () => { + describe('zip', () => { it('should throw error when manifest is missing', async () => { let err; try { diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 6d8198a..f874550 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -983,6 +983,7 @@ export interface StageOptions { export interface ZipOptions { stagingDir?: string; outDir?: string; + outFile?: string; } export interface SideloadOptions { diff --git a/src/cli.spec.ts b/src/cli.spec.ts index 8c9ba59..c266068 100644 --- a/src/cli.spec.ts +++ b/src/cli.spec.ts @@ -59,13 +59,6 @@ describe('cli', () => { expectPathExists(`${stagingDir}/source/main.brs`); }); - it('Successfully uses zipPackage to create .zip', () => { - fsExtra.outputFileSync(`${stagingDir}/manifest`, ''); - - execSync(`node ${cwd}/dist/cli.js zipPackage --stagingDir ${stagingDir} --outDir ${outDir}`); - expectPathExists(`${outDir}/roku-deploy.zip`); - }); - it('Publish passes proper options', async () => { const stub = sinon.stub(rokuDeploy, 'sideload').callsFake(async () => { return Promise.resolve({ diff --git a/src/cli.ts b/src/cli.ts index e047847..dc78e02 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -3,7 +3,6 @@ import * as yargs from 'yargs'; import { ExecCommand } from './commands/ExecCommand'; import { SendTextCommand } from './commands/SendTextCommand'; import { StageCommand } from './commands/StageCommand'; -import { ZipPackageCommand } from './commands/ZipPackageCommand'; import { SideloadCommand } from './commands/SideloadCommand'; import { ConvertToSquashfsCommand } from './commands/ConvertToSquashfsCommand'; import { RekeyDeviceCommand } from './commands/RekeyDeviceCommand'; @@ -22,7 +21,8 @@ void yargs .command('bundle', 'execute build actions for bundling app', (builder) => { return builder .option('rootDir', { type: 'string', description: 'The selected root folder to be copied', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); + .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }) + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }); }, (args: any) => { return new ExecCommand( 'stage|zip', @@ -152,14 +152,6 @@ void yargs return new StageCommand().run(args); }) - .command(['zip', 'zipPackage'], 'Given an already-populated staging folder, create a zip archive of it and copy it to the output folder', (builder) => { - return builder - .option('stagingDir', { type: 'string', description: 'The selected staging folder', demandOption: false }) - .option('outDir', { type: 'string', description: 'The output directory', demandOption: false }); - }, (args: any) => { - return new ZipPackageCommand().run(args); - }) - .command('sideload', 'Sideload a pre-existing packaged zip file to a remote Roku', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) @@ -233,7 +225,8 @@ void yargs .command('zip', 'Given a path to a folder, zip up that folder and all of its contents', (builder) => { return builder .option('stagingDir', { type: 'string', description: 'The folder that should be zipped', demandOption: false }) - .option('outDir', { type: 'string', description: 'The path to the zip that will be created. Must be .zip file name', demandOption: false }); + .option('outDir', { type: 'string', description: 'The path to the zip that will be created. Must be .zip file name', demandOption: false }) + .option('outFile', { type: 'string', description: 'The output file', demandOption: false }); }, (args: any) => { console.log('args', args); return new ZipCommand().run(args); diff --git a/src/commands/ZipPackageCommand.ts b/src/commands/ZipPackageCommand.ts deleted file mode 100644 index b1463e7..0000000 --- a/src/commands/ZipPackageCommand.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { rokuDeploy } from '../index'; -import { util } from '../util'; - -export class ZipPackageCommand { - async run(args) { - const options = { - ...util.getOptionsFromJson(), - ...args - }; - await rokuDeploy.zip(options); - } -} From 94a4d43dd85bfeddb67caee70421bd44c7731994 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 20 Mar 2024 12:41:05 -0400 Subject: [PATCH 64/93] StagingDir is defaulted anyway so this error will never occur --- src/RokuDeploy.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index f874550..96f3f13 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -37,9 +37,6 @@ export class RokuDeploy { //make sure the staging folder exists await fsExtra.ensureDir(options.stagingDir); - if (!options.stagingDir) { - throw new Error('stagingPath is required'); - } if (!await fsExtra.pathExists(options.rootDir)) { throw new Error(`rootDir does not exist at "${options.rootDir}"`); } From 782ec2241256e47ea3f3e1c139853b0ae8fc794c Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 20 Mar 2024 12:42:19 -0400 Subject: [PATCH 65/93] Delete MissingRequiredOptionError --- src/Errors.ts | 7 ------- src/RokuDeploy.ts | 10 +++++----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Errors.ts b/src/Errors.ts index e87ba2b..bec353e 100644 --- a/src/Errors.ts +++ b/src/Errors.ts @@ -48,10 +48,3 @@ export class ConvertError extends Error { Object.setPrototypeOf(this, ConvertError.prototype); } } - -export class MissingRequiredOptionError extends Error { - constructor(message: string) { - super(message); - Object.setPrototypeOf(this, MissingRequiredOptionError.prototype); - } -} diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 96f3f13..68f239f 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -236,7 +236,7 @@ export class RokuDeploy { public async sideload(options: SideloadOptions): Promise<{ message: string; results: any }> { options = this.getOptions(options) as any; if (!options.host) { - throw new errors.MissingRequiredOptionError('must specify the host for the Roku device'); + throw new Error('must specify the host for the Roku device'); } //make sure the outDir exists await fsExtra.ensureDir(options.outDir); @@ -330,7 +330,7 @@ export class RokuDeploy { public async convertToSquashfs(options: ConvertToSquashfsOptions) { options = this.getOptions(options) as any; if (!options.host) { - throw new errors.MissingRequiredOptionError('must specify the host for the Roku device'); + throw new Error('must specify the host for the Roku device'); } let requestOptions = this.generateBaseRequestOptions('plugin_install', options as any, { archive: '', @@ -350,11 +350,11 @@ export class RokuDeploy { public async rekeyDevice(options: RekeyDeviceOptions) { options = this.getOptions(options) as any; if (!options.rekeySignedPackage) { - throw new errors.MissingRequiredOptionError('Must supply rekeySignedPackage'); + throw new Error('Must supply rekeySignedPackage'); } if (!options.signingPassword) { - throw new errors.MissingRequiredOptionError('Must supply signingPassword'); + throw new Error('Must supply signingPassword'); } let rekeySignedPackagePath = options.rekeySignedPackage; @@ -403,7 +403,7 @@ export class RokuDeploy { public async createSignedPackage(options: CreateSignedPackageOptions): Promise { options = this.getOptions(options) as any; if (!options.signingPassword) { - throw new errors.MissingRequiredOptionError('Must supply signingPassword'); + throw new Error('Must supply signingPassword'); } let manifestPath = path.join(options.stagingDir, 'manifest'); let parsedManifest = await this.parseManifest(manifestPath); From 895c250f7decaff128421805476862e4ccbc5791 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 20 Mar 2024 12:52:48 -0400 Subject: [PATCH 66/93] Add checkRequiredOptions function to test for required options --- src/RokuDeploy.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 68f239f..3199541 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -709,6 +709,14 @@ export class RokuDeploy { return options; } + public checkRequiredOptions(options: RokuDeployOptions, requiredOptions: string[]) { + for (let opt of requiredOptions) { + if (options[opt] === undefined) { + throw new Error('Missing required option: ' + opt); + } + } + } + /** * Centralizes getting output zip file path based on passed in options * @param options From 469a62a184d8bee0c9e62f4cc94c13e710984f20 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Wed, 20 Mar 2024 12:53:33 -0400 Subject: [PATCH 67/93] Add checking for required options in sendKeyEvent function, start testing --- src/RokuDeploy.spec.ts | 16 ++++++++++++++++ src/RokuDeploy.ts | 1 + 2 files changed, 17 insertions(+) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 0b31958..2735a14 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -16,6 +16,7 @@ import { cwd, expectPathExists, expectPathNotExists, expectThrowsAsync, outDir, import { createSandbox } from 'sinon'; import * as r from 'postman-request'; import type * as requestType from 'request'; +import type { SendKeyEventOptions } from './RokuDeploy'; const request = r as typeof requestType; const sinon = createSandbox(); @@ -3175,6 +3176,21 @@ describe('index', () => { }); }); + describe('checkRequiredOptions', () => { + async function testRequiredOptions(action: string, requiredOptions: Partial, testedOption: string) { + const newOptions = { ...requiredOptions }; + delete newOptions[testedOption]; + await expectThrowsAsync(async () => { + await rokuDeploy[action](newOptions); + }, `Missing required option: ${testedOption}`); + } + it.only('throws error when sendKeyEvent is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4', key: 'string' }; + await testRequiredOptions('sendKeyEvent', requiredOptions, 'host'); + await testRequiredOptions('sendKeyEvent', requiredOptions, 'key'); + }); + }); + describe('downloadFile', () => { it('waits for the write stream to finish writing before resolving', async () => { let downloadFileIsResolved = false; diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 3199541..e71f325 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -212,6 +212,7 @@ export class RokuDeploy { * This makes the roku return to the home screen */ private async sendKeyEvent(options: SendKeyEventOptions) { + this.checkRequiredOptions(options, ['host', 'key']); let filledOptions = this.getOptions(options); // press the home button to return to the main screen return this.doPostRequest({ From 76b1f7dc4e4438b3c788a542534f81e6f6a65e13 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Sat, 23 Mar 2024 13:19:01 -0400 Subject: [PATCH 68/93] Add check for if options are part of the defined interface that they are being called with --- src/RokuDeploy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index e71f325..58a7c8a 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -710,8 +710,8 @@ export class RokuDeploy { return options; } - public checkRequiredOptions(options: RokuDeployOptions, requiredOptions: string[]) { - for (let opt of requiredOptions) { + public checkRequiredOptions>(options: T, requiredOptions: Array) { + for (let opt of requiredOptions as string[]) { if (options[opt] === undefined) { throw new Error('Missing required option: ' + opt); } From 9e44992ca331f59d6088f042a1db148c64b71742 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Sat, 23 Mar 2024 13:19:44 -0400 Subject: [PATCH 69/93] Add check for various required options and add tests for each one --- src/RokuDeploy.spec.ts | 52 +++++++++++++++++++++++++++++++++++++++++- src/RokuDeploy.ts | 8 +++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 2735a14..53e8c11 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -16,7 +16,7 @@ import { cwd, expectPathExists, expectPathNotExists, expectThrowsAsync, outDir, import { createSandbox } from 'sinon'; import * as r from 'postman-request'; import type * as requestType from 'request'; -import type { SendKeyEventOptions } from './RokuDeploy'; +import type { CaptureScreenshotOptions, ConvertToSquashfsOptions, CreateSignedPackageOptions, DeleteDevChannelOptions, GetDevIdOptions, GetDeviceInfoOptions, RekeyDeviceOptions, SendKeyEventOptions, SideloadOptions } from './RokuDeploy'; const request = r as typeof requestType; const sinon = createSandbox(); @@ -3184,11 +3184,61 @@ describe('index', () => { await rokuDeploy[action](newOptions); }, `Missing required option: ${testedOption}`); } + it.only('throws error when sendKeyEvent is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', key: 'string' }; await testRequiredOptions('sendKeyEvent', requiredOptions, 'host'); await testRequiredOptions('sendKeyEvent', requiredOptions, 'key'); }); + + it.only('throws error when sideload is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; + await testRequiredOptions('sideload', requiredOptions, 'host'); + await testRequiredOptions('sideload', requiredOptions, 'password'); + }); + + it.only('throws error when convertToSquashfs is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; + await testRequiredOptions('convertToSquashfs', requiredOptions, 'host'); + await testRequiredOptions('convertToSquashfs', requiredOptions, 'password'); + }); + + it.only('throws error when rekeyDevice is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', rekeySignedPackage: 'abcd', signingPassword: 'abcd'}; + await testRequiredOptions('rekeyDevice', requiredOptions, 'host'); + await testRequiredOptions('rekeyDevice', requiredOptions, 'password'); + await testRequiredOptions('rekeyDevice', requiredOptions, 'rekeySignedPackage'); + await testRequiredOptions('rekeyDevice', requiredOptions, 'signingPassword'); + }); + + it.only('throws error when createSignedPackage is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', signingPassword: 'abcd'}; + await testRequiredOptions('createSignedPackage', requiredOptions, 'host'); + await testRequiredOptions('createSignedPackage', requiredOptions, 'password'); + await testRequiredOptions('createSignedPackage', requiredOptions, 'signingPassword'); + }); + + it.only('throws error when deleteDevChannel is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; + await testRequiredOptions('deleteDevChannel', requiredOptions, 'host'); + await testRequiredOptions('deleteDevChannel', requiredOptions, 'password'); + }); + + it.only('throws error when captureScreenshot is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; + await testRequiredOptions('captureScreenshot', requiredOptions, 'host'); + await testRequiredOptions('captureScreenshot', requiredOptions, 'password'); + }); + + it.only('throws error when getDeviceInfo is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4' }; + await testRequiredOptions('getDeviceInfo', requiredOptions, 'host'); + }); + + it.only('throws error when getDevId is missing required options', async () => { + const requiredOptions: Partial = { host: '1.2.3.4' }; + await testRequiredOptions('getDevId', requiredOptions, 'host'); + }); }); describe('downloadFile', () => { diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 58a7c8a..343820c 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -235,6 +235,7 @@ export class RokuDeploy { * @param options */ public async sideload(options: SideloadOptions): Promise<{ message: string; results: any }> { + this.checkRequiredOptions(options, ['host', 'password']); options = this.getOptions(options) as any; if (!options.host) { throw new Error('must specify the host for the Roku device'); @@ -329,6 +330,7 @@ export class RokuDeploy { * @param options */ public async convertToSquashfs(options: ConvertToSquashfsOptions) { + this.checkRequiredOptions(options, ['host', 'password']); options = this.getOptions(options) as any; if (!options.host) { throw new Error('must specify the host for the Roku device'); @@ -349,6 +351,7 @@ export class RokuDeploy { * @param options */ public async rekeyDevice(options: RekeyDeviceOptions) { + this.checkRequiredOptions(options, ['host', 'password', 'rekeySignedPackage', 'signingPassword']); options = this.getOptions(options) as any; if (!options.rekeySignedPackage) { throw new Error('Must supply rekeySignedPackage'); @@ -402,6 +405,7 @@ export class RokuDeploy { * @param options */ public async createSignedPackage(options: CreateSignedPackageOptions): Promise { + this.checkRequiredOptions(options, ['host', 'password', 'signingPassword']); options = this.getOptions(options) as any; if (!options.signingPassword) { throw new Error('Must supply signingPassword'); @@ -591,6 +595,7 @@ export class RokuDeploy { * @param options */ public async deleteDevChannel(options?: DeleteDevChannelOptions) { + this.checkRequiredOptions(options, ['host', 'password']); options = this.getOptions(options) as any; let deleteOptions = this.generateBaseRequestOptions('plugin_install', options as any); @@ -605,6 +610,7 @@ export class RokuDeploy { * Gets a screenshot from the device. A side-loaded channel must be running or an error will be thrown. */ public async captureScreenshot(options: CaptureScreenshotOptions) { + this.checkRequiredOptions(options, ['host', 'password']); options = this.getOptions(options); options.screenshotFile = options.screenshotFile ?? `screenshot-${dayjs().format('YYYY-MM-DD-HH.mm.ss.SSS')}`; let saveFilePath: string; @@ -762,6 +768,7 @@ export class RokuDeploy { public async getDeviceInfo(options?: { enhance: true } & GetDeviceInfoOptions): Promise; public async getDeviceInfo(options?: GetDeviceInfoOptions): Promise public async getDeviceInfo(options: GetDeviceInfoOptions) { + this.checkRequiredOptions(options, ['host']); options = this.getOptions(options) as any; //if the host is a DNS name, look up the IP address @@ -828,6 +835,7 @@ export class RokuDeploy { * @returns */ public async getDevId(options?: GetDevIdOptions) { + this.checkRequiredOptions(options, ['host']); const deviceInfo = await this.getDeviceInfo(options); return deviceInfo['keyed-developer-id']; } From db3d782b5fa028eaac7fa403817cc6767dde9189 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Sat, 23 Mar 2024 13:27:47 -0400 Subject: [PATCH 70/93] take out it.only in tests --- src/RokuDeploy.spec.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 53e8c11..bb284e3 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3185,25 +3185,25 @@ describe('index', () => { }, `Missing required option: ${testedOption}`); } - it.only('throws error when sendKeyEvent is missing required options', async () => { + it('throws error when sendKeyEvent is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', key: 'string' }; await testRequiredOptions('sendKeyEvent', requiredOptions, 'host'); await testRequiredOptions('sendKeyEvent', requiredOptions, 'key'); }); - it.only('throws error when sideload is missing required options', async () => { + it('throws error when sideload is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; await testRequiredOptions('sideload', requiredOptions, 'host'); await testRequiredOptions('sideload', requiredOptions, 'password'); }); - it.only('throws error when convertToSquashfs is missing required options', async () => { + it('throws error when convertToSquashfs is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; await testRequiredOptions('convertToSquashfs', requiredOptions, 'host'); await testRequiredOptions('convertToSquashfs', requiredOptions, 'password'); }); - it.only('throws error when rekeyDevice is missing required options', async () => { + it('throws error when rekeyDevice is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', rekeySignedPackage: 'abcd', signingPassword: 'abcd'}; await testRequiredOptions('rekeyDevice', requiredOptions, 'host'); await testRequiredOptions('rekeyDevice', requiredOptions, 'password'); @@ -3211,31 +3211,31 @@ describe('index', () => { await testRequiredOptions('rekeyDevice', requiredOptions, 'signingPassword'); }); - it.only('throws error when createSignedPackage is missing required options', async () => { + it('throws error when createSignedPackage is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', signingPassword: 'abcd'}; await testRequiredOptions('createSignedPackage', requiredOptions, 'host'); await testRequiredOptions('createSignedPackage', requiredOptions, 'password'); await testRequiredOptions('createSignedPackage', requiredOptions, 'signingPassword'); }); - it.only('throws error when deleteDevChannel is missing required options', async () => { + it('throws error when deleteDevChannel is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; await testRequiredOptions('deleteDevChannel', requiredOptions, 'host'); await testRequiredOptions('deleteDevChannel', requiredOptions, 'password'); }); - it.only('throws error when captureScreenshot is missing required options', async () => { + it('throws error when captureScreenshot is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd' }; await testRequiredOptions('captureScreenshot', requiredOptions, 'host'); await testRequiredOptions('captureScreenshot', requiredOptions, 'password'); }); - it.only('throws error when getDeviceInfo is missing required options', async () => { + it('throws error when getDeviceInfo is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4' }; await testRequiredOptions('getDeviceInfo', requiredOptions, 'host'); }); - it.only('throws error when getDevId is missing required options', async () => { + it('throws error when getDevId is missing required options', async () => { const requiredOptions: Partial = { host: '1.2.3.4' }; await testRequiredOptions('getDevId', requiredOptions, 'host'); }); From e11ae26ac8030d4eaf111d03484b84a93f455117 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Sat, 23 Mar 2024 13:28:02 -0400 Subject: [PATCH 71/93] Delete old MissingRequiredOptionError tests --- src/RokuDeploy.spec.ts | 49 ------------------------------------------ 1 file changed, 49 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index bb284e3..cecf4bd 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -1059,21 +1059,6 @@ describe('index', () => { }); }); - it('should return MissingRequiredOptionError if host was not provided', async () => { - mockDoPostRequest(); - try { - options.host = undefined; - await rokuDeploy.convertToSquashfs({ - host: options.host, - password: 'password' - }); - } catch (e) { - expect(e).to.be.instanceof(errors.MissingRequiredOptionError); - return; - } - assert.fail('Should not have succeeded'); - }); - it('should return ConvertError if converting failed', async () => { mockDoPostRequest(); try { @@ -1182,40 +1167,6 @@ describe('index', () => { }); }); - it('should throw error if missing rekeySignedPackage option', async () => { - try { - await rokuDeploy.rekeyDevice({ - host: '1.2.3.4', - password: 'password', - rekeySignedPackage: null, - signingPassword: options.signingPassword, - rootDir: options.rootDir, - devId: options.devId - }); - } catch (e) { - expect(e).to.be.instanceof(errors.MissingRequiredOptionError); - return; - } - assert.fail('Exception should have been thrown'); - }); - - it('should throw error if missing signingPassword option', async () => { - try { - await rokuDeploy.rekeyDevice({ - host: '1.2.3.4', - password: 'password', - rekeySignedPackage: options.rekeySignedPackage, - signingPassword: null, - rootDir: options.rootDir, - devId: options.devId - }); - } catch (e) { - expect(e).to.be.instanceof(errors.MissingRequiredOptionError); - return; - } - assert.fail('Exception should have been thrown'); - }); - it('should throw error if response is not parsable', async () => { try { mockDoPostRequest(); From b298acb6371ca9c35c5aa41493fe0422b7d9156b Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Sat, 23 Mar 2024 13:44:30 -0400 Subject: [PATCH 72/93] fix tests --- src/RokuDeploy.spec.ts | 39 ++++++++++++++------------------------- src/RokuDeploy.ts | 2 +- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index cecf4bd..5b36730 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -647,11 +647,11 @@ describe('index', () => { describe('generateBaseRequestOptions', () => { it('uses default port', () => { - expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', password: options.password }).url).to.equal('http://1.2.3.4:80/a_b_c'); + expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', password: 'password' }).url).to.equal('http://1.2.3.4:80/a_b_c'); }); it('uses overridden port', () => { - expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', packagePort: 999, password: options.password }).url).to.equal('http://1.2.3.4:999/a_b_c'); + expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', packagePort: 999, password: 'password' }).url).to.equal('http://1.2.3.4:999/a_b_c'); }); }); @@ -1255,17 +1255,6 @@ describe('index', () => { }); }); - it('should return our error if signingPassword is not supplied', async () => { - await expectThrowsAsync(async () => { - await rokuDeploy.createSignedPackage({ - host: '1.2.3.4', - password: 'password', - signingPassword: undefined, - stagingDir: stagingDir - }); - }, 'Must supply signingPassword'); - }); - it('should return an error if there is a problem with the network request', async () => { let error = new Error('Network Error'); try { @@ -1353,7 +1342,7 @@ describe('index', () => { ); }); - it('should return our fallback error if neither error or package link was detected', async () => { + it('should return error if dev id does not match', async () => { mockDoGetRequest(` 789 @@ -2051,19 +2040,19 @@ describe('index', () => { `); mockDoPostRequest(body); - await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' })); }); it('throws when there is no response body', async () => { // missing body mockDoPostRequest(null); - await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' })); }); it('throws when there is an empty response body', async () => { // empty body mockDoPostRequest(); - await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' })); }); it('throws when there is an error downloading the image from device', async () => { @@ -2084,7 +2073,7 @@ describe('index', () => { }; mockDoPostRequest(body); - await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password })); + await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' })); }); it('handles the device returning a png', async () => { @@ -2105,7 +2094,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password' }); expect(result).not.to.be.undefined; expect(path.extname(result)).to.equal('.png'); expect(fsExtra.existsSync(result)); @@ -2129,7 +2118,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password' }); expect(result).not.to.be.undefined; expect(path.extname(result)).to.equal('.jpg'); expect(fsExtra.existsSync(result)); @@ -2153,7 +2142,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: `${tempDir}/myScreenShots` }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotDir: `${tempDir}/myScreenShots` }); expect(result).not.to.be.undefined; expect(util.standardizePath(`${tempDir}/myScreenShots`)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(result)); @@ -2177,7 +2166,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: tempDir, screenshotFile: 'my' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotDir: tempDir, screenshotFile: 'my' }); expect(result).not.to.be.undefined; expect(util.standardizePath(tempDir)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(path.join(tempDir, 'my.png'))); @@ -2201,7 +2190,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: tempDir, screenshotFile: 'my.jpg' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotDir: tempDir, screenshotFile: 'my.jpg' }); expect(result).not.to.be.undefined; expect(util.standardizePath(tempDir)).to.equal(path.dirname(result)); expect(fsExtra.existsSync(path.join(tempDir, 'my.jpg.png'))); @@ -2225,7 +2214,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password' }); expect(result).not.to.be.undefined; expect(fsExtra.existsSync(result)); }); @@ -2248,7 +2237,7 @@ describe('index', () => { }; mockDoPostRequest(body); - let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotFile: 'myFile' }); + let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotFile: 'myFile' }); expect(result).not.to.be.undefined; expect(path.basename(result)).to.equal('myFile.jpg'); expect(fsExtra.existsSync(result)); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 343820c..cc0f7b0 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -416,7 +416,7 @@ export class RokuDeploy { //prevent devId mismatch (if devId is specified) if (options.devId) { - const deviceDevId = await this.getDevId(); + const deviceDevId = await this.getDevId(options); if (options.devId !== deviceDevId) { throw new Error(`Package signing cancelled: provided devId '${options.devId}' does not match on-device devId '${deviceDevId}'`); } From d9397d5d52f8cfebc292d522d0d29c8908d8fc2c Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Sat, 23 Mar 2024 13:47:10 -0400 Subject: [PATCH 73/93] Fix lint error --- src/RokuDeploy.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 5b36730..fc26829 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3144,7 +3144,7 @@ describe('index', () => { }); it('throws error when rekeyDevice is missing required options', async () => { - const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', rekeySignedPackage: 'abcd', signingPassword: 'abcd'}; + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', rekeySignedPackage: 'abcd', signingPassword: 'abcd' }; await testRequiredOptions('rekeyDevice', requiredOptions, 'host'); await testRequiredOptions('rekeyDevice', requiredOptions, 'password'); await testRequiredOptions('rekeyDevice', requiredOptions, 'rekeySignedPackage'); @@ -3152,7 +3152,7 @@ describe('index', () => { }); it('throws error when createSignedPackage is missing required options', async () => { - const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', signingPassword: 'abcd'}; + const requiredOptions: Partial = { host: '1.2.3.4', password: 'abcd', signingPassword: 'abcd' }; await testRequiredOptions('createSignedPackage', requiredOptions, 'host'); await testRequiredOptions('createSignedPackage', requiredOptions, 'password'); await testRequiredOptions('createSignedPackage', requiredOptions, 'signingPassword'); From 9dd053d3c1768fc44b64bd8f01500c9caf8e7ba5 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 25 Mar 2024 18:27:28 -0400 Subject: [PATCH 74/93] Upgrade as many packages as possible, delete chalk stub --- package-lock.json | 1768 +++++++++++++++++++++++++++++++------------- package.json | 14 +- src/Logger.spec.ts | 3 - 3 files changed, 1278 insertions(+), 507 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3695c96..9e0c255 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,15 +47,24 @@ "chai": "^4.3.4", "coveralls-next": "^4.2.0", "dedent": "^0.7.0", - "eslint": "8.0.1", - "mocha": "^9.1.3", + "eslint": "^8.57.0", + "mocha": "^10.3.0", "nyc": "^15.1.0", "q": "^1.5.1", - "rimraf": "^2.6.2", - "sinon": "^11.1.2", - "source-map-support": "^0.5.13", - "ts-node": "^10.3.1", - "typescript": "^4.4.4" + "rimraf": "^5.0.5", + "sinon": "^17.0.1", + "source-map-support": "^0.5.21", + "ts-node": "^10.9.2", + "typescript": "^5.4.3" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/@babel/code-frame": { @@ -405,76 +414,221 @@ "node": ">=6.9.0" } }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, "engines": { - "node": ">= 12" + "node": ">=12" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz", - "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.0.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.6.0", + "globals": "^13.19.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" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { - "node": ">= 4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -561,6 +715,31 @@ "node": ">=8" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -593,6 +772,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@postman/form-data": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", @@ -658,20 +847,29 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.6.0", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", "type-detect": "^4.0.8" } }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, "node_modules/@tsconfig/node10": { @@ -978,16 +1176,16 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, "node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1328,17 +1526,18 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "node_modules/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -1358,10 +1557,13 @@ } }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } @@ -1573,9 +1775,9 @@ "integrity": "sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug==" }, "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -1605,15 +1807,15 @@ "dev": true }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/deep-is": { @@ -1675,6 +1877,12 @@ "node": ">=6.0.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1695,18 +1903,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -1730,49 +1926,49 @@ } }, "node_modules/eslint": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.0.1.tgz", - "integrity": "sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.0.3", - "@humanwhocodes/config-array": "^0.6.0", - "ajv": "^6.10.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "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": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "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.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -1825,12 +2021,15 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", - "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/ansi-styles": { @@ -1901,9 +2100,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", - "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -1911,12 +2110,15 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -1931,15 +2133,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1965,17 +2158,20 @@ } }, "node_modules/espree": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", - "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.5.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.0.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -1992,9 +2188,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -2004,9 +2200,9 @@ } }, "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" @@ -2103,7 +2299,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fastq": { @@ -2325,9 +2521,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -2383,9 +2579,9 @@ } }, "node_modules/globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2422,14 +2618,11 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/har-schema": { "version": "2.0.0", @@ -2501,9 +2694,9 @@ "dev": true }, "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -2610,6 +2803,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2813,6 +3015,24 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2907,9 +3127,9 @@ } }, "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, "node_modules/lcov-parse": { @@ -2971,7 +3191,7 @@ "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "node_modules/lodash.merge": { @@ -3075,6 +3295,15 @@ "node": ">=8" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3177,47 +3406,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", "dev": true, "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", + "glob": "8.1.0", "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", "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" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "node": ">= 14.0.0" } }, "node_modules/mocha/node_modules/argparse": { @@ -3226,6 +3456,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/mocha/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -3249,6 +3488,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3271,12 +3529,12 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" @@ -3335,18 +3593,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3354,16 +3600,34 @@ "dev": true }, "node_modules/nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^7.0.4", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, + "node_modules/nise/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" } }, "node_modules/node-preload": { @@ -3627,17 +3891,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -3761,19 +4025,35 @@ "node": ">=8" } }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "isarray": "0.0.1" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-to-regexp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", "dev": true }, "node_modules/path-type": { @@ -3973,15 +4253,6 @@ "node": ">=8" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -4134,15 +4405,95 @@ } }, "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/run-parallel": { @@ -4248,16 +4599,16 @@ "dev": true }, "node_modules/sinon": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", - "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, "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", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", "supports-color": "^7.2.0" }, "funding": { @@ -4265,6 +4616,33 @@ "url": "https://opencollective.com/sinon" } }, + "node_modules/sinon/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/sinon/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4305,9 +4683,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -4414,6 +4792,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4425,6 +4818,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -4506,12 +4912,12 @@ } }, "node_modules/ts-node": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.1.tgz", - "integrity": "sha512-Yw3W2mYzhHfCHOICGNJqa0i+rbL0rAyg7ZIHxU+K4pgY8gd2Lh1j+XbHCusJMykbj6RZMJVOY0MlHVd+GOivcw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -4522,11 +4928,13 @@ "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" }, "bin": { "ts-node": "dist/bin.js", "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" @@ -4624,16 +5032,16 @@ } }, "node_modules/typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/universalify": { @@ -4676,10 +5084,10 @@ "uuid": "bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "node_modules/verror": { @@ -4721,19 +5129,10 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "node_modules/word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "node_modules/wrap-ansi": { @@ -4752,6 +5151,57 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4939,6 +5389,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@babel/code-frame": { "version": "7.15.8", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", @@ -5204,63 +5660,158 @@ "to-fast-properties": "^2.0.0" } }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "requires": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" } }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz", - "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.0.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.6.0", + "globals": "^13.19.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" }, "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, + "@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true + }, "@humanwhocodes/config-array": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz", - "integrity": "sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" } }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -5325,6 +5876,28 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -5348,6 +5921,13 @@ "fastq": "^1.6.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@postman/form-data": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", @@ -5403,20 +5983,31 @@ } }, "@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, "requires": { - "@sinonjs/commons": "^1.6.0", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", "type-detect": "^4.0.8" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } } }, "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, "@tsconfig/node10": { @@ -5649,24 +6240,23 @@ "eslint-visitor-keys": "^3.0.0" } }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "8.2.0", @@ -5911,17 +6501,18 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "requires": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" } }, "chalk": { @@ -5935,10 +6526,13 @@ } }, "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "requires": { + "get-func-name": "^2.0.2" + } }, "chokidar": { "version": "3.5.3", @@ -6107,9 +6701,9 @@ "integrity": "sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug==" }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -6128,9 +6722,9 @@ "dev": true }, "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -6180,6 +6774,12 @@ "esutils": "^2.0.2" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -6200,15 +6800,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -6226,49 +6817,49 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.0.1.tgz", - "integrity": "sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.0.3", - "@humanwhocodes/config-array": "^0.6.0", - "ajv": "^6.10.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^6.0.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "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": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "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.2.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "dependencies": { "ansi-styles": { @@ -6318,9 +6909,9 @@ "dev": true }, "eslint-scope": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-6.0.0.tgz", - "integrity": "sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -6328,9 +6919,9 @@ } }, "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "has-flag": { @@ -6339,12 +6930,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -6393,20 +6978,20 @@ } }, "eslint-visitor-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz", - "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.0.0.tgz", - "integrity": "sha512-r5EQJcYZ2oaGbeR0jR0fFVijGOcwai07/690YRXLINuhmVeRY4UKSAsQPe/0BNuDgwP7Ophoc1PRsr2E3tkbdQ==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.5.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.0.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -6416,18 +7001,18 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -6506,7 +7091,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { @@ -6661,9 +7246,9 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-package-type": { @@ -6704,9 +7289,9 @@ } }, "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -6731,10 +7316,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "har-schema": { @@ -6787,9 +7372,9 @@ "dev": true }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "immediate": { @@ -6866,6 +7451,12 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -7023,6 +7614,16 @@ "istanbul-lib-report": "^3.0.0" } }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -7102,9 +7703,9 @@ } }, "just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, "lcov-parse": { @@ -7154,7 +7755,7 @@ "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "lodash.merge": { @@ -7230,6 +7831,15 @@ } } }, + "loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "requires": { + "get-func-name": "^2.0.1" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7304,33 +7914,35 @@ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true + }, "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", "dev": true, "requires": { - "@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", + "glob": "8.1.0", "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", "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" @@ -7342,6 +7954,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -7359,6 +7980,19 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7375,12 +8009,12 @@ } }, "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "ms": { @@ -7426,12 +8060,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7439,16 +8067,36 @@ "dev": true }, "nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^7.0.4", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + } + } } }, "node-preload": { @@ -7657,17 +8305,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "p-limit": { @@ -7752,23 +8400,30 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "requires": { - "isarray": "0.0.1" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", "dev": true } } }, + "path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "dev": true + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -7922,12 +8577,6 @@ "fromentries": "^1.2.0" } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -8034,12 +8683,61 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "requires": { - "glob": "^7.1.3" + "glob": "^10.3.7" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } } }, "run-parallel": { @@ -8116,19 +8814,43 @@ "dev": true }, "sinon": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", - "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^7.1.2", - "@sinonjs/samsam": "^6.0.2", - "diff": "^5.0.0", - "nise": "^5.1.0", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", "supports-color": "^7.2.0" }, "dependencies": { + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + } + }, + "diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -8159,9 +8881,9 @@ "dev": true }, "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -8249,6 +8971,17 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -8257,6 +8990,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -8314,12 +9056,12 @@ } }, "ts-node": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.1.tgz", - "integrity": "sha512-Yw3W2mYzhHfCHOICGNJqa0i+rbL0rAyg7ZIHxU+K4pgY8gd2Lh1j+XbHCusJMykbj6RZMJVOY0MlHVd+GOivcw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "requires": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -8330,6 +9072,7 @@ "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" }, "dependencies": { @@ -8392,9 +9135,9 @@ } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true }, "universalify": { @@ -8430,10 +9173,10 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "verror": { @@ -8468,16 +9211,10 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", - "dev": true - }, "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { @@ -8513,6 +9250,43 @@ } } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 5372773..d89d7fd 100644 --- a/package.json +++ b/package.json @@ -52,15 +52,15 @@ "chai": "^4.3.4", "coveralls-next": "^4.2.0", "dedent": "^0.7.0", - "eslint": "8.0.1", - "mocha": "^9.1.3", + "eslint": "^8.57.0", + "mocha": "^10.3.0", "nyc": "^15.1.0", "q": "^1.5.1", - "rimraf": "^2.6.2", - "sinon": "^11.1.2", - "source-map-support": "^0.5.13", - "ts-node": "^10.3.1", - "typescript": "^4.4.4" + "rimraf": "^5.0.5", + "sinon": "^17.0.1", + "source-map-support": "^0.5.21", + "ts-node": "^10.9.2", + "typescript": "^5.4.3" }, "mocha": { "require": [ diff --git a/src/Logger.spec.ts b/src/Logger.spec.ts index e34a7ee..8aff42e 100644 --- a/src/Logger.spec.ts +++ b/src/Logger.spec.ts @@ -1,6 +1,5 @@ import { expect } from 'chai'; import { Logger, LogLevel, noop } from './Logger'; -import chalk from 'chalk'; import { createSandbox } from 'sinon'; const sinon = createSandbox(); @@ -10,8 +9,6 @@ describe('Logger', () => { beforeEach(() => { logger = new Logger(LogLevel.trace); sinon.restore(); - //disable chalk colors for testing - sinon.stub(chalk, 'grey').callsFake((arg) => arg as any); }); it('noop does nothing', () => { From 0bf6dd3309aea6a5865afea2e68ff3462ac8e8fa Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 14:45:29 -0400 Subject: [PATCH 75/93] Bring back chalk by downgrading sinon to v12 --- package.json | 2 +- src/Logger.spec.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d89d7fd..dabe4e7 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "nyc": "^15.1.0", "q": "^1.5.1", "rimraf": "^5.0.5", - "sinon": "^17.0.1", + "sinon": "^12.0.0", "source-map-support": "^0.5.21", "ts-node": "^10.9.2", "typescript": "^5.4.3" diff --git a/src/Logger.spec.ts b/src/Logger.spec.ts index 8aff42e..e34a7ee 100644 --- a/src/Logger.spec.ts +++ b/src/Logger.spec.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { Logger, LogLevel, noop } from './Logger'; +import chalk from 'chalk'; import { createSandbox } from 'sinon'; const sinon = createSandbox(); @@ -9,6 +10,8 @@ describe('Logger', () => { beforeEach(() => { logger = new Logger(LogLevel.trace); sinon.restore(); + //disable chalk colors for testing + sinon.stub(chalk, 'grey').callsFake((arg) => arg as any); }); it('noop does nothing', () => { From ef8a3ec23800ee8492a12efad3be5a72e1d89196 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 14:46:13 -0400 Subject: [PATCH 76/93] New package-lock --- package-lock.json | 5480 +-------------------------------------------- 1 file changed, 41 insertions(+), 5439 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e0c255..83e5f92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5393 +1,8 @@ { "name": "roku-deploy", "version": "3.11.1", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "roku-deploy", - "version": "3.11.1", - "license": "MIT", - "dependencies": { - "chalk": "^2.4.2", - "dateformat": "^3.0.3", - "dayjs": "^1.11.0", - "fast-glob": "^3.2.12", - "fs-extra": "^7.0.1", - "is-glob": "^4.0.3", - "jsonc-parser": "^2.3.0", - "jszip": "^3.6.0", - "lodash": "^4.17.21", - "micromatch": "^4.0.4", - "moment": "^2.29.1", - "parse-ms": "^2.1.0", - "postman-request": "^2.88.1-postman.32", - "temp-dir": "^2.0.0", - "xml2js": "^0.5.0", - "yargs": "^17.7.2" - }, - "bin": { - "roku-deploy": "dist/cli.js" - }, - "devDependencies": { - "@types/chai": "^4.2.22", - "@types/fs-extra": "^5.0.1", - "@types/is-glob": "^4.0.2", - "@types/lodash": "^4.14.200", - "@types/micromatch": "^4.0.2", - "@types/mocha": "^9.0.0", - "@types/node": "^16.11.3", - "@types/q": "^1.5.8", - "@types/request": "^2.47.0", - "@types/sinon": "^10.0.4", - "@types/xml2js": "^0.4.5", - "@types/yargs": "^17.0.32", - "@typescript-eslint/eslint-plugin": "5.1.0", - "@typescript-eslint/parser": "5.1.0", - "chai": "^4.3.4", - "coveralls-next": "^4.2.0", - "dedent": "^0.7.0", - "eslint": "^8.57.0", - "mocha": "^10.3.0", - "nyc": "^15.1.0", - "q": "^1.5.1", - "rimraf": "^5.0.5", - "sinon": "^17.0.1", - "source-map-support": "^0.5.21", - "ts-node": "^10.9.2", - "typescript": "^5.4.3" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", - "dev": true, - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@postman/form-data": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", - "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@postman/tough-cookie": { - "version": "4.1.2-postman.2", - "resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.2-postman.2.tgz", - "integrity": "sha512-nrBdX3jA5HzlxTrGI/I0g6pmUKic7xbGA4fAMLFgmJCA3DL2Ma+3MvmD+Sdiw9gLEzZJIF4fz33sT8raV/L/PQ==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@postman/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/@postman/tunnel-agent": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz", - "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "node_modules/@types/braces": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.1.tgz", - "integrity": "sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==", - "dev": true - }, - "node_modules/@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", - "dev": true - }, - "node_modules/@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "dev": true - }, - "node_modules/@types/fs-extra": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.1.0.tgz", - "integrity": "sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/is-glob": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/is-glob/-/is-glob-4.0.2.tgz", - "integrity": "sha512-4j5G9Y5jljDSICQ1R2f/Rcyoj6DZmYGneny+p/cDkjep0rkqNg0W73Ty0bVjMUTZgLXHf8oiMjg1XC3CDwCz+g==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.14.200", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", - "integrity": "sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==", - "dev": true - }, - "node_modules/@types/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==", - "dev": true, - "dependencies": { - "@types/braces": "*" - } - }, - "node_modules/@types/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "16.11.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.3.tgz", - "integrity": "sha512-aIYL9Eemcecs1y77XzFGiSc+FdfN58k4J23UEe6+hynf4Wd9g4DzQPwIKL080vSMuubFqy2hWwOzCtJdc6vFKw==", - "dev": true - }, - "node_modules/@types/q": { - "version": "1.5.8", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", - "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==", - "dev": true - }, - "node_modules/@types/request": { - "version": "2.48.7", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.7.tgz", - "integrity": "sha512-GWP9AZW7foLd4YQxyFZDBepl0lPsWLMEXDZUjQ/c1gqVPDPECrRZyEzuhJdnPWioFCq3Tv0qoGpMD6U+ygd4ZA==", - "dev": true, - "dependencies": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "node_modules/@types/sinon": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.4.tgz", - "integrity": "sha512-fOYjrxQv8zJsqOY6V6ecP4eZhQBxtY80X0er1VVnUIAIZo74jHm8e1vguG5Yt4Iv8W2Wr7TgibB8MfRe32k9pA==", - "dev": true, - "dependencies": { - "@sinonjs/fake-timers": "^7.1.0" - } - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", - "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==", - "dev": true - }, - "node_modules/@types/xml2js": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.9.tgz", - "integrity": "sha512-CHiCKIihl1pychwR2RNX5mAYmJDACgFVCMT5OArMaO3erzwXVcBqPcusr+Vl8yeeXukxZqtF8mZioqX+mpjjdw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz", - "integrity": "sha512-bekODL3Tqf36Yz8u+ilha4zGxL9mdB6LIsIoMAvvC5FAuWo4NpZYXtCbv7B2CeR1LhI/lLtLk+q4tbtxuoVuCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "5.1.0", - "@typescript-eslint/scope-manager": "5.1.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.1.0.tgz", - "integrity": "sha512-ovE9qUiZMOMgxQAESZsdBT+EXIfx/YUYAbwGUI6V03amFdOOxI9c6kitkgRvLkJaLusgMZ2xBhss+tQ0Y1HWxA==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.1.0.tgz", - "integrity": "sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "debug": "^4.3.2" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz", - "integrity": "sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.1.0.tgz", - "integrity": "sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz", - "integrity": "sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz", - "integrity": "sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.1.0", - "eslint-visitor-keys": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brotli": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", - "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", - "dependencies": { - "base64-js": "^1.1.2" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", - "dev": true, - "dependencies": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001271", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001271.tgz", - "integrity": "sha512-BBruZFWmt3HFdVPS8kceTBIguKxu4f99n5JNp06OlPD/luoAMIaIK5ieV5YjnBLH3Nysai9sxj9rpJj4ZisXOA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "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" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/coveralls-next": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/coveralls-next/-/coveralls-next-4.2.0.tgz", - "integrity": "sha512-zg41a/4QDSASPtlV6gp+6owoU43U5CguxuPZR3nPZ26M5ZYdEK3MdUe7HwE+AnCZPkucudfhqqJZehCNkz2rYg==", - "dev": true, - "dependencies": { - "form-data": "4.0.0", - "js-yaml": "4.1.0", - "lcov-parse": "1.0.0", - "log-driver": "1.2.7", - "minimist": "1.2.7" - }, - "bin": { - "coveralls": "bin/coveralls.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/coveralls-next/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/coveralls-next/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/coveralls-next/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "engines": { - "node": "*" - } - }, - "node_modules/dayjs": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.0.tgz", - "integrity": "sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.3.877", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.877.tgz", - "integrity": "sha512-fT5mW5Giw5iyVukeHb2XvB4joBKvzHtl8Vs3QzE7APATpFMt/T7RWyUcIKSZzYkKQgpMbu+vDBTCHfQZvh8klA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", - "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==" - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jszip": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.8.0.tgz", - "integrity": "sha512-cnpQrXvFSLdsR9KR5/x7zdf6c3m8IhZfZzSblFEHSqBaVwD2nvJ4CuCKLyvKvwBgZm08CgfSoiTBQLm5WW9hGw==", - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - } - }, - "node_modules/just-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true - }, - "node_modules/lcov-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", - "dev": true, - "bin": { - "lcov-parse": "bin/cli.js" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true, - "engines": { - "node": ">=0.8.6" - } - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mocha": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", - "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/nise": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", - "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "node_modules/nise/node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "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" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/nyc/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postman-request": { - "version": "2.88.1-postman.32", - "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.32.tgz", - "integrity": "sha512-Zf5D0b2G/UmnmjRwQKhYy4TBkuahwD0AMNyWwFK3atxU1u5GS38gdd7aw3vyR6E7Ii+gD//hREpflj2dmpbE7w==", - "dependencies": { - "@postman/form-data": "~3.1.1", - "@postman/tough-cookie": "~4.1.2-postman.1", - "@postman/tunnel-agent": "^0.6.3", - "aws-sign2": "~0.7.0", - "aws4": "^1.12.0", - "brotli": "^1.3.3", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "har-validator": "~5.1.3", - "http-signature": "~1.3.1", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "^2.1.35", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.3", - "safe-buffer": "^5.1.2", - "stream-length": "^1.0.2", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postman-request/node_modules/http-signature": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", - "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.14.1" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/postman-request/node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "node_modules/postman-request/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "node_modules/sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "node_modules/sinon/node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/sinon/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/sinon/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/sinon/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/spawn-wrap/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "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" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-length/-/stream-length-1.0.2.tgz", - "integrity": "sha512-aI+qKFiwoDV4rsXiS7WRoCt+v2RX1nUj17+KJC5r2gfh5xoSJIfP6Y3Do/HtvesFcTSWthIuJ3l1cvKQY/+nZg==", - "dependencies": { - "bluebird": "^2.6.2" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "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" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, "dependencies": { "@aashutoshrathi/word-wrap": { "version": "1.2.6", @@ -5606,6 +221,19 @@ "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } } }, "@babel/parser": { @@ -5983,25 +611,14 @@ } }, "@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.3.tgz", + "integrity": "sha512-nhOb2dWPeb1sd3IQXL/dVPnKHDOAFfvichtBf4xV00/rU1QbPCQqKMbvIheIjqwVjh7qIgf2AHTHi391yMOMpQ==", "dev": true, "requires": { - "@sinonjs/commons": "^2.0.0", + "@sinonjs/commons": "^1.6.0", "lodash.get": "^4.4.2", "type-detect": "^4.0.8" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } } }, "@sinonjs/text-encoding": { @@ -6588,7 +1205,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "combined-stream": { "version": "1.0.8", @@ -6814,7 +1431,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { "version": "8.57.0", @@ -7339,7 +1956,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "hasha": { "version": "5.2.2", @@ -8814,43 +3431,28 @@ "dev": true }, "sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.0.tgz", + "integrity": "sha512-wVMT1jvgyLroQu+tWTa2XJu2g5SoVaEBhdwGPuzmWlRvZNSG+pcEb8HEmsxTdoPjUL58pJFQ3+oFRWrhC4JKHw==", "dev": true, "requires": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^8.1.0", + "@sinonjs/samsam": "^6.0.2", + "diff": "^5.0.0", + "nise": "^5.1.0", "supports-color": "^7.2.0" }, "dependencies": { - "@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, "@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dev": true, "requires": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^1.7.0" } }, - "diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -8953,14 +3555,6 @@ "bluebird": "^2.6.2" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -8982,6 +3576,14 @@ "strip-ansi": "^6.0.1" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", From 1c4b4f17e465d2365affc920e6f419e28fa787e9 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 14:51:26 -0400 Subject: [PATCH 77/93] Upgrade node to 14.7.0 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7d453e1..802af9c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "12.22.7" + node-version: "14.7.0" - run: cd src && cd .. #trying to fix "ENOENT: no such file or directory, uv_cwd" error - run: npm ci - run: npm run build @@ -38,7 +38,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "10.19.0" + node-version: "14.7.0" - run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ./.npmrc - run: npm ci - run: npm run build From 9eab0ecef147af65ce1f36f1bc464ab5dbcee2b8 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 14:53:11 -0400 Subject: [PATCH 78/93] Undo last commit wrong branch --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 802af9c..7d453e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "14.7.0" + node-version: "12.22.7" - run: cd src && cd .. #trying to fix "ENOENT: no such file or directory, uv_cwd" error - run: npm ci - run: npm run build @@ -38,7 +38,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "14.7.0" + node-version: "10.19.0" - run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ./.npmrc - run: npm ci - run: npm run build From 643b565aaa6b939eac5716283228028f36273b46 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 14:53:45 -0400 Subject: [PATCH 79/93] Upgrade node in build script to 14.17 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7d453e1..dfa1910 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "12.22.7" + node-version: "14.17.0" - run: cd src && cd .. #trying to fix "ENOENT: no such file or directory, uv_cwd" error - run: npm ci - run: npm run build @@ -38,7 +38,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "10.19.0" + node-version: "14.17.0" - run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ./.npmrc - run: npm ci - run: npm run build From 1b1bca35e47a23ca0507d677de05443ef7b101e6 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 14:56:12 -0400 Subject: [PATCH 80/93] Get rid of individual options checks --- src/RokuDeploy.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index cc0f7b0..f797f99 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -237,9 +237,6 @@ export class RokuDeploy { public async sideload(options: SideloadOptions): Promise<{ message: string; results: any }> { this.checkRequiredOptions(options, ['host', 'password']); options = this.getOptions(options) as any; - if (!options.host) { - throw new Error('must specify the host for the Roku device'); - } //make sure the outDir exists await fsExtra.ensureDir(options.outDir); @@ -332,9 +329,6 @@ export class RokuDeploy { public async convertToSquashfs(options: ConvertToSquashfsOptions) { this.checkRequiredOptions(options, ['host', 'password']); options = this.getOptions(options) as any; - if (!options.host) { - throw new Error('must specify the host for the Roku device'); - } let requestOptions = this.generateBaseRequestOptions('plugin_install', options as any, { archive: '', mysubmit: 'Convert to squashfs' @@ -353,13 +347,6 @@ export class RokuDeploy { public async rekeyDevice(options: RekeyDeviceOptions) { this.checkRequiredOptions(options, ['host', 'password', 'rekeySignedPackage', 'signingPassword']); options = this.getOptions(options) as any; - if (!options.rekeySignedPackage) { - throw new Error('Must supply rekeySignedPackage'); - } - - if (!options.signingPassword) { - throw new Error('Must supply signingPassword'); - } let rekeySignedPackagePath = options.rekeySignedPackage; if (!path.isAbsolute(options.rekeySignedPackage)) { @@ -407,9 +394,6 @@ export class RokuDeploy { public async createSignedPackage(options: CreateSignedPackageOptions): Promise { this.checkRequiredOptions(options, ['host', 'password', 'signingPassword']); options = this.getOptions(options) as any; - if (!options.signingPassword) { - throw new Error('Must supply signingPassword'); - } let manifestPath = path.join(options.stagingDir, 'manifest'); let parsedManifest = await this.parseManifest(manifestPath); let appName = parsedManifest.title + '/' + parsedManifest.major_version + '.' + parsedManifest.minor_version; From 20eaeb7eeb50fcfd5cfc687c73772a8e9489da29 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 14:59:28 -0400 Subject: [PATCH 81/93] Fixed option type in tests function --- src/RokuDeploy.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index fc26829..ec2233a 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3117,7 +3117,7 @@ describe('index', () => { }); describe('checkRequiredOptions', () => { - async function testRequiredOptions(action: string, requiredOptions: Partial, testedOption: string) { + async function testRequiredOptions(action: string, requiredOptions: Partial, testedOption: string) { const newOptions = { ...requiredOptions }; delete newOptions[testedOption]; await expectThrowsAsync(async () => { From c27809c8334c31a034e9c2b0a693c6da506ad32b Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 15:57:44 -0400 Subject: [PATCH 82/93] Fixing eslint libraries to be compatible with the version of node we are using --- package-lock.json | 876 ++++++++++++++++++++++++++++++++++------------ package.json | 7 +- 2 files changed, 653 insertions(+), 230 deletions(-) diff --git a/package-lock.json b/package-lock.json index 83e5f92..1b55b45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -301,7 +301,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, "requires": { "eslint-visitor-keys": "^3.3.0" } @@ -309,70 +308,48 @@ "@eslint-community/regexpp": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==" }, "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } } } }, - "@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true - }, "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" } }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, "@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@isaacs/cliui": { @@ -685,10 +662,9 @@ "dev": true }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "@types/lodash": { "version": "4.14.200", @@ -735,6 +711,11 @@ "form-data": "^2.5.0" } }, + "@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" + }, "@types/sinon": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.4.tgz", @@ -775,94 +756,303 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz", - "integrity": "sha512-bekODL3Tqf36Yz8u+ilha4zGxL9mdB6LIsIoMAvvC5FAuWo4NpZYXtCbv7B2CeR1LhI/lLtLk+q4tbtxuoVuCg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "5.1.0", - "@typescript-eslint/scope-manager": "5.1.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + } + } } }, - "@typescript-eslint/experimental-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.1.0.tgz", - "integrity": "sha512-ovE9qUiZMOMgxQAESZsdBT+EXIfx/YUYAbwGUI6V03amFdOOxI9c6kitkgRvLkJaLusgMZ2xBhss+tQ0Y1HWxA==", + "@typescript-eslint/parser": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.11.tgz", + "integrity": "sha512-s9ZF3M+Nym6CAZEkJJeO2TFHHDsKAM3ecNkLuH4i4s8/RCPnF5JRip2GyviYkeEAcwGMJxkqG9h2dAsnA1nZpA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@typescript-eslint/scope-manager": "5.59.11", + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/typescript-estree": "5.59.11", + "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.11.tgz", + "integrity": "sha512-dHFOsxoLFtrIcSj5h0QoBT/89hxQONwmn3FOQ0GOQcLOOXm+MIrS8zEAhs4tWl5MraxCY3ZJpaXQQdFMc2Tu+Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11" + } + }, + "@typescript-eslint/types": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.11.tgz", + "integrity": "sha512-epoN6R6tkvBYSc+cllrz+c2sOFWkbisJZWkOE+y3xHtvYaOE6Wk6B8e114McRJwFRjGvYdJwLXQH5c9osME/AA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.11.tgz", + "integrity": "sha512-YupOpot5hJO0maupJXixi6l5ETdrITxeo5eBOeuV7RSKgYdU3G5cxO49/9WRnJq9EMrB7AuTSLH/bqOsXi7wPA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.11", + "@typescript-eslint/visitor-keys": "5.59.11", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.59.11", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.11.tgz", + "integrity": "sha512-KGYniTGG3AMTuKF9QBD7EIrvufkB6O6uX3knP73xbKLMpH+QRPcgnCxjWXSHjMRuOxFLovljqQgQpR0c7GvjoA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.59.11", + "eslint-visitor-keys": "^3.3.0" + } + } } }, - "@typescript-eslint/parser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.1.0.tgz", - "integrity": "sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==", + "@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.1.0", - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/typescript-estree": "5.1.0", - "debug": "^4.3.2" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" } }, - "@typescript-eslint/scope-manager": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz", - "integrity": "sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==", - "dev": true, + "@typescript-eslint/type-utils": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", + "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0" + "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/utils": "7.4.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==" + }, + "@typescript-eslint/typescript-estree": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", + "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", + "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "eslint-visitor-keys": "^3.4.1" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.1.0.tgz", - "integrity": "sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz", - "integrity": "sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.1.0", - "@typescript-eslint/visitor-keys": "5.1.0", - "debug": "^4.3.2", - "globby": "^11.0.4", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" } }, + "@typescript-eslint/utils": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", + "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", + "semver": "^7.5.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", + "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0" + } + }, + "@typescript-eslint/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==" + }, + "@typescript-eslint/typescript-estree": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", + "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", + "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "eslint-visitor-keys": "^3.4.1" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "@typescript-eslint/visitor-keys": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz", - "integrity": "sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.1.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" } }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -964,8 +1154,7 @@ "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" }, "asn1": { "version": "0.2.4", @@ -986,6 +1175,12 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1004,8 +1199,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base64-js": { "version": "1.5.1", @@ -1321,7 +1515,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -1377,7 +1570,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, "requires": { "path-type": "^4.0.0" } @@ -1417,6 +1609,16 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + } + }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -1434,51 +1636,62 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.3.2", + "debug": "^4.0.1", "doctrine": "^3.0.0", + "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.0.4", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1488,12 +1701,6 @@ "color-convert": "^2.0.1" } }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1525,20 +1732,10 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "has-flag": { @@ -1547,14 +1744,11 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true }, "supports-color": { "version": "7.2.0", @@ -1578,18 +1772,18 @@ } }, "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "eslint-visitor-keys": "^2.0.0" + "eslint-visitor-keys": "^1.1.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } @@ -1597,18 +1791,31 @@ "eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==" }, "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "esprima": { @@ -1764,12 +1971,13 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "dependencies": { @@ -1785,9 +1993,9 @@ } }, "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "foreground-child": { @@ -1848,7 +2056,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "gensync": { @@ -1897,12 +2105,12 @@ } }, "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { - "is-glob": "^4.0.3" + "is-glob": "^4.0.1" } }, "globals": { @@ -1915,16 +2123,16 @@ } }, "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" } }, @@ -1936,8 +2144,7 @@ "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "har-schema": { "version": "2.0.0", @@ -1991,8 +2198,7 @@ "ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==" }, "immediate": { "version": "3.0.6", @@ -2068,12 +2274,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2268,6 +2468,12 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -2281,7 +2487,7 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json-stringify-safe": { @@ -2325,6 +2531,15 @@ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, "lcov-parse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", @@ -2381,6 +2596,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -2461,7 +2682,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -2674,13 +2894,17 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, "nise": { @@ -3044,8 +3268,7 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "pathval": { "version": "1.1.1", @@ -3194,6 +3417,12 @@ "fromentries": "^1.2.0" } }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -3277,6 +3506,12 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -3384,7 +3619,6 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -3473,8 +3707,44 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } }, "source-map": { "version": "0.5.7", @@ -3621,6 +3891,39 @@ "has-flag": "^3.0.0" } }, + "table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, "temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -3640,7 +3943,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "to-fast-properties": { @@ -3657,6 +3960,11 @@ "is-number": "^7.0.0" } }, + "ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==" + }, "ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -3742,6 +4050,115 @@ "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "dev": true }, + "typescript-eslint": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.4.0.tgz", + "integrity": "sha512-8GYQsb/joknlAZEAs/kqonfrsAc98C5DoellmwHREPqKwSTKSY2YB93IwmvNuX6+WE5QkKc31X9wHo/UcpYXpw==", + "requires": { + "@typescript-eslint/eslint-plugin": "7.4.0", + "@typescript-eslint/parser": "7.4.0", + "@typescript-eslint/utils": "7.4.0" + }, + "dependencies": { + "@typescript-eslint/eslint-plugin": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", + "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", + "requires": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/type-utils": "7.4.0", + "@typescript-eslint/utils": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/parser": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", + "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "requires": { + "@typescript-eslint/scope-manager": "7.4.0", + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/typescript-estree": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", + "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0" + } + }, + "@typescript-eslint/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==" + }, + "@typescript-eslint/typescript-estree": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", + "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "@typescript-eslint/visitor-keys": "7.4.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", + "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "requires": { + "@typescript-eslint/types": "7.4.0", + "eslint-visitor-keys": "^3.4.1" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -3775,6 +4192,12 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", + "dev": true + }, "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -3929,8 +4352,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yargs": { "version": "17.7.2", diff --git a/package.json b/package.json index dabe4e7..ab102c1 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "parse-ms": "^2.1.0", "postman-request": "^2.88.1-postman.32", "temp-dir": "^2.0.0", + "typescript-eslint": "^7.4.0", "xml2js": "^0.5.0", "yargs": "^17.7.2" }, @@ -47,12 +48,12 @@ "@types/sinon": "^10.0.4", "@types/xml2js": "^0.4.5", "@types/yargs": "^17.0.32", - "@typescript-eslint/eslint-plugin": "5.1.0", - "@typescript-eslint/parser": "5.1.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.59.11", "chai": "^4.3.4", "coveralls-next": "^4.2.0", "dedent": "^0.7.0", - "eslint": "^8.57.0", + "eslint": "^7.32.0", "mocha": "^10.3.0", "nyc": "^15.1.0", "q": "^1.5.1", From 75cff5bfe28b7b331936f788b8437dff338588e3 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 16:20:38 -0400 Subject: [PATCH 83/93] Fix lint errors: sorting unions and importing types in the same line as packages --- src/RokuDeploy.spec.ts | 5 ++--- src/RokuDeploy.ts | 10 +++++----- src/RokuDeployOptions.ts | 2 +- src/commands/ExecCommand.ts | 3 +-- src/util.ts | 7 +++---- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index ec2233a..48d4370 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -8,7 +8,6 @@ import * as path from 'path'; import * as JSZip from 'jszip'; import * as child_process from 'child_process'; import * as glob from 'glob'; -import { RokuDeploy } from './RokuDeploy'; import * as errors from './Errors'; import { util, standardizePath as s, standardizePathPosix as sp } from './util'; import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; @@ -16,7 +15,7 @@ import { cwd, expectPathExists, expectPathNotExists, expectThrowsAsync, outDir, import { createSandbox } from 'sinon'; import * as r from 'postman-request'; import type * as requestType from 'request'; -import type { CaptureScreenshotOptions, ConvertToSquashfsOptions, CreateSignedPackageOptions, DeleteDevChannelOptions, GetDevIdOptions, GetDeviceInfoOptions, RekeyDeviceOptions, SendKeyEventOptions, SideloadOptions } from './RokuDeploy'; +import { RokuDeploy, type CaptureScreenshotOptions, type ConvertToSquashfsOptions, type CreateSignedPackageOptions, type DeleteDevChannelOptions, type GetDevIdOptions, type GetDeviceInfoOptions, type RekeyDeviceOptions, type SendKeyEventOptions, type SideloadOptions } from './RokuDeploy'; const request = r as typeof requestType; const sinon = createSandbox(); @@ -26,7 +25,7 @@ describe('index', () => { let options: RokuDeployOptions; let writeStreamPromise: Promise; - let writeStreamDeferred: q.Deferred & { isComplete: undefined | true }; + let writeStreamDeferred: q.Deferred & { isComplete: true | undefined }; let createWriteStreamStub: sinon.SinonStub; beforeEach(() => { diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index f797f99..5b8ffbf 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -662,7 +662,7 @@ export class RokuDeploy { * Get an options with all overridden values, and then defaults for missing values * @param options */ - public getOptions(options: T & RokuDeployOptions = {} as any): RokuDeployOptions & T { + public getOptions(options: RokuDeployOptions & T = {} as any): RokuDeployOptions & T { // Fill in default options for any missing values options = { cwd: process.cwd(), @@ -749,8 +749,8 @@ export class RokuDeploy { * @param host the host or IP address of the Roku * @param port the port to use for the ECP request (defaults to 8060) */ - public async getDeviceInfo(options?: { enhance: true } & GetDeviceInfoOptions): Promise; - public async getDeviceInfo(options?: GetDeviceInfoOptions): Promise + public async getDeviceInfo(options?: GetDeviceInfoOptions & { enhance: true }): Promise; + public async getDeviceInfo(options?: GetDeviceInfoOptions): Promise; public async getDeviceInfo(options: GetDeviceInfoOptions) { this.checkRequiredOptions(options, ['host']); options = this.getOptions(options) as any; @@ -937,9 +937,9 @@ export interface GetDeviceInfoOptions { enhance?: boolean; } -type RokuKey = 'home' | 'rev' | 'fwd' | 'play' | 'select' | 'left' | 'right' | 'down' | 'up' | 'back' | 'instantreplay' | 'info' | 'backspace' | 'search' | 'enter' | 'findremote' | 'volumeup' | 'volumedown' | 'volumemute' | 'poweroff' | 'channelup' | 'channeldown' | 'inputtuner' | 'inputhdmi1' | 'inputhdmi2' | 'inputhdmi3' | 'inputhdmi4' | 'inputav1'; +type RokuKey = 'back' | 'backspace' | 'channeldown' | 'channelup' | 'down' | 'enter' | 'findremote' | 'fwd' | 'home' | 'info' | 'inputav1' | 'inputhdmi1' | 'inputhdmi2' | 'inputhdmi3' | 'inputhdmi4' | 'inputtuner' | 'instantreplay' | 'left' | 'play' | 'poweroff' | 'rev' | 'right' | 'search' | 'select' | 'up' | 'volumedown' | 'volumemute' | 'volumeup'; export interface SendKeyEventOptions { - action?: 'keypress' | 'keydown' | 'keyup'; + action?: 'keydown' | 'keypress' | 'keyup'; host: string; key: RokuKey | string; remotePort?: number; diff --git a/src/RokuDeployOptions.ts b/src/RokuDeployOptions.ts index 058b22b..1e3de34 100644 --- a/src/RokuDeployOptions.ts +++ b/src/RokuDeployOptions.ts @@ -136,4 +136,4 @@ export interface RokuDeployOptions { deleteDevChannel?: boolean; } -export type FileEntry = (string | { src: string | string[]; dest?: string }); +export type FileEntry = (string | { src: string[] | string; dest?: string }); diff --git a/src/commands/ExecCommand.ts b/src/commands/ExecCommand.ts index 04fd034..1a37371 100644 --- a/src/commands/ExecCommand.ts +++ b/src/commands/ExecCommand.ts @@ -1,7 +1,6 @@ import { util } from '../util'; -import { rokuDeploy } from '../RokuDeploy'; -import type { CloseChannelOptions, ConvertToSquashfsOptions, CreateSignedPackageOptions, DeleteDevChannelOptions, RekeyDeviceOptions, SideloadOptions } from '../RokuDeploy'; import type { RokuDeployOptions } from '../RokuDeployOptions'; +import { rokuDeploy, type CloseChannelOptions, type ConvertToSquashfsOptions, type CreateSignedPackageOptions, type DeleteDevChannelOptions, type RekeyDeviceOptions, type SideloadOptions } from '../RokuDeploy'; export class ExecCommand { private actions: string[]; diff --git a/src/util.ts b/src/util.ts index bc11ead..e587f31 100644 --- a/src/util.ts +++ b/src/util.ts @@ -9,8 +9,7 @@ import type { FileEntry, RokuDeployOptions } from './RokuDeployOptions'; import type { StandardizedFileEntry } from './RokuDeploy'; import * as isGlob from 'is-glob'; import * as picomatch from 'picomatch'; -import { parse as parseJsonc, printParseErrorCode } from 'jsonc-parser'; -import type { ParseError } from 'jsonc-parser'; +import { parse as parseJsonc, printParseErrorCode, type ParseError } from 'jsonc-parser'; export class Util { /** @@ -238,7 +237,7 @@ export class Util { * @param files */ public normalizeFilesArray(files: FileEntry[]) { - const result: Array = []; + const result: Array = []; for (let i = 0; i < files.length; i++) { let entry = files[i]; @@ -345,7 +344,7 @@ export class Util { * @param pattern the glob pattern originally used to find this file * @param rootDir absolute normalized path to the rootDir */ - public computeFileDestPath(srcPath: string, entry: string | StandardizedFileEntry, rootDir: string) { + public computeFileDestPath(srcPath: string, entry: StandardizedFileEntry | string, rootDir: string) { let result: string; let globstarIdx: number; //files under rootDir with no specified dest From b5b532bbc42ad4b45db99e0a67c0fbfb3a2a02ec Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Tue, 26 Mar 2024 16:25:34 -0400 Subject: [PATCH 84/93] Fix lint errors: lines around comments set to false, prefer nullish coalescing set to false, propert results should be set as a class property, optional chaining, and no redundant types --- .eslintrc.js | 3 ++- src/Errors.ts | 12 ++++++------ src/RokuDeploy.ts | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index bf4e5bd..5ce7699 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,6 +23,7 @@ module.exports = { '@typescript-eslint/explicit-member-accessibility': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/init-declarations': 'off', + '@typescript-eslint/lines-around-comment': 'off', '@typescript-eslint/member-ordering': 'off', "@typescript-eslint/naming-convention": 'off', '@typescript-eslint/no-base-to-string': 'off', @@ -52,6 +53,7 @@ module.exports = { 'error', 'always' ], + '@typescript-eslint/prefer-nullish-coalescing': 'off', '@typescript-eslint/prefer-readonly': 'off', '@typescript-eslint/prefer-readonly-parameter-types': 'off', '@typescript-eslint/promise-function-async': 'off', @@ -94,7 +96,6 @@ module.exports = { 'init-declarations': 'off', 'line-comment-position': 'off', 'linebreak-style': 'off', - 'lines-around-comment': 'off', 'lines-between-class-members': 'off', 'max-classes-per-file': 'off', 'max-depth': 'off', diff --git a/src/Errors.ts b/src/Errors.ts index bec353e..1c4b697 100644 --- a/src/Errors.ts +++ b/src/Errors.ts @@ -1,42 +1,42 @@ import type { RokuMessages } from './RokuDeploy'; export class InvalidDeviceResponseCodeError extends Error { - constructor(message: string, public results?: any) { + constructor(message: string, results?: any) { super(message); Object.setPrototypeOf(this, InvalidDeviceResponseCodeError.prototype); } } export class UnauthorizedDeviceResponseError extends Error { - constructor(message: string, public results?: any) { + constructor(message: string, results?: any) { super(message); Object.setPrototypeOf(this, UnauthorizedDeviceResponseError.prototype); } } export class UnparsableDeviceResponseError extends Error { - constructor(message: string, public results?: any) { + constructor(message: string, results?: any) { super(message); Object.setPrototypeOf(this, UnparsableDeviceResponseError.prototype); } } export class FailedDeviceResponseError extends Error { - constructor(message: string, public results?: any) { + constructor(message: string, results?: any) { super(message); Object.setPrototypeOf(this, FailedDeviceResponseError.prototype); } } export class UnknownDeviceResponseError extends Error { - constructor(message: string, public results?: any) { + constructor(message: string, results?: any) { super(message); Object.setPrototypeOf(this, UnknownDeviceResponseError.prototype); } } export class CompileError extends Error { - constructor(message: string, public results: any, public rokuMessages: RokuMessages) { + constructor(message: string, results: any, rokuMessages: RokuMessages) { super(message); Object.setPrototypeOf(this, CompileError.prototype); } diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 5b8ffbf..1657ec7 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -470,7 +470,7 @@ export class RokuDeploy { } private checkRequest(results) { - if (!results || !results.response || typeof results.body !== 'string') { + if (!results?.response || typeof results?.body !== 'string') { throw new errors.UnparsableDeviceResponseError('Invalid response', results); } @@ -941,7 +941,7 @@ type RokuKey = 'back' | 'backspace' | 'channeldown' | 'channelup' | 'down' | 'en export interface SendKeyEventOptions { action?: 'keydown' | 'keypress' | 'keyup'; host: string; - key: RokuKey | string; + key: RokuKey; remotePort?: number; timeout?: number; } From 1a8c5c5fdf0e2eafec3139f3a59a9642a2274183 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 28 Mar 2024 13:17:11 -0400 Subject: [PATCH 85/93] Fix 2 more lint errors --- src/RokuDeploy.spec.ts | 2 +- src/RokuDeploy.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 48d4370..497fd2f 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3125,7 +3125,7 @@ describe('index', () => { } it('throws error when sendKeyEvent is missing required options', async () => { - const requiredOptions: Partial = { host: '1.2.3.4', key: 'string' }; + const requiredOptions: Partial = { host: '1.2.3.4', key: 'up' }; await testRequiredOptions('sendKeyEvent', requiredOptions, 'host'); await testRequiredOptions('sendKeyEvent', requiredOptions, 'key'); }); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 1657ec7..9f2967a 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -941,7 +941,8 @@ type RokuKey = 'back' | 'backspace' | 'channeldown' | 'channelup' | 'down' | 'en export interface SendKeyEventOptions { action?: 'keydown' | 'keypress' | 'keyup'; host: string; - key: RokuKey; + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + key: RokuKey | string; remotePort?: number; timeout?: number; } From 83ee40676d68b7a02956bdfc9afe8e5401ea2b8e Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 28 Mar 2024 15:44:12 -0400 Subject: [PATCH 86/93] Fix jszip error --- src/RokuDeploy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 9f2967a..49126f6 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -15,6 +15,7 @@ import * as dayjs from 'dayjs'; import * as lodash from 'lodash'; import type { DeviceInfo, DeviceInfoRaw } from './DeviceInfo'; import * as tempDir from 'temp-dir'; +import { Compression } from 'jszip'; export class RokuDeploy { @@ -97,7 +98,7 @@ export class RokuDeploy { for (const file of filePaths) { const promise = fsExtra.readFile(file.src).then((data) => { const ext = path.extname(file.dest).toLowerCase(); - let compression = 'DEFLATE'; + let compression: Compression = 'DEFLATE'; if (ext === '.jpg' || ext === '.png' || ext === '.jpeg') { compression = 'STORE'; From c41a97a1bbcb6401cef853b889d29cfb0ffe28ad Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 28 Mar 2024 15:51:41 -0400 Subject: [PATCH 87/93] Undo last change --- src/RokuDeploy.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 49126f6..9f2967a 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -15,7 +15,6 @@ import * as dayjs from 'dayjs'; import * as lodash from 'lodash'; import type { DeviceInfo, DeviceInfoRaw } from './DeviceInfo'; import * as tempDir from 'temp-dir'; -import { Compression } from 'jszip'; export class RokuDeploy { @@ -98,7 +97,7 @@ export class RokuDeploy { for (const file of filePaths) { const promise = fsExtra.readFile(file.src).then((data) => { const ext = path.extname(file.dest).toLowerCase(); - let compression: Compression = 'DEFLATE'; + let compression = 'DEFLATE'; if (ext === '.jpg' || ext === '.png' || ext === '.jpeg') { compression = 'STORE'; From da4367506d70f199606266370fd38f60ea1273b7 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 28 Mar 2024 16:16:54 -0400 Subject: [PATCH 88/93] Turn off prefer optional chain --- .eslintrc.js | 1 + src/RokuDeploy.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index 5ce7699..55941b1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -54,6 +54,7 @@ module.exports = { 'always' ], '@typescript-eslint/prefer-nullish-coalescing': 'off', + "@typescript-eslint/prefer-optional-chain": 'off', '@typescript-eslint/prefer-readonly': 'off', '@typescript-eslint/prefer-readonly-parameter-types': 'off', '@typescript-eslint/promise-function-async': 'off', diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index 9f2967a..fd21800 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -470,7 +470,7 @@ export class RokuDeploy { } private checkRequest(results) { - if (!results?.response || typeof results?.body !== 'string') { + if (!results || !results.response || typeof results.body !== 'string') { throw new errors.UnparsableDeviceResponseError('Invalid response', results); } From 896e0afc8430ab7357bd690d1d3c27236610e09b Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 28 Mar 2024 16:34:27 -0400 Subject: [PATCH 89/93] Disable duplicate imports error one time --- src/RokuDeploy.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 497fd2f..f53d7a6 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -15,7 +15,9 @@ import { cwd, expectPathExists, expectPathNotExists, expectThrowsAsync, outDir, import { createSandbox } from 'sinon'; import * as r from 'postman-request'; import type * as requestType from 'request'; -import { RokuDeploy, type CaptureScreenshotOptions, type ConvertToSquashfsOptions, type CreateSignedPackageOptions, type DeleteDevChannelOptions, type GetDevIdOptions, type GetDeviceInfoOptions, type RekeyDeviceOptions, type SendKeyEventOptions, type SideloadOptions } from './RokuDeploy'; +import { RokuDeploy } from './RokuDeploy'; +// eslint-disable-next-line no-duplicate-imports +import type { CaptureScreenshotOptions, ConvertToSquashfsOptions, CreateSignedPackageOptions, DeleteDevChannelOptions, GetDevIdOptions, GetDeviceInfoOptions, RekeyDeviceOptions, SendKeyEventOptions, SideloadOptions } from './RokuDeploy'; const request = r as typeof requestType; const sinon = createSandbox(); From e529688ef09cee071fc2dfb8d1634cd306754bff Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Thu, 28 Mar 2024 16:37:43 -0400 Subject: [PATCH 90/93] move eslint to a dev dependency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ab102c1..f9c5bd4 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "parse-ms": "^2.1.0", "postman-request": "^2.88.1-postman.32", "temp-dir": "^2.0.0", - "typescript-eslint": "^7.4.0", "xml2js": "^0.5.0", "yargs": "^17.7.2" }, @@ -48,6 +47,7 @@ "@types/sinon": "^10.0.4", "@types/xml2js": "^0.4.5", "@types/yargs": "^17.0.32", + "typescript-eslint": "^7.4.0", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.59.11", "chai": "^4.3.4", From a805021757ead10ca6ee189afc713136a04ba3c5 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 1 Apr 2024 11:29:15 -0400 Subject: [PATCH 91/93] Fix eslint errors --- package.json | 8 ++++---- src/RokuDeploy.ts | 2 +- types/Blob/index.d.ts | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 types/Blob/index.d.ts diff --git a/package.json b/package.json index f9c5bd4..cd829a6 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "fs-extra": "^7.0.1", "is-glob": "^4.0.3", "jsonc-parser": "^2.3.0", - "jszip": "^3.6.0", + "jszip": "^3.10.1", "lodash": "^4.17.21", "micromatch": "^4.0.4", "moment": "^2.29.1", @@ -47,13 +47,12 @@ "@types/sinon": "^10.0.4", "@types/xml2js": "^0.4.5", "@types/yargs": "^17.0.32", - "typescript-eslint": "^7.4.0", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.59.11", "chai": "^4.3.4", "coveralls-next": "^4.2.0", "dedent": "^0.7.0", - "eslint": "^7.32.0", + "eslint": "^8.56.0", "mocha": "^10.3.0", "nyc": "^15.1.0", "q": "^1.5.1", @@ -61,7 +60,8 @@ "sinon": "^12.0.0", "source-map-support": "^0.5.21", "ts-node": "^10.9.2", - "typescript": "^5.4.3" + "typescript": "^5.4.3", + "typescript-eslint": "^7.4.0" }, "mocha": { "require": [ diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index fd21800..b071633 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -97,7 +97,7 @@ export class RokuDeploy { for (const file of filePaths) { const promise = fsExtra.readFile(file.src).then((data) => { const ext = path.extname(file.dest).toLowerCase(); - let compression = 'DEFLATE'; + let compression: 'DEFLATE' | 'STORE' = 'DEFLATE'; if (ext === '.jpg' || ext === '.png' || ext === '.jpeg') { compression = 'STORE'; diff --git a/types/Blob/index.d.ts b/types/Blob/index.d.ts new file mode 100644 index 0000000..a68edc8 --- /dev/null +++ b/types/Blob/index.d.ts @@ -0,0 +1 @@ +type Blob = never \ No newline at end of file From 1f914fa39ca9e9a7ddcff84853a5e5333645e4c6 Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 1 Apr 2024 13:24:25 -0400 Subject: [PATCH 92/93] Added npm install package lock, which actually fixed a different issue --- package-lock.json | 721 ++++++++++++++++++++--------------------- src/RokuDeploy.spec.ts | 1 - types/Blob/index.d.ts | 1 - 3 files changed, 358 insertions(+), 365 deletions(-) delete mode 100644 types/Blob/index.d.ts diff --git a/package-lock.json b/package-lock.json index 1b55b45..74fb047 100644 --- a/package-lock.json +++ b/package-lock.json @@ -301,6 +301,7 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, "requires": { "eslint-visitor-keys": "^3.3.0" } @@ -308,48 +309,70 @@ "@eslint-community/regexpp": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==" + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true }, "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "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.6.0", + "globals": "^13.19.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" }, "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, + "@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true + }, "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" } }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "@isaacs/cliui": { @@ -378,6 +401,21 @@ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -395,6 +433,40 @@ "strip-ansi": "^7.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", @@ -404,6 +476,23 @@ "ansi-regex": "^6.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + } + } + }, "wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -414,6 +503,60 @@ "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } } } }, @@ -664,7 +807,8 @@ "@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "@types/lodash": { "version": "4.14.200", @@ -714,7 +858,8 @@ "@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true }, "@types/sinon": { "version": "10.0.4", @@ -872,6 +1017,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz", "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==", + "dev": true, "requires": { "@typescript-eslint/typescript-estree": "7.4.0", "@typescript-eslint/utils": "7.4.0", @@ -882,12 +1028,14 @@ "@typescript-eslint/types": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==" + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "dev": true }, "@typescript-eslint/typescript-estree": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "@typescript-eslint/visitor-keys": "7.4.0", @@ -903,6 +1051,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "eslint-visitor-keys": "^3.4.1" @@ -912,6 +1061,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "requires": { "balanced-match": "^1.0.0" } @@ -920,6 +1070,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -933,6 +1084,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "requires": { "brace-expansion": "^2.0.1" } @@ -964,6 +1116,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz", "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==", + "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -978,6 +1131,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "@typescript-eslint/visitor-keys": "7.4.0" @@ -986,12 +1140,14 @@ "@typescript-eslint/types": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==" + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "dev": true }, "@typescript-eslint/typescript-estree": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "@typescript-eslint/visitor-keys": "7.4.0", @@ -1007,6 +1163,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "eslint-visitor-keys": "^3.4.1" @@ -1016,6 +1173,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "requires": { "balanced-match": "^1.0.0" } @@ -1024,6 +1182,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -1037,6 +1196,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "requires": { "brace-expansion": "^2.0.1" } @@ -1053,6 +1213,12 @@ "eslint-visitor-keys": "^3.3.0" } }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -1133,7 +1299,7 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, "arg": { @@ -1154,7 +1320,8 @@ "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true }, "asn1": { "version": "0.2.4", @@ -1167,7 +1334,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" }, "assertion-error": { "version": "1.1.0", @@ -1175,21 +1342,15 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" }, "aws4": { "version": "1.12.0", @@ -1199,7 +1360,8 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "base64-js": { "version": "1.5.1", @@ -1209,7 +1371,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "requires": { "tweetnacl": "^0.14.3" } @@ -1309,7 +1471,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, "chai": { "version": "4.4.1", @@ -1412,13 +1574,13 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "convert-source-map": { @@ -1496,7 +1658,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "requires": { "assert-plus": "^1.0.0" } @@ -1515,6 +1677,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -1528,7 +1691,7 @@ "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, "deep-eql": { @@ -1558,7 +1721,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "diff": { "version": "5.0.0", @@ -1570,6 +1733,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "requires": { "path-type": "^4.0.0" } @@ -1592,7 +1756,7 @@ "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -1609,16 +1773,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - } - }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -1636,62 +1790,51 @@ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "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", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "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", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "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", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1701,6 +1844,12 @@ "color-convert": "^2.0.1" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1732,10 +1881,20 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "has-flag": { @@ -1744,11 +1903,14 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } }, "supports-color": { "version": "7.2.0", @@ -1771,51 +1933,21 @@ "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, "eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==" + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true }, "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -1878,7 +2010,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" }, "fast-deep-equal": { "version": "3.1.3", @@ -2011,7 +2143,7 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" }, "form-data": { "version": "2.5.1", @@ -2043,7 +2175,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { @@ -2053,12 +2185,6 @@ "dev": true, "optional": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2085,7 +2211,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "requires": { "assert-plus": "^1.0.0" } @@ -2105,12 +2231,12 @@ } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, "globals": { @@ -2144,12 +2270,13 @@ "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" }, "har-validator": { "version": "5.1.5", @@ -2198,12 +2325,13 @@ "ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==" + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true }, "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" }, "import-fresh": { "version": "3.3.0", @@ -2218,7 +2346,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -2230,7 +2358,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -2254,7 +2382,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -2274,6 +2402,12 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2283,7 +2417,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "is-unicode-supported": { "version": "0.1.0", @@ -2300,18 +2434,18 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -2460,7 +2594,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "jsesc": { "version": "2.5.2", @@ -2493,7 +2627,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { "version": "2.2.3", @@ -2509,20 +2643,20 @@ "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "requires": { "graceful-fs": "^4.1.6" } }, "jszip": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.8.0.tgz", - "integrity": "sha512-cnpQrXvFSLdsR9KR5/x7zdf6c3m8IhZfZzSblFEHSqBaVwD2nvJ4CuCKLyvKvwBgZm08CgfSoiTBQLm5WW9hGw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "requires": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" + "setimmediate": "^1.0.5" } }, "just-extend": { @@ -2543,7 +2677,7 @@ "lcov-parse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "integrity": "sha512-aprLII/vPzuQvYZnDRU78Fns9I2Ag3gi4Ipga/hxnVMCZC8DnR2nI7XBqrPoywGfxqIx/DgarGvDJZAD3YBTgQ==", "dev": true }, "levn": { @@ -2581,7 +2715,7 @@ "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", "dev": true }, "lodash.get": { @@ -2596,12 +2730,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -2682,6 +2810,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "requires": { "yallist": "^4.0.0" } @@ -2894,12 +3023,14 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true }, "natural-compare-lite": { "version": "1.4.0", @@ -3139,7 +3270,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -3232,7 +3363,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { @@ -3268,7 +3399,8 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "pathval": { "version": "1.1.1", @@ -3279,7 +3411,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "picocolors": { "version": "1.0.0", @@ -3417,12 +3549,6 @@ "fromentries": "^1.2.0" } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -3464,9 +3590,9 @@ } }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3486,16 +3612,10 @@ "picomatch": "^2.2.1" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, "requires": { "es6-error": "^4.0.1" @@ -3504,13 +3624,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "require-main-filename": { "version": "2.0.0", @@ -3619,6 +3733,7 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -3635,13 +3750,13 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "shebang-command": { "version": "2.0.0", @@ -3707,44 +3822,8 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, "source-map": { "version": "0.5.7", @@ -3798,7 +3877,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "sshpk": { @@ -3835,17 +3914,6 @@ "strip-ansi": "^6.0.1" } }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -3862,15 +3930,6 @@ "ansi-regex": "^5.0.1" } }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -3891,39 +3950,6 @@ "has-flag": "^3.0.0" } }, - "table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, "temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -3949,7 +3975,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, "to-regex-range": { @@ -3963,7 +3989,8 @@ "ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==" + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true }, "ts-node": { "version": "10.9.2", @@ -4012,7 +4039,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "type-check": { "version": "0.4.0", @@ -4054,6 +4081,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.4.0.tgz", "integrity": "sha512-8GYQsb/joknlAZEAs/kqonfrsAc98C5DoellmwHREPqKwSTKSY2YB93IwmvNuX6+WE5QkKc31X9wHo/UcpYXpw==", + "dev": true, "requires": { "@typescript-eslint/eslint-plugin": "7.4.0", "@typescript-eslint/parser": "7.4.0", @@ -4064,6 +4092,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz", "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==", + "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "7.4.0", @@ -4082,6 +4111,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz", "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==", + "dev": true, "requires": { "@typescript-eslint/scope-manager": "7.4.0", "@typescript-eslint/types": "7.4.0", @@ -4094,6 +4124,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz", "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "@typescript-eslint/visitor-keys": "7.4.0" @@ -4102,12 +4133,14 @@ "@typescript-eslint/types": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz", - "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==" + "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==", + "dev": true }, "@typescript-eslint/typescript-estree": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz", "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "@typescript-eslint/visitor-keys": "7.4.0", @@ -4123,6 +4156,7 @@ "version": "7.4.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz", "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==", + "dev": true, "requires": { "@typescript-eslint/types": "7.4.0", "eslint-visitor-keys": "^3.4.1" @@ -4132,6 +4166,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "requires": { "balanced-match": "^1.0.0" } @@ -4140,6 +4175,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -4153,6 +4189,7 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, "requires": { "brace-expansion": "^2.0.1" } @@ -4184,7 +4221,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "uuid": { "version": "3.4.0", @@ -4192,12 +4229,6 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -4207,7 +4238,7 @@ "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -4217,7 +4248,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" } } }, @@ -4275,47 +4306,10 @@ } } }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "write-file-atomic": { @@ -4352,7 +4346,8 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "yargs": { "version": "17.7.2", diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index f53d7a6..716b4ea 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -16,7 +16,6 @@ import { createSandbox } from 'sinon'; import * as r from 'postman-request'; import type * as requestType from 'request'; import { RokuDeploy } from './RokuDeploy'; -// eslint-disable-next-line no-duplicate-imports import type { CaptureScreenshotOptions, ConvertToSquashfsOptions, CreateSignedPackageOptions, DeleteDevChannelOptions, GetDevIdOptions, GetDeviceInfoOptions, RekeyDeviceOptions, SendKeyEventOptions, SideloadOptions } from './RokuDeploy'; const request = r as typeof requestType; diff --git a/types/Blob/index.d.ts b/types/Blob/index.d.ts deleted file mode 100644 index a68edc8..0000000 --- a/types/Blob/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -type Blob = never \ No newline at end of file From cb25a04824d5aa061f83a01b4d3b60bd5b210a6a Mon Sep 17 00:00:00 2001 From: Milap Naik Date: Mon, 1 Apr 2024 13:52:02 -0400 Subject: [PATCH 93/93] add eslint plugin import, fix logical-assignment-operators error --- .eslintrc.js | 5 +- package-lock.json | 947 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/RokuDeploy.ts | 2 +- 4 files changed, 953 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 55941b1..70ce03d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,7 +10,8 @@ module.exports = { project: './tsconfig.json' }, plugins: [ - '@typescript-eslint' + '@typescript-eslint', + 'import' ], extends: [ 'eslint:all', @@ -93,6 +94,7 @@ module.exports = { 'function-paren-newline': 'off', 'guard-for-in': 'off', 'id-length': 'off', + 'import/no-duplicates': 'error', 'indent': 'off', 'init-declarations': 'off', 'line-comment-position': 'off', @@ -114,6 +116,7 @@ module.exports = { 'no-constant-condition': 'off', 'no-console': 'off', 'no-continue': 'off', + 'no-duplicate-imports': 'off', 'no-else-return': 'off', 'no-empty': 'off', 'no-implicit-coercion': 'off', diff --git a/package-lock.json b/package-lock.json index 74fb047..6780326 100644 --- a/package-lock.json +++ b/package-lock.json @@ -810,6 +810,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "@types/lodash": { "version": "4.14.200", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", @@ -1317,12 +1323,90 @@ "sprintf-js": "~1.0.2" } }, + "array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + } + }, + "array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + } + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -1347,6 +1431,15 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -1450,6 +1543,19 @@ "write-file-atomic": "^3.0.0" } }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1663,6 +1769,39 @@ "assert-plus": "^1.0.0" } }, + "data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -1718,6 +1857,28 @@ "strip-bom": "^4.0.0" } }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, + "define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1773,6 +1934,115 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + } + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + } + }, + "es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "requires": { + "hasown": "^2.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -1923,6 +2193,99 @@ } } }, + "eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "requires": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -2130,6 +2493,15 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -2185,6 +2557,30 @@ "dev": true, "optional": true }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true + }, + "function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2202,12 +2598,36 @@ "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -2248,6 +2668,15 @@ "type-fest": "^0.20.2" } }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -2262,6 +2691,15 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", @@ -2287,11 +2725,47 @@ "har-schema": "^2.0.0" } }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, "hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", @@ -2310,6 +2784,15 @@ } } }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -2370,6 +2853,36 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2379,6 +2892,49 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "requires": { + "hasown": "^2.0.0" + } + }, + "is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "requires": { + "is-typed-array": "^1.1.13" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2397,23 +2953,84 @@ "is-extglob": "^2.1.1" } }, + "is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "requires": { + "call-bind": "^1.0.7" + } + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "requires": { + "which-typed-array": "^1.1.14" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -2425,6 +3042,15 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -3267,6 +3893,64 @@ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + } + }, + "object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + } + }, + "object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3372,6 +4056,12 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, "path-scurry": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", @@ -3472,6 +4162,12 @@ } } }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, "postman-request": { "version": "2.88.1-postman.32", "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.32.tgz", @@ -3612,6 +4308,18 @@ "picomatch": "^2.2.1" } }, + "regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + } + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -3637,6 +4345,17 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3714,11 +4433,42 @@ "queue-microtask": "^1.2.2" } }, + "safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -3753,6 +4503,32 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, + "set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + } + }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -3773,6 +4549,18 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, "signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", @@ -3914,6 +4702,40 @@ "strip-ansi": "^6.0.1" } }, + "string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -3950,6 +4772,12 @@ "has-flag": "^3.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -4021,6 +4849,35 @@ } } }, + "tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + } + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -4062,6 +4919,58 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + } + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -4196,6 +5105,18 @@ } } }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -4261,12 +5182,38 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + } + }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", diff --git a/package.json b/package.json index cd829a6..40b383a 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "coveralls-next": "^4.2.0", "dedent": "^0.7.0", "eslint": "^8.56.0", + "eslint-plugin-import": "^2.29.1", "mocha": "^10.3.0", "nyc": "^15.1.0", "q": "^1.5.1", diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index b071633..4d2dea9 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -596,7 +596,7 @@ export class RokuDeploy { public async captureScreenshot(options: CaptureScreenshotOptions) { this.checkRequiredOptions(options, ['host', 'password']); options = this.getOptions(options); - options.screenshotFile = options.screenshotFile ?? `screenshot-${dayjs().format('YYYY-MM-DD-HH.mm.ss.SSS')}`; + options.screenshotFile ??= `screenshot-${dayjs().format('YYYY-MM-DD-HH.mm.ss.SSS')}`; let saveFilePath: string; // Ask for the device to make an image