diff --git a/examples/test/a.v b/examples/test/a.v new file mode 100644 index 0000000..2d4e526 --- /dev/null +++ b/examples/test/a.v @@ -0,0 +1,11 @@ +static a; + +restore() { + if(typeof b !== 'object') { + throw new Error('Static instance A does not exist!'); + } else b.fun(); +} + +fun() { + console.log('hello from A'); +} \ No newline at end of file diff --git a/examples/test/b.v b/examples/test/b.v new file mode 100644 index 0000000..8bc7b41 --- /dev/null +++ b/examples/test/b.v @@ -0,0 +1,11 @@ +static b; + +restore() { + if(typeof a !== 'object') { + throw new Error('Static instance A does not exist!'); + } else a.fun(); +} + +fun() { + console.log('hello from B'); +} \ No newline at end of file diff --git a/examples/test/main.v b/examples/test/main.v index cd334cf..4fb31b7 100644 --- a/examples/test/main.v +++ b/examples/test/main.v @@ -1,4 +1,3 @@ -singleton; link counter; link window; diff --git a/package.json b/package.json index 21a01cf..fb3b42d 100644 --- a/package.json +++ b/package.json @@ -12,20 +12,17 @@ }, "scripts": { "dev": "multiview [ yarn test:watch ] [ yarn compile:watch ] [ yarn debug:watch ]", - "test": "c8 --all mocha", + "test": "c8 --include src/**/*.ts --reporter lcov --reporter text mocha", "test:watch": "cross-env FORCE_COLOR=true supervisor -t -w src,test,.mocharc.json -n exit --extensions js,ts,node --exec cross-env -- yarn test", - "debug": "cross-env DEBUG=vogue:* FORCE_COLOR=true DEBUG_COLORS=true DEBUG_HIDE_DATE=true node --enable-source-maps --unhandled-rejections=strict out/run.js examples/test", + "debug": "cross-env DEBUG=vogue:* FORCE_COLOR=true DEBUG_COLORS=true DEBUG_HIDE_DATE=true node --enable-source-maps out/run.js examples/test", "debug:watch": "supervisor -t -w out,test/system/**/*.v,lib -n exit --exec yarn -- debug", "compile": "tsc", "compile:watch": "yarn compile --watch --preserveWatchOutput", "postinstall": "yarn compile && cd examples/test && yarn" }, "devDependencies": { - "c8": "^7.7.2", - "cross-env": "^7.0.3", - "multiview": "^3.0.1", - "yarn": "^1.22.10", "@types/chai": "^4.2.18", + "@types/chai-as-promised": "^7.1.4", "@types/debug": "^4.1.5", "@types/fs-extra": "^9.0.11", "@types/jest": "^26.0.23", @@ -35,20 +32,29 @@ "@types/sinon": "^10.0.0", "@types/uglify-js": "^3.13.0", "@types/uuid": "^8.3.0", + "c8": "^7.7.2", "chai": "^4.3.4", + "chai-as-promised": "^7.1.1", + "cross-env": "^7.0.3", "mocha": "^8.4.0", "mocha-lcov-reporter": "^1.3.0", - "supervisor": "^0.12.0", + "multiview": "^3.0.1", "sinon": "^10.0.0", + "supervisor": "^0.12.0", "ts-node": "^9.1.1", - "typescript": "^4.2.4" + "typescript": "^4.2.4", + "yarn": "^1.22.10" }, "dependencies": { + "@types/rimraf": "^3.0.0", + "@types/tmp": "^0.2.0", "debug": "^4.3.1", "fs-extra": "^10.0.0", "lodash": "^4.17.21", "moo": "^0.5.1", "nearley": "^2.20.1", + "rimraf": "^3.0.2", + "tmp": "^0.2.1", "uglify-js": "^3.13.5", "uuid": "^8.3.2" } diff --git a/src/Instance.ts b/src/Instance.ts index 9ce88dd..e361dff 100644 --- a/src/Instance.ts +++ b/src/Instance.ts @@ -3,7 +3,7 @@ import _ from 'lodash'; const log = debug('vogue:instance'); import vm from 'vm'; import Module, { LinkDescription, Variable } from './Module.js'; -import System from './System.js'; +import { System } from './System.js'; import * as uuid from 'uuid'; /** * @typedef {import('./System.js').default} System @@ -54,9 +54,11 @@ export default class Instance { // TODO request context from system... initialContext.create = this.system.newLink.bind(this.system); initialContext.process = process; - for(const name in this.system.staticLinks) { + + // static links! + for(const [name, link] of this.system.staticLinks) { log('creating context with static link: ' + name); - initialContext[name] = this.system.staticLinks[name]; + initialContext[name] = this.system.staticLinks.get(name); } // local links! @@ -89,9 +91,11 @@ export default class Instance { vm.runInContext(injectedScript, context, {}); } - log('context created! ' + Object.keys(context)); + log('context created!'); + log(Object.keys(context)); // log(context); + this.context = context; return context; }; @@ -107,7 +111,6 @@ export default class Instance { constructor( module: Module, - location: string, parameters: {[name: string]: any}, system: System, options?: { @@ -115,7 +118,7 @@ export default class Instance { } ) { this.module = module; - this.location = location; + this.location = this.module.rootDir; this.system = system; // this.context = this.createContext(); this._id = options?.id ?? uuid.v4(); @@ -124,9 +127,6 @@ export default class Instance { get(target: Instance, prop: string, receiver) { log(`getting ${target.module.name.full}.${prop.toString()}: (${target.module.identifiers[prop]}|${typeof target.context?.[prop]})`); - if(target.context === null) - target.restore(); - const DNEText = `${target.module.name.full}.${prop.toString()} either does not exist, or is not accessible`; if(prop === 'restore') throw new Error(DNEText); if(prop === '__link__') return target._id; @@ -140,11 +140,9 @@ export default class Instance { log('created ' + this); } - restore() { - if(this.context === null) - this.context = this.createContext(); + async restore() { - return this.context?.restore?.(); + return await this.context?.restore?.(); } get link () { diff --git a/src/System.ts b/src/System.ts index b7167e9..788c58e 100644 --- a/src/System.ts +++ b/src/System.ts @@ -5,7 +5,8 @@ import debug from 'debug'; import { lstatSync, readdirSync, readFileSync, writeFileSync } from 'fs'; import { resolve } from 'path'; import { ensureDirSync } from 'fs-extra'; -const log = debug('vogue:system') +import * as uuid from 'uuid'; +const log = debug('vogue:system'); const {get, set} = _; @@ -15,93 +16,157 @@ type ModuleNamespaceMap = { type ModuleName = string; -class System { +export class System { instances: Map = new Map(); + bootInstances: Map = new Map(); + staticInstances: Map = new Map(); + staticLinks: Map = new Map(); + + modules: Module[]; namespace: ModuleNamespaceMap = {}; - staticLinks: { - [key: string]: Link - } = {}; rootDir: string; - constructor(modules: Module[], rootDir: string) { + static async create(modules: Module[], rootDir: string) { + const system = new System(modules, rootDir); + await system.start(); + return system; + } + + async start() { + ensureDirSync(resolve(this.rootDir, '.system')); + + log('System startup, in 5 steps!'); + + // step 1.1: load serialized instances... + log('Step 1.1: reading serialized instances...') + const serializedInstances: SerializedInstance[] = + readdirSync(resolve(this.rootDir, '.system')) + .map(v => resolve(this.rootDir, '.system', v)) + .map(v => JSON.parse(readFileSync(v).toString())); + + // step 1.2: create serialized instances + log('Step 1.2: creating serialized instances...'); + for(const serializedInstance of serializedInstances) + this.createInstance(serializedInstance); + + // TODO again, make links automagically tranform from strings to links when needed at runtime, so this isnt needed... + // step 1.2 addendum: + log('Step 1.2+: linking serialized instances...'); + for(const serializedInstance of serializedInstances) { + const instance = this.getInstanceById(serializedInstance.id); + for(const name in serializedInstance.links) { + const linkId = serializedInstance.links[name] + const linkedInstance = this.getInstanceById(linkId); + const linkedInstanceLink = linkedInstance.link; + instance.setLink(name, linkedInstanceLink); + } + } + + // step 2: validate all modules decalred as static have a static module counterpart + log('Step 2: creating missing static instances...'); + for(const module of this.modules.filter(module => !!module.static)) { + const staticIdentifier = module.static; + const moduleName = module.name.full; + if(!this.staticLinks.has(staticIdentifier)) { + this.createInstance({ + type: moduleName, + links: {}, + members: {}, + id: uuid.v4() + }) + } + } + + // step 3: create missing singleton instances + log('Step 3: creating missing singleton instances...'); + for(const module of this.modules.filter(module => !!module.singleton)) { + let instanceCount = 0; + for(const [,instance] of this.instances) { + if(instance.module.name.full === module.name.full) { + instanceCount ++; + } + } + if(instanceCount === 0) { + this.createInstance({ + type: module.name.full, + links: {}, + members: {}, + id: uuid.v4() + }) + } + } + + // step 4: create context in all instances + log('Step 4: create context in instances...'); + for(const [,instance] of this.instances) { + instance.createContext(); + } + + // step 5: restore all boot modules (static & singleton) + log('Step 5: restore all boot modules...'); + for(const [,instance] of this.bootInstances) { + await instance.restore(); + } + + // log('restoring static instances...'); + // for(const [,instance] of this.instances) { + // if(!!instance.module.static) { + // await instance.restore(); + // } + // } + + // log('restoring boot instances...'); + // for(const [,instance] of this.instances) { + // if(!!instance.module.singleton) { + // await instance.restore(); + // } + // } + + // const bootModules = this.deriveBootModules(); + // this.createStaticInstances(); + + // log('instantiating boot modules...'); + // for(const name of bootModules) { + // log(' ' + name); + // await this.newLink(name); + // } + } + + private constructor(modules: Module[], rootDir: string) { this.rootDir = rootDir; this.modules = modules; this.createNamespace(); - - ensureDirSync(resolve(this.rootDir, '.system')); - - const vault = readdirSync(resolve(this.rootDir, '.system')).map(v => resolve(this.rootDir, '.system', v)); - const serializedInstances: SerializedInstance[] = vault.map((v) => JSON.parse(readFileSync(v).toString())); - - log('injecting serialized instances...'); - for(const serializedInstance of serializedInstances) - this.injectSerializedInstance(serializedInstance); - log('linking serialized instances...'); - for(const serializedInstance of serializedInstances) - this.linkSerializedInstance(serializedInstance); - - log('restoring static instances...'); - for(const [,instance] of this.instances) { - if(!!instance.module.static) { - instance.restore(); - } - } - - log('restoring boot instances...'); - for(const [,instance] of this.instances) { - if(!!instance.module.singleton) { - instance.restore(); - } - } - // this.inject(serializedInstance); - - - if (vault.length !== 0) { - return this; - } - - // TODO future workflow notes - // pull jsons into boots - // filter json boots - // create static / singletons into boots - // boot boots! - - - const bootModules = this.deriveBootModules(); - this.createStaticInstances(); - - log('instantiating boot modules...'); - for(const name of bootModules) { - log(' ' + name); - this.newLink(name); - } } - linkSerializedInstance(serializedInstance: SerializedInstance): void { - const instance = this.getInstanceById(serializedInstance.id); - for(const name in serializedInstance.links) { - const linkId = serializedInstance.links[name] - const linkedInstance = this.getInstanceById(linkId); - const linkedInstanceLink = linkedInstance.link; - instance.setLink(name, linkedInstanceLink); - } - } - - injectSerializedInstance(serializedInstance: SerializedInstance): void { - const instance = new Instance(this.getModule(serializedInstance.type), this.rootDir, {}, this, { + createInstance(serializedInstance: SerializedInstance) { + // create instance + const instance = new Instance(this.getModule(serializedInstance.type), {}, this, { id: serializedInstance.id }); - this.instances.set(instance._id, instance); + // preset members for(const name in serializedInstance.members) { instance.setMember(name, serializedInstance.members[name]); } + // TODO preset links + // TODO consolidate links/members into args + + // add to all isntances + this.instances.set(instance._id, instance); + // if its static, add it to both static instance data structures. if(instance.module.static) { - log('injected static instance ' + instance.module.static + ': ' + instance.module.name.full); - this.staticLinks[instance.module.static] = instance.link; + this.staticLinks.set(instance.module.static, instance.link); + this.staticInstances.set(instance._id, instance); } + + // if it static, or just a singleton, add it to boot modules! + if(instance.module.singleton || instance.module.static) { + this.bootInstances.set(instance._id, instance); + } + + return instance; } getInstanceById(id: string): Instance { @@ -111,23 +176,6 @@ class System { return this.instances.get(id) as Instance; } - createStaticInstances() { - log('deriving static modules...'); - const staticModules = this.modules.filter((module) => { - return !!module.static; - }).map((module) => { - log(' ' + module.name.full); - return module; - }); - - log('instantiating static modules...'); - for(const module of staticModules) { - log(' ' + module.static + ': ' + module.name.full); - this.staticLinks[module.static] = - this.newLink(module.name.full, {}); - } - } - deriveBootModules() { log('deriving boot modules...'); const bootModules = this.modules.filter((module) => { @@ -143,12 +191,10 @@ class System { } createNamespace() { - log('creating namespace map...'); this.namespace = this.modules.reduce((acc, val) => { if(get(acc, val.name.full) instanceof Module) throw new Error('Duplicate module "' + val.name.full + '"'); set(acc, val.name.full, val); - log(' ' + val.name.full); return acc; }, {}); } @@ -164,27 +210,25 @@ class System { } getModule(name: ModuleName): Module { + console.log('GETTING MODULE', name) const module = get(this.namespace, name); if(module instanceof Module) return module; - else throw Error(`${name} is not a module`); + else throw Error(`unknown module ${name}`); } - createInstance(name: ModuleName, args = {}) { - const instance = new Instance(this.getModule(name), this.rootDir, args, this); - this.saveInstance(instance); - return instance; - } - - newLink(name: ModuleName, args = {}) { - const instance = this.createInstance(name, args); - const link = instance.link; - instance.restore(); - return link; + async newLink(name: ModuleName, args = {}) { + const instance = this.createInstance({ + type: name, + links: args, + members: {}, + id: uuid.v4() + }); + instance.createContext(); + await instance.restore(); + return instance.link; } } -export default System; - // class SerializedInstanceInjector { // system: System; // serializedInstances: SerializedInstance[]; diff --git a/src/extensions.ts b/src/extensions.ts index c1422e4..bd3d8ac 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -5,7 +5,10 @@ Object.defineProperty(Array.prototype, 'empty', { } }); -// in theory we dont need this anymore... with strict promise rejections... -// process.on('unhandledRejection', (reason: Error, p) => { -// console.log(reason.stack ?? reason.name + '\n\nStack trace unavailable...'); -// }); \ No newline at end of file +// ignored because there seems to be no good way to test this. +// would love to find one though... +/* c8 ignore start */ +process.on('unhandledRejection', (reason: Error, p) => { + console.log(reason.stack ?? reason.name + '\n\nStack trace unavailable...'); +}); +/* c8 ignore end */ \ No newline at end of file diff --git a/src/minify.ts b/src/minify.ts deleted file mode 100644 index d64f379..0000000 --- a/src/minify.ts +++ /dev/null @@ -1,16 +0,0 @@ - -// import uglify from 'uglify-js'; - -// export default (code: string): string => { -// return uglify.minify(code, { -// compress: { -// dead_code: true, -// global_defs: { -// DEBUG: false -// } -// }, -// sourceMap: { -// content: 'inline' -// } -// }).code; -// } \ No newline at end of file diff --git a/src/run.ts b/src/run.ts index 5de9ebb..190cdcc 100644 --- a/src/run.ts +++ b/src/run.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env node --enable-source-maps --unhandled-rejections=strict +#!/usr/bin/env node --enable-source-maps import debug from 'debug'; const log = debug('vogue:cli'); const systemLocation = resolve(process.argv[2]); @@ -8,7 +8,7 @@ import { readdirSync, lstatSync } from 'fs'; import _ from 'lodash'; import Module from './Module.js'; -import System from './System.js'; +import {System} from './System.js'; import './extensions.js'; import { fileURLToPath } from 'url'; @@ -31,7 +31,7 @@ const standardLibrary = resolve(fileURLToPath(dirname(import.meta.url)), '..', ' log('parsing modules...'); const modules = await Promise.all(fullpaths.map(loc => Module.create(loc, systemLocation))); - const sys = new System(modules, systemLocation); + const sys = await System.create(modules, systemLocation); })(); function walkdirSync(root: string, filter: ((path: string) => boolean) = () => true): string[] { diff --git a/test/extensions.test.ts b/test/extensions.test.ts index 6f193f6..752a873 100644 --- a/test/extensions.test.ts +++ b/test/extensions.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { expect } from './lib/expect.js'; import '../src/extensions.ts'; describe('extensions', () => { diff --git a/test/lexer.test.ts b/test/lexer.test.ts index 98d6805..403a6ad 100644 --- a/test/lexer.test.ts +++ b/test/lexer.test.ts @@ -1,5 +1,5 @@ import { createAst } from '../src/createAst.js'; -import { expect } from 'chai'; +import { expect } from './lib/expect.js'; import * as ModuleFiles from './lib/ModuleFiles.js' describe('Lexer', () => { diff --git a/test/lib/System.ts b/test/lib/System.ts new file mode 100644 index 0000000..3285e74 --- /dev/null +++ b/test/lib/System.ts @@ -0,0 +1,22 @@ +import {System} from '../../src/System.js'; +import * as tmp from 'tmp'; +import { dirname, resolve } from 'path'; +import { fileURLToPath } from 'url'; +import { createAst } from '../../src/createAst.js'; +import { readdirSync } from 'fs'; +import Module from '../../src/Module.js'; + +const systemsPath = resolve(fileURLToPath(dirname(import.meta.url)), '..', 'systems'); + +export async function createSystem(systemName: string) { + const { name: tmpDir } = tmp.dirSync(); + + const modulesPath = resolve(systemsPath, systemName); + const modules = await Promise.all(readdirSync(modulesPath) + .map(v => resolve(modulesPath, v)) + .map(v => Module.create(v, modulesPath))); + + const system = await System.create(modules, tmpDir); + + return system; +} \ No newline at end of file diff --git a/test/lib/expect.ts b/test/lib/expect.ts new file mode 100644 index 0000000..a8f8f7b --- /dev/null +++ b/test/lib/expect.ts @@ -0,0 +1,5 @@ +import * as chai from 'chai'; +import cap from 'chai-as-promised'; + +chai.use(cap); +export const {expect} = chai; \ No newline at end of file diff --git a/test/system.test.ts b/test/system.test.ts new file mode 100644 index 0000000..74f3464 --- /dev/null +++ b/test/system.test.ts @@ -0,0 +1,12 @@ +import { createSystem } from './lib/System.js'; +import { expect } from './lib/expect.js' + +describe('system', () => { + it('cross linked static instances', (done) => { + expect(createSystem('crossStaticLinking')).to.eventually.be.fulfilled.notify(done); + }); + + it('non-existant module retrieval throws', (done) => { + expect(createSystem('unknownModule')).to.eventually.be.rejected.notify(done); + }) +}); \ No newline at end of file diff --git a/test/systems/crossStaticLinking/a.v b/test/systems/crossStaticLinking/a.v new file mode 100644 index 0000000..0d310aa --- /dev/null +++ b/test/systems/crossStaticLinking/a.v @@ -0,0 +1,11 @@ +static a; + +restore() { + if(typeof b !== 'object') { + throw new Error('Static instance A does not exist!'); + } else b.fun(); +} + +fun() { + +} \ No newline at end of file diff --git a/test/systems/crossStaticLinking/b.v b/test/systems/crossStaticLinking/b.v new file mode 100644 index 0000000..0301d00 --- /dev/null +++ b/test/systems/crossStaticLinking/b.v @@ -0,0 +1,11 @@ +static b; + +restore() { + if(typeof a !== 'object') { + throw new Error('Static instance A does not exist!'); + } else a.fun(); +} + +fun() { + +} \ No newline at end of file diff --git a/test/systems/unknownModule/main.v b/test/systems/unknownModule/main.v new file mode 100644 index 0000000..e4c7ec5 --- /dev/null +++ b/test/systems/unknownModule/main.v @@ -0,0 +1,5 @@ +singleton; + +async restore { + await create('this.module.doesnt.exist'); +} \ No newline at end of file diff --git a/test/tsconfig.json b/test/tsconfig.json index 055efbf..45501cb 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,8 +1,9 @@ { "compilerOptions": { - "module": "ES6", + "module": "esnext", "moduleResolution": "node", - "target": "es2020" + "target": "es2020", + "allowSyntheticDefaultImports": true }, "include": [ "**/*.ts" diff --git a/yarn.lock b/yarn.lock index 48b1f2c..df18114 100644 --- a/yarn.lock +++ b/yarn.lock @@ -50,7 +50,13 @@ version "0.7.1" resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" -"@types/chai@^4.2.18": +"@types/chai-as-promised@^7.1.4": + version "7.1.4" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.4.tgz#caf64e76fb056b8c8ced4b761ed499272b737601" + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.2.18": version "4.2.18" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.18.tgz#0c8e298dbff8205e2266606c1ea5fbdba29b46e4" @@ -64,6 +70,13 @@ dependencies: "@types/node" "*" +"@types/glob@*": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" @@ -91,6 +104,10 @@ version "4.14.170" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" +"@types/minimatch@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" + "@types/nearley@^2.11.1": version "2.11.1" resolved "https://registry.yarnpkg.com/@types/nearley/-/nearley-2.11.1.tgz#6ac3f57c00ca28071a1774ec72d2e45750f21420" @@ -99,12 +116,23 @@ version "15.6.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.0.tgz#f0ddca5a61e52627c9dcb771a6039d44694597bc" +"@types/rimraf@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f" + dependencies: + "@types/glob" "*" + "@types/node" "*" + "@types/sinon@^10.0.0": version "10.0.0" resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.0.tgz#eecc3847af03d45ffe53d55aaaaf6ecb28b5e584" dependencies: "@sinonjs/fake-timers" "^7.0.4" +"@types/tmp@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.0.tgz#e3f52b4d7397eaa9193592ef3fdd44dc0af4298c" + "@types/uglify-js@^3.13.0": version "3.13.0" resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.0.tgz#1cad8df1fb0b143c5aba08de5712ea9d1ff71124" @@ -228,6 +256,12 @@ camelcase@^6.0.0: version "6.2.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" +chai-as-promised@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" + dependencies: + check-error "^1.0.2" + chai@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" @@ -859,7 +893,7 @@ ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" -rimraf@^3.0.0: +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" dependencies: @@ -1015,6 +1049,12 @@ through@2: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + dependencies: + rimraf "^3.0.0" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"