From f9738f1d61871461660cabca7935eff9de1f4b2e Mon Sep 17 00:00:00 2001 From: lilsweetcaligula <3748714-lilsweetcaligula@users.noreply.gitlab.com> Date: Fri, 7 May 2021 16:15:34 +0300 Subject: [PATCH 1/9] Bump the version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0cc34c3..9a38499 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "seneca-store-test", - "version": "3.1.0", + "version": "3.2.0", "description": "Standard test cases for seneca stores", "main": "store-test.js", "scripts": { From cb07cfe3fd177a3cfc33d83c12c090deaccca8fb Mon Sep 17 00:00:00 2001 From: lilsweetcaligula <3748714-lilsweetcaligula@users.noreply.gitlab.com> Date: Fri, 7 May 2021 16:42:23 +0300 Subject: [PATCH 2/9] Add tests for the upsertion functionality --- store-test.js | 854 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 854 insertions(+) diff --git a/store-test.js b/store-test.js index 737b2ef..63a2953 100644 --- a/store-test.js +++ b/store-test.js @@ -75,9 +75,18 @@ function clearDb(si) { function clearFoo(next) { si.make('foo').remove$({ all$: true }, next) }, + function clearBar(next) { si.make('zen', 'moon', 'bar').remove$({ all$: true }, next) }, + + function clearUser(next) { + si.make('user').remove$({ all$: true }, next) + }, + + function clearProduct(next) { + si.make('product').remove$({ all$: true }, next) + } ], done ) @@ -1319,6 +1328,850 @@ function limitstest(settings) { return script } +function upserttest(settings) { + Assert('seneca' in settings, 'settings.seneca') + const si = settings.seneca + + const script = settings.script || Lab.script() + + const { describe, before, beforeEach } = script + const it = make_it(script) + + describe('Upserts', () => { + beforeEach(() => new Promise((resolve, _reject) => { + si.ready(resolve) + })) + + beforeEach(clearDb(si)) + + describe('save$ invoked on a new entity instance', () => { + describe('matching entity exists', () => { + describe('matches on 1 upsert$ field', () => { + beforeEach(() => new Promise(fin => { + si.make('user') + .data$({ username: 'richard', points: 0 }) + .save$(fin) + })) + + beforeEach(fin => new Promise(fin => { + si.make('user') + .data$({ username: 'bob', points: 0 }) + .save$(fin) + })) + + it('updates the entity', fin => { + si.test(fin) + + si.ready(() => { + si.make('user') + .data$({ username: 'richard', points: 9999 }) + .save$({ upsert$: ['username'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + + expect(users.length).to.equal(2) + + + expect(users[0]).to.contain({ + username: 'richard', + points: 9999 + }) + + + expect(users[1]).to.contain({ + username: 'bob', + points: 0 + }) + + return fin() + }) + }) + }) + }) + }) + + describe('matches on 2 upsert$ fields', () => { + beforeEach(() => new Promise(fin => { + si.make('user') + .data$({ username: 'richard', skill: 9999, points: 0 }) + .save$(fin) + })) + + beforeEach(() => new Promise(fin => { + si.make('user') + .data$({ username: 'bob', skill: 9999, points: 0 }) + .save$(fin) + })) + + it('updates the entity', fin => { + si.test(fin) + + si.ready(() => { + si.make('user') + .data$({ username: 'richard', skill: 9999, points: 1234 }) + .save$({ upsert$: ['username', 'skill'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + + expect(users.length).to.equal(2) + + + expect(users[0]).to.contain({ + username: 'richard', + skill: 9999, + points: 1234 + }) + + + expect(users[1]).to.contain({ + username: 'bob', + skill: 9999, + points: 0 + }) + + + return fin() + }) + }) + }) + }) + }) + }) + + describe('many matching entities exist', () => { + describe('matches on 1 upsert$ field', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a toothbrush', price: '3.95' }) + .save$(fin) + })) + + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a toothbrush', price: '3.70' }) + .save$(fin) + })) + + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'bbs tires', price: '4.10' }) + .save$(fin) + })) + + it('updates a single matching entity', fin => { + si.test(fin) + + si.ready(() => { + si.make('product') + .data$({ label: 'a toothbrush', price: '4.95' }) + .save$({ upsert$: ['label'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(3) + + expect(products[0]).to.contain({ + label: 'a toothbrush', + price: '4.95' + }) + + expect(products[1]).to.contain({ + label: 'a toothbrush', + price: '3.70' + }) + + expect(products[2]).to.contain({ + label: 'bbs tires', + price: '4.10' + }) + + return fin() + }) + }) + }) + }) + }) + + describe('matches on 2 upsert$ fields', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a toothbrush', price: '3.95', coolness_factor: 2 }) + .save$(fin) + })) + + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a toothbrush', price: '3.70', coolness_factor: 3 }) + .save$(fin) + })) + + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'bbs tires', price: '4.10', coolness_factor: 7 }) + .save$(fin) + })) + + it('updates a single matching entity', fin => { + si.test(fin) + + si.ready(() => { + si.make('product') + .data$({ label: 'a toothbrush', price: '3.95', coolness_factor: 4 }) + .save$({ upsert$: ['label', 'price'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(3) + + expect(products[0]).to.contain({ + label: 'a toothbrush', + price: '3.95', + coolness_factor: 4 + }) + + expect(products[1]).to.contain({ + label: 'a toothbrush', + price: '3.70', + coolness_factor: 3 + }) + + expect(products[2]).to.contain({ + label: 'bbs tires', + price: '4.10', + coolness_factor: 7 + }) + + return fin() + }) + }) + }) + }) + }) + }) + + describe('no matching entity exists', () => { + describe('1 upsert$ field', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a macchiato espressionado', price: '3.40' }) + .save$(fin) + })) + + it('creates a new entity', fin => { + si.test(fin) + + si.make('product') + .data$({ label: 'b toothbrush', price: '3.40' }) + .save$({ upsert$: ['label'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + label: 'a macchiato espressionado', + price: '3.40' + }) + + expect(products[1]).to.contain({ + label: 'b toothbrush', + price: '3.40' + }) + + return fin() + }) + }) + }) + }) + + describe('2 upsert$ fields', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'frapuccino', price: '2.40', coolness_factor: 5 }) + .save$(fin) + })) + + it('creates a new entity', fin => { + si.test(fin) + + si.make('product') + .data$({ label: 'frapuccino', price: '3.40', coolness_factor: 7 }) + .save$({ upsert$: ['label', 'price'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + label: 'frapuccino', + price: '2.40', + coolness_factor: 5 + }) + + expect(products[1]).to.contain({ + label: 'frapuccino', + price: '3.40', + coolness_factor: 7 + }) + + return fin() + }) + }) + }) + }) + + describe('edge cases', () => { + describe('bombarding the store with near-parallel upserts', () => { + describe('1 upsert$ field', () => { + it('does not result in a race condition - creates a single new entity', fin => { + si.test(fin) + + const product_entity = si.entity('product') + + const upsertProduct = cb => + product_entity + .data$({ name: 'pencil', price: '1.95' }) + .save$({ upsert$: ['name'] }, cb) + + + Async.parallel([ + upsertProduct, + upsertProduct, + upsertProduct + ], err => { + if (err) { + return fin(err) + } + + product_entity.list$((err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(1) + + expect(products[0]).to.contain({ + name: 'pencil', + price: '1.95' + }) + + return fin() + }) + }) + + return + }) + }) + }) + }) + }) + + describe('edge cases', () => { + describe('entity matches on a private field', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'toothbrush', price: '3.95', psst$: 'private' }) + .save$(fin) + })) + + it('creates a new entity', fin => { + si.test(fin) + + si.ready(() => { + si.make('product') + .data$({ label: 'a new toothbrush', price: '5.95', psst$: 'private' }) + .save$({ upsert$: ['psst$'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + label: 'toothbrush', + price: '3.95' + }) + + expect(products[1]).to.contain({ + label: 'a new toothbrush', + price: '5.95' + }) + + return fin() + }) + }) + }) + }) + }) + + describe('empty upsert$ array', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'toothbrush', price: '3.95' }) + .save$(fin) + })) + + it('creates a new document', fin => { + si.test(fin) + + si.ready(() => { + si.make('product') + .data$({ label: 'toothbrush', price: '5.95' }) + .save$({ upsert$: [] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + label: 'toothbrush', + price: '3.95' + }) + + expect(products[1]).to.contain({ + label: 'toothbrush', + price: '5.95' + }) + + return fin() + }) + }) + }) + }) + }) + + describe('entity matches on a field with the `undefined` value', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: undefined, price: '3.95' }) + .save$(fin) + })) + + it('creates a new document', fin => { + si.test(fin) + + si.ready(() => { + si.make('product') + .data$({ label: undefined, price: '5.95' }) + .save$({ upsert$: ['label'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + // NOTE: Seneca is stripping out fields + // with a value of `undefined` in a document. + // + // label: undefined, + + price: '3.95' + }) + + expect(products[1]).to.contain({ + // NOTE: Seneca is stripping out fields + // with a value of `undefined` in a document. + // + // label: undefined, + + price: '5.95' + }) + + return fin() + }) + }) + }) + }) + }) + + describe('entity matches on a field with the null value', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: null, price: '3.95' }) + .save$(fin) + })) + + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'CS101 textbook', price: '134.95' }) + .save$(fin) + })) + + it('updates the existing entity', fin => { + si.test(fin) + + si.ready(() => { + si.make('product') + .data$({ label: null, price: '5.95' }) + .save$({ upsert$: ['label'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + label: null, + price: '5.95' + }) + + expect(products[1]).to.contain({ + label: 'CS101 textbook', + price: '134.95' + }) + + return fin() + }) + }) + }) + }) + }) + + describe('some fields in data$/upsert$ are not present in existing entities', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a toothbrush', price: '3.40' }) + .save$(fin) + })) + + it('creates a new entity', fin => { + si.test(fin) + + si.make('product') + .data$({ label: 'a toothbrush', price: '2.95', coolness_factor: '0.95' }) + .save$({ upsert$: ['label', 'coolness_factor'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[1]).to.contain({ + label: 'a toothbrush', + price: '2.95', + coolness_factor: '0.95' + }) + + + return fin() + }) + }) + }) + }) + + describe('fields in upsert$ are not present in the data$ object', () => { + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a toothbrush', price: '3.40' }) + .save$(fin) + })) + + it('creates a new entity because it can never match', fin => { + si.test(fin) + + si.make('product') + .data$({ label: 'a toothbrush', price: '2.95' }) + .save$({ upsert$: ['label', 'coolness_factor'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + label: 'a toothbrush', + price: '3.40' + }) + + expect(products[1]).to.contain({ + label: 'a toothbrush', + price: '2.95' + }) + + return fin() + }) + }) + }) + }) + + describe('upserting on the id field', () => { + describe('matching entity exists', () => { + const id_of_richard = 'some_id' + + beforeEach(() => new Promise(fin => { + si.make('user') + .data$({ id: id_of_richard, username: 'richard', points: 8000 }) + .save$(fin) + })) + + + beforeEach(() => new Promise(fin => { + si.make('user') + .data$({ username: 'bob', points: 1000 }) + .save$(fin) + })) + + it('updates the matching entity', fin => { + si.test(fin) + + si.make('user') + .data$({ id: id_of_richard, username: 'richard', points: 9999 }) + .save$({ upsert$: ['id'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + + expect(users.length).to.equal(2) + + expect(users[0]).to.contain({ + id: id_of_richard, + username: 'richard', + points: 9999 + }) + + expect(users[1]).to.contain({ + username: 'bob', + points: 1000 + }) + + return fin() + }) + }) + }) + + it('works with load$ after the update', fin => { + si.test(fin) + + si.make('user') + .data$({ id: id_of_richard, username: 'richard', points: 9999 }) + .save$({ upsert$: ['id'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').load$(id_of_richard, (err, user) => { + if (err) { + return fin(err) + } + + expect(user).to.contain({ + id: id_of_richard, + username: 'richard', + points: 9999 + }) + + return fin() + }) + }) + }) + }) + + describe('matching entity does not exist', () => { + const some_id = 'some_id' + + beforeEach(() => new Promise(fin => { + si.make('user') + .data$({ username: 'richard' }) + .save$(fin) + })) + + it('creates a new document with that id', fin => { + si.test(fin) + + si.make('user') + .data$({ id: some_id, username: 'jim' }) + .save$({ upsert$: ['id'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + + expect(users.length).to.equal(2) + + expect(users[0]).to.contain({ + username: 'richard' + }) + + expect(users[1]).to.contain({ + id: some_id, + username: 'jim' + }) + + return fin() + }) + }) + }) + + it('works with load$ after the creation', fin => { + si.test(fin) + + si.make('user') + .data$({ id: some_id, username: 'jim' }) + .save$({ upsert$: ['id'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').load$(some_id, (err, user) => { + if (err) { + return fin(err) + } + + expect(user).to.contain({ + id: some_id, + username: 'jim' + }) + + return fin() + }) + }) + }) + }) + }) + }) + }) + + describe('save$ invoked as a method on an existing entity instance', () => { + describe('a matching entity exists', () => { + let existing_product + + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a macchiato espressionado', price: '3.40' }) + .save$((err, new_product) => { + if (err) { + return fin(err) + } + + existing_product = new_product + + return fin() + }) + })) + + + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a macchiato espressionado', price: '7.99' }) + .save$(fin) + })) + + + it('ignores the upsert$ directive and updates the existing entity, as it normally would', fin => { + si.test(fin) + + existing_product + .data$({ label: 'a macchiato espressionado', price: '3.95' }) + .save$({ upsert$: ['label'] }, err => { + if (err) { + return fin(err) + } + + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } + + expect(products.length).to.equal(2) + + expect(products[0]).to.contain({ + label: 'a macchiato espressionado', + price: '3.95' + }) + + expect(products[1]).to.contain({ + label: 'a macchiato espressionado', + price: '7.99' + }) + + return fin() + }) + }) + }) + }) + }) + }) + + return script +} + function sqltest(settings) { var si = settings.seneca var script = settings.script || Lab.script() @@ -1381,6 +2234,7 @@ module.exports = { basictest: basictest, sorttest: sorttest, limitstest: limitstest, + upserttest: upserttest, sqltest: sqltest, extended: ExtendedTests, verify: verify, From 341fbc87f32769d236039d5f332c84790b166da3 Mon Sep 17 00:00:00 2001 From: lilsweetcaligula <3748714-lilsweetcaligula@users.noreply.gitlab.com> Date: Fri, 7 May 2021 16:43:24 +0300 Subject: [PATCH 3/9] gitignore the lockfile --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f31f3f2..7f18441 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ node_modules docs/annotated docs/coverage.html +package-lock.json From 353f8eb48f6007eb0b50dc67a92e8338520676ce Mon Sep 17 00:00:00 2001 From: lilsweetcaligula <3748714-lilsweetcaligula@users.noreply.gitlab.com> Date: Fri, 7 May 2021 16:43:39 +0300 Subject: [PATCH 4/9] Remove the lockfile --- package-lock.json | 2312 --------------------------------------------- 1 file changed, 2312 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 9044d8c..0000000 --- a/package-lock.json +++ /dev/null @@ -1,2312 +0,0 @@ -{ - "name": "seneca-store-test", - "version": "3.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.11.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.6.tgz", - "integrity": "sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA==", - "dev": true, - "requires": { - "@babel/types": "^7.11.5", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", - "dev": true, - "requires": { - "@babel/types": "^7.11.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", - "dev": true - }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/traverse": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.5.tgz", - "integrity": "sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.5", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.5", - "@babel/types": "^7.11.5", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - } - }, - "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "@eslint/eslintrc": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", - "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - } - } - }, - "@hapi/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", - "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/boom": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.0.tgz", - "integrity": "sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==", - "dev": true, - "requires": { - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/bossy": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@hapi/bossy/-/bossy-5.0.1.tgz", - "integrity": "sha512-/HP5KSQ7EGLcnIdmwYj47mKh6f1htos2Dd8QlQjy59k61lENzKgvFbaPa+REQQGGgVQK7QREO55w/Wjkw2dzrQ==", - "dev": true, - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/hoek": "9.x.x", - "@hapi/validate": "1.x.x" - } - }, - "@hapi/bourne": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", - "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==", - "dev": true - }, - "@hapi/code": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@hapi/code/-/code-8.0.2.tgz", - "integrity": "sha512-JG3yfRMU/acl48i14YAwucyf12wtIyyfEJ4PyL/qZxDd3ltjqCVIlZmOSCazxFjtDZTfMx6TLVcDU5XWvP8tNQ==", - "dev": true, - "requires": { - "@hapi/hoek": "9.x.x" - } - }, - "@hapi/eslint-plugin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/eslint-plugin/-/eslint-plugin-5.0.0.tgz", - "integrity": "sha512-a3K7cVhxhcN3NJv+UCFeOS8RO+mFtnpgbtkDIPplOdBQoYEuAUCePooZKJuYu07N5z/QjmsSQz83Xx/hHlfJDA==", - "dev": true - }, - "@hapi/formula": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", - "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==", - "dev": true - }, - "@hapi/hoek": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.0.tgz", - "integrity": "sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw==", - "dev": true - }, - "@hapi/joi": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz", - "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==", - "dev": true, - "requires": { - "@hapi/address": "^4.0.1", - "@hapi/formula": "^2.0.0", - "@hapi/hoek": "^9.0.0", - "@hapi/pinpoint": "^2.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "@hapi/lab": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/@hapi/lab/-/lab-24.0.0.tgz", - "integrity": "sha512-cFlx07vzjX7UJ6c4Wq2C+EZFuOrLHKZhxV4wjKWj8no1DoAghsCysI0+q8SYfexm4AF+PKPIGkluXqMtdVarYg==", - "dev": true, - "requires": { - "@hapi/bossy": "5.x.x", - "@hapi/eslint-plugin": "5.x.x", - "@hapi/hoek": "9.x.x", - "babel-eslint": "10.x.x", - "diff": "4.x.x", - "eslint": "7.x.x", - "find-rc": "4.x.x", - "globby": "10.x.x", - "handlebars": "4.x.x", - "seedrandom": "3.x.x", - "source-map": "0.7.x", - "source-map-support": "0.5.x", - "supports-color": "7.x.x", - "will-call": "1.x.x" - } - }, - "@hapi/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==", - "dev": true - }, - "@hapi/topo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", - "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/validate": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@hapi/validate/-/validate-1.1.2.tgz", - "integrity": "sha512-ojg3iE/haKh8aCZFObkOzuJ1vQ8NP+EiuibliJKe01IMstBPXQc4Xl08+8zqAL+iZSZKp1TaWdwaNSzq8HIMKA==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "@hapi/wreck": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@hapi/wreck/-/wreck-17.0.0.tgz", - "integrity": "sha512-d8lqCinbKyDByn7GzJDRDbitddhIEydNm44UcAMejfhEH3o4IYvKYq6K8cAqXbilXPuvZc0ErlUOg9SDdgRtMw==", - "dev": true, - "requires": { - "@hapi/boom": "9.x.x", - "@hapi/bourne": "2.x.x", - "@hapi/hoek": "9.x.x" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "14.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", - "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==", - "dev": true - }, - "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "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 - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "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 - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "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=", - "dev": true - }, - "aws4": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", - "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==", - "dev": true - }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - } - }, - "backoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", - "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", - "dev": true, - "requires": { - "precond": "0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "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, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - } - }, - "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" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" - }, - "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==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "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 - }, - "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=", - "dev": true - }, - "coveralls": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", - "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", - "dev": true, - "requires": { - "js-yaml": "^3.13.1", - "lcov-parse": "^1.0.0", - "log-driver": "^1.2.7", - "minimist": "^1.2.5", - "request": "^2.88.2" - } - }, - "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, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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==", - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "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, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "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" - } - }, - "eraro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eraro/-/eraro-2.1.0.tgz", - "integrity": "sha512-i8t3tkUixYL6q9gQvTqgkOok8VJCw2mr3/YfATdFcOE2pxw3MUM8Uv4B822zVDPIyIZDKx7jixr24ej3vdul2A==", - "dev": true, - "requires": { - "lodash.template": "^4.5.0" - } - }, - "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=", - "dev": true - }, - "eslint": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.10.0.tgz", - "integrity": "sha512-BDVffmqWl7JJXqCjAK6lWtcQThZB/aP1HXSH1JKwGwv0LQEdvpR7qzNrUT487RM39B5goWuboFad5ovMBmD8yA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.1.3", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^1.3.0", - "espree": "^7.3.0", - "esquery": "^1.2.0", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "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": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "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 - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - } - } - }, - "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, - "requires": { - "esrecurse": "^4.3.0", - "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" - } - }, - "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 - }, - "espree": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", - "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.3.0" - } - }, - "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 - }, - "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", - "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==", - "dev": true - } - } - }, - "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, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "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==", - "dev": true - }, - "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - } - }, - "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==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", - "dev": true - }, - "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "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==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-rc": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/find-rc/-/find-rc-4.0.1.tgz", - "integrity": "sha512-YEox27Ie95/zoqkxm6BYSPguJsvYz9d9G1YuaNKhxjSgZbjMC9q5blmvbL4+Ail8yacQIE0OObhDb+ZwvfJafw==", - "dev": true - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": 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": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gate-executor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gate-executor/-/gate-executor-2.1.0.tgz", - "integrity": "sha512-IpMP2TzkVO/Vh/LmOIzj79O5g5SGAS/66tYZnR35PTfqWrGHbXNLDL1W81fzTTaWQqY/YUnpM9FiXqfJ8p/stw==", - "dev": true - }, - "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=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "gex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gex/-/gex-1.0.0.tgz", - "integrity": "sha512-wEyZcD4WWlL8IMw/ZOhWGfy4X/Q2yFqXZ16Loq/vh3XwsS+42Fm23Jd5ph+3yw9wNzVMmloskBwO3vCL8M7+2Q==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "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" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "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 - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "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 - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "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 - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "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=", - "dev": true - }, - "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 - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "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==", - "dev": true - }, - "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 - }, - "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=", - "dev": true - }, - "jsonic": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/jsonic/-/jsonic-0.3.1.tgz", - "integrity": "sha512-5Md4EK3vPAMvP2sXY6M3/vQEPeX3LxEQBJuF979uypddXjsUlEoAI9/Nojh8tbw+YU5FjMoqSElO6oyjrAuprw==", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "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 - }, - "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, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.defaultsdeep": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", - "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.foreach": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", - "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", - "dev": true - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isdate": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isdate/-/lodash.isdate-4.0.1.tgz", - "integrity": "sha1-NaVDZzuddhEN5BFLMsxXcEin82Y=", - "dev": true - }, - "lodash.isnan": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isnan/-/lodash.isnan-3.0.2.tgz", - "integrity": "sha1-gu0Epfnqi9YibQwmrwysMvRQd0U=", - "dev": true - }, - "lodash.isregexp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isregexp/-/lodash.isregexp-4.0.1.tgz", - "integrity": "sha1-4T5kezDNVZdSoEzZEghvr32hwws=", - "dev": true - }, - "lodash.omit": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true - }, - "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dev": true, - "requires": { - "mime-db": "1.44.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "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 - }, - "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 - }, - "ndjson": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-1.5.0.tgz", - "integrity": "sha1-rmA7NrE0vOw0e0UkIrC/mNWDLsg=", - "dev": true, - "requires": { - "json-stringify-safe": "^5.0.1", - "minimist": "^1.2.0", - "split2": "^2.1.0", - "through2": "^2.0.3" - } - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nid": { - "version": "1.3.3", - "resolved": "http://localhost:4873/nid/-/nid-1.3.3.tgz", - "integrity": "sha512-D4icLe9or1K4gsH8CQ2gfnRJECRlq63oNq5LNADMVmyPQqMhtHQIE3LE8bXDbQRYR8yzwoo0stG1m2pL5kr3aA==" - }, - "norma": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/norma/-/norma-2.0.2.tgz", - "integrity": "sha512-dpZEilsy4GuVX3E1/L/7xAFDsv5V7vopP/wOF/yxnw4Qy7vkEQZjL0lEv9nM7BMX0QZNOauL/oHAtZ10BUOTIA==", - "dev": true, - "requires": { - "eraro": "^2.0.0", - "lodash.isarguments": "^3.1.0", - "lodash.isdate": "^4.0.1", - "lodash.isnan": "^3.0.2", - "lodash.isregexp": "^4.0.1" - } - }, - "nua": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nua/-/nua-1.0.2.tgz", - "integrity": "sha512-M94zvCWqflfJ38ziwbIHKISUUdU3nOdrRY5L2LCan/inAbTJm2O+ajHNNajKaeDFLPVhi+6wx9nGv2ectGEIGg==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "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" - } - }, - "optioner": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/optioner/-/optioner-5.0.1.tgz", - "integrity": "sha512-WrR6M1H5JnK9lI/0TUDtSdqTwTSLOno4EZR4dC/NAJIz1Z8HePbo37eJqlrx8KP4YpB6lhrtl621gRPuOhgoLQ==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.3", - "@hapi/joi": "^17.1.0" - } - }, - "ordu": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/ordu/-/ordu-1.7.1.tgz", - "integrity": "sha512-qn2Uf9qHOJoxBfjc0rl7IDKn5I8EDS5hy+YeXzTrtbMe6QfK8kFelD19xUZdcAPHoODbiGOpp3kotUmTGi5VCQ==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.4", - "nua": "^1.0.2", - "strict-event-emitter-types": "^2.0.0" - } - }, - "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, - "requires": { - "callsites": "^3.0.0" - } - }, - "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 - }, - "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 - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "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 - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" - }, - "patrun": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/patrun/-/patrun-4.0.0.tgz", - "integrity": "sha512-T+YuxuG7IKvOi4276DBNAFaAOEdeY5qjRs3sQ0owM45SFVFz14DTAjfE9J4Q/aUHlTw638/1B8k7tBo/dWTb3A==", - "dev": true, - "requires": { - "gex": "^1.0.0" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "precond": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=", - "dev": true - }, - "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 - }, - "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==", - "dev": true - }, - "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", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "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==", - "dev": true - } - } - }, - "reconnect-core": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/reconnect-core/-/reconnect-core-1.3.0.tgz", - "integrity": "sha1-+65SkZp4d9hE4yRtAaLyZwHIM8g=", - "dev": true, - "requires": { - "backoff": "~2.5.0" - } - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "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 - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rolling-stats": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/rolling-stats/-/rolling-stats-0.1.1.tgz", - "integrity": "sha1-zVr3dKiJOzCmdIMvovSrqkeM/IA=", - "dev": true - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "seedrandom": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", - "dev": true - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "seneca": { - "version": "3.22.0", - "resolved": "https://registry.npmjs.org/seneca/-/seneca-3.22.0.tgz", - "integrity": "sha512-QsqkCJugJIJE77l1vNR3xEEegCmS5po23s6jnfTKCa9hq+7ZKwP4j3TLkihB/p4zMblk55CsXx5axONp5Ujzsw==", - "dev": true, - "requires": { - "@hapi/joi": "^17.1.1", - "@hapi/wreck": "^17.0.0", - "eraro": "^2.1.0", - "fast-safe-stringify": "^2.0.7", - "gate-executor": "^2.1.0", - "gex": "^1.0.0", - "jsonic": "^0.3.1", - "lodash.defaultsdeep": "^4.6.1", - "lodash.flatten": "^4.4.0", - "lodash.uniq": "^4.5.0", - "minimist": "^1.2.5", - "nid": "^1.1.0", - "norma": "^2.0.2", - "optioner": "^5.0.1", - "ordu": "^1.7.1", - "patrun": "^4.0.0", - "qs": "^6.9.4", - "rolling-stats": "^0.1.1", - "seneca-transport": "^6.0.0", - "use-plugin": "^8.2.0" - }, - "dependencies": { - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", - "dev": true - } - } - }, - "seneca-entity": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/seneca-entity/-/seneca-entity-10.1.0.tgz", - "integrity": "sha512-Q7yglj/+gK+aztmtRRXcVFPhepBFXiYAL2z6fp8LBvAnI95e/wEGZ9r/A132pPNBlomGumZUQHYfvzjsj7qapA==", - "dev": true, - "requires": { - "eraro": "^2.1.0", - "jsonic": "^1.0.1", - "nid": "^1.3.3", - "seneca-mem-store": "^3.0.1" - }, - "dependencies": { - "jsonic": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsonic/-/jsonic-1.0.1.tgz", - "integrity": "sha512-6GitEN4plTuB/I1o9kDZl7Pgc+DvFG1BG88IqaUz4eQglCA1uAgxWdXhLNA6ffaYsmzPjOysDpp6CYTwRiuXLw==", - "dev": true - }, - "seneca-mem-store": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/seneca-mem-store/-/seneca-mem-store-3.0.1.tgz", - "integrity": "sha512-4ocd0amgzT+F4iHTSc3LnAqQym6RtldPUEmKgMcAEqfqPvsImF/rVPObgfDnE0wVL117Z0IGa8yKlAnILClCzw==", - "dev": true - } - } - }, - "seneca-mem-store": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/seneca-mem-store/-/seneca-mem-store-4.0.0.tgz", - "integrity": "sha512-qK2n6rvuKmpyO4CEVYML8N0RszfV47yECgwEa89+f86t/r+q5aCbSBzF6TS/51AuZIIvgLEZydhI7Q1v8rHrAw==", - "dev": true - }, - "seneca-transport": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/seneca-transport/-/seneca-transport-6.0.0.tgz", - "integrity": "sha512-5x+Z9uwhpHysbmo+/Cifw0jmwowaEpn5KYPm7HLkHKBQDUdspPnI3084PbSLYfSPZADg8uy8XMvv093kbw1Kiw==", - "dev": true, - "requires": { - "@hapi/wreck": "^17.0.0", - "eraro": "^2.1.0", - "gex": "^1.0.0", - "jsonic": "^0.3.1", - "lodash.foreach": "^4.5.0", - "lodash.omit": "^4.5.0", - "lru-cache": "^5.1.1", - "ndjson": "^1.5.0", - "nid": "^1.1.0", - "patrun": "^3.0.0", - "qs": "^6.9.4", - "reconnect-core": "^1.3.0" - }, - "dependencies": { - "patrun": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/patrun/-/patrun-3.0.0.tgz", - "integrity": "sha512-fQ++l3FCnrQbO03wEjb2SFn+ixGXscS8948A4js0qDTBsod0eElYUDvuWCH4mV61V/7QN2lCtryRvoyBP0K/7g==", - "dev": true, - "requires": { - "gex": "^1.0.0" - } - }, - "qs": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", - "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", - "dev": true - } - } - }, - "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, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "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 - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", - "dev": true, - "requires": { - "through2": "^2.0.2" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "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" - } - }, - "strict-event-emitter-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", - "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "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==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "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==", - "dev": true - } - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "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 - }, - "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, - "requires": { - "has-flag": "^4.0.0" - }, - "dependencies": { - "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 - } - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - } - }, - "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 - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "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 - }, - "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==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "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, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "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==" - }, - "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 - }, - "uglify-js": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.4.tgz", - "integrity": "sha512-kBFT3U4Dcj4/pJ52vfjCSfyLyvG9VYYuGYPmrPvAxRw/i7xHiT4VvCev+uiEMcEEiu6UNB6KgWmGtSUYIWScbw==", - "dev": true, - "optional": true - }, - "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "use-plugin": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/use-plugin/-/use-plugin-8.2.0.tgz", - "integrity": "sha512-mISoqGU0ouiSn2QY3k8a88yPqgDilOMpVjXBswMVNibz1MmIzgtxNVRtFwsb30rNvfvl5ZGu44JQtP/gY4/1Bw==", - "dev": true, - "requires": { - "eraro": "^2.1.0", - "nid": "^1.1.0", - "norma": "^2.0.2", - "optioner": "^5.0.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "will-call": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/will-call/-/will-call-1.0.1.tgz", - "integrity": "sha512-1hEeV8SfBYhNRc/bNXeQfyUBX8Dl9SCYME3qXh99iZP9wJcnhnlBsoBw8Y0lXVZ3YuPsoxImTzBiol1ouNR/hg==", - "dev": true - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } -} From 400c306c8d33971d14c32d2ec64d33ff1b3fc06d Mon Sep 17 00:00:00 2001 From: lilsweetcaligula <3748714-lilsweetcaligula@users.noreply.gitlab.com> Date: Fri, 7 May 2021 16:43:53 +0300 Subject: [PATCH 5/9] Freeze the mem-store version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a38499..dba5363 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,6 @@ "coveralls": "^3.1.0", "seneca": "plugin", "seneca-entity": "^10.1.0", - "seneca-mem-store": "^4.0.0" + "seneca-mem-store": "5.0.0" } } From fe704bcc052d723fbf334b2fe48d96ed02ed1f2e Mon Sep 17 00:00:00 2001 From: lilsweetcaligula Date: Fri, 7 May 2021 18:51:54 +0300 Subject: [PATCH 6/9] Add extra tests --- lib/common.js | 7 +++++++ store-test.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 lib/common.js diff --git a/lib/common.js b/lib/common.js new file mode 100644 index 0000000..dce1ff2 --- /dev/null +++ b/lib/common.js @@ -0,0 +1,7 @@ +exports.fetchProp = function (o, prop) { + if (!(prop in o)) { + throw new Error(`Missing property: ${prop}`) + } + + return o[prop] +} diff --git a/store-test.js b/store-test.js index 63a2953..d37e46d 100644 --- a/store-test.js +++ b/store-test.js @@ -10,6 +10,7 @@ const Code = require('@hapi/code') const Nid = require('nid') var ExtendedTests = require('./lib/store-test-extended') +const { fetchProp } = require('./lib/common') const expect = Code.expect @@ -1347,16 +1348,45 @@ function upserttest(settings) { describe('save$ invoked on a new entity instance', () => { describe('matching entity exists', () => { describe('matches on 1 upsert$ field', () => { + let id_of_richard + beforeEach(() => new Promise(fin => { si.make('user') .data$({ username: 'richard', points: 0 }) - .save$(fin) + .save$((err, user) => { + if (err) { + return fin(err) + } + + try { + id_of_richard = fetchProp(user, 'id') + + return fin() + } catch (err) { + return fin(err) + } + }) })) + + let id_of_bob + beforeEach(fin => new Promise(fin => { si.make('user') .data$({ username: 'bob', points: 0 }) - .save$(fin) + .save$((err, user) => { + if (err) { + return fin(err) + } + + try { + id_of_bob = fetchProp(user, 'id') + + return fin() + } catch (err) { + return fin(err) + } + }) })) it('updates the entity', fin => { @@ -1379,12 +1409,14 @@ function upserttest(settings) { expect(users[0]).to.contain({ + id: id_of_richard, username: 'richard', points: 9999 }) expect(users[1]).to.contain({ + id: id_of_bob, username: 'bob', points: 0 }) @@ -1575,12 +1607,27 @@ function upserttest(settings) { describe('no matching entity exists', () => { describe('1 upsert$ field', () => { + let id_of_macchiato + beforeEach(() => new Promise(fin => { si.make('product') .data$({ label: 'a macchiato espressionado', price: '3.40' }) - .save$(fin) + .save$((err, product) => { + if (err) { + return fin(err) + } + + try { + id_of_macchiato = fetchProp(product, 'id') + + return fin() + } catch (err) { + return fin(err) + } + }) })) + it('creates a new entity', fin => { si.test(fin) @@ -1599,6 +1646,7 @@ function upserttest(settings) { expect(products.length).to.equal(2) expect(products[0]).to.contain({ + id: id_of_macchiato, label: 'a macchiato espressionado', price: '3.40' }) @@ -1608,6 +1656,8 @@ function upserttest(settings) { price: '3.40' }) + expect(products[1].id).not.to.equal(id_of_macchiato) + return fin() }) }) From 9765463716b7a4ddc48954acb3bd2bde64ac7c59 Mon Sep 17 00:00:00 2001 From: lilsweetcaligula Date: Sat, 8 May 2021 10:10:06 +0300 Subject: [PATCH 7/9] Add extra tests to make sure that an update is done and not complete replacement --- store-test.js | 185 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 135 insertions(+), 50 deletions(-) diff --git a/store-test.js b/store-test.js index d37e46d..a91ea4d 100644 --- a/store-test.js +++ b/store-test.js @@ -1348,82 +1348,167 @@ function upserttest(settings) { describe('save$ invoked on a new entity instance', () => { describe('matching entity exists', () => { describe('matches on 1 upsert$ field', () => { - let id_of_richard + describe('all entity fields are also present in data$', () => { + let id_of_richard - beforeEach(() => new Promise(fin => { - si.make('user') - .data$({ username: 'richard', points: 0 }) - .save$((err, user) => { - if (err) { - return fin(err) - } + beforeEach(() => new Promise(fin => { + si.make('user') + .data$({ username: 'richard', points: 0 }) + .save$((err, user) => { + if (err) { + return fin(err) + } - try { - id_of_richard = fetchProp(user, 'id') + try { + id_of_richard = fetchProp(user, 'id') - return fin() - } catch (err) { - return fin(err) - } - }) - })) + return fin() + } catch (err) { + return fin(err) + } + }) + })) - let id_of_bob + let id_of_bob - beforeEach(fin => new Promise(fin => { - si.make('user') - .data$({ username: 'bob', points: 0 }) - .save$((err, user) => { - if (err) { - return fin(err) - } + beforeEach(fin => new Promise(fin => { + si.make('user') + .data$({ username: 'bob', points: 0 }) + .save$((err, user) => { + if (err) { + return fin(err) + } - try { - id_of_bob = fetchProp(user, 'id') + try { + id_of_bob = fetchProp(user, 'id') - return fin() - } catch (err) { - return fin(err) - } + return fin() + } catch (err) { + return fin(err) + } + }) + })) + + it('updates the entity', fin => { + si.test(fin) + + si.ready(() => { + si.make('user') + .data$({ username: 'richard', points: 9999 }) + .save$({ upsert$: ['username'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + + expect(users.length).to.equal(2) + + + expect(users[0]).to.contain({ + id: id_of_richard, + username: 'richard', + points: 9999 + }) + + + expect(users[1]).to.contain({ + id: id_of_bob, + username: 'bob', + points: 0 + }) + + return fin() + }) + }) }) - })) + }) + }) - it('updates the entity', fin => { - si.test(fin) + describe('some entity fields are missing from data$', () => { + let id_of_richard - si.ready(() => { + beforeEach(() => new Promise(fin => { si.make('user') - .data$({ username: 'richard', points: 9999 }) - .save$({ upsert$: ['username'] }, err => { + .data$({ username: 'richard', points: 37, favorite_car: 'land rover' }) + .save$((err, user) => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + try { + id_of_richard = fetchProp(user, 'id') + + return fin() + } catch (err) { + return fin(err) + } + }) + })) + + + let id_of_bob + + beforeEach(fin => new Promise(fin => { + si.make('user') + .data$({ username: 'bob', points: 20, favorite_car: 'peugeot 307' }) + .save$((err, user) => { + if (err) { + return fin(err) + } + + try { + id_of_bob = fetchProp(user, 'id') + + return fin() + } catch (err) { + return fin(err) + } + }) + })) + + it('retains the entity fields missing from data$', fin => { + si.test(fin) + + si.ready(() => { + si.make('user') + .data$({ username: 'richard', favorite_car: 'bmw m3 e46' }) + .save$({ upsert$: ['username'] }, err => { if (err) { return fin(err) } - expect(users.length).to.equal(2) + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + expect(users.length).to.equal(2) - expect(users[0]).to.contain({ - id: id_of_richard, - username: 'richard', - points: 9999 - }) + expect(users[0]).to.contain({ + id: id_of_richard, + username: 'richard', + points: 37, + favorite_car: 'bmw m3 e46' + }) - expect(users[1]).to.contain({ - id: id_of_bob, - username: 'bob', - points: 0 - }) - return fin() + expect(users[1]).to.contain({ + id: id_of_bob, + username: 'bob', + points: 20, + favorite_car: 'peugeot 307' + }) + + return fin() + }) }) - }) + }) }) }) }) From eb610163253bf502ed93f9c5c3d047d8c66c1581 Mon Sep 17 00:00:00 2001 From: lilsweetcaligula Date: Mon, 10 May 2021 19:42:06 +0300 Subject: [PATCH 8/9] Add more tests for the id$ qualifier in save$ when upserting --- store-test.js | 191 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 152 insertions(+), 39 deletions(-) diff --git a/store-test.js b/store-test.js index a91ea4d..fce9a31 100644 --- a/store-test.js +++ b/store-test.js @@ -1335,7 +1335,7 @@ function upserttest(settings) { const script = settings.script || Lab.script() - const { describe, before, beforeEach } = script + const { describe, before, beforeEach, afterEach } = script const it = make_it(script) describe('Upserts', () => { @@ -1511,6 +1511,82 @@ function upserttest(settings) { }) }) }) + + describe('the save$ query includes the id$ field', () => { + beforeEach(clearDb) + + + let target_user_id + + beforeEach(() => new Promise((resolve, reject) => { + si.make('user') + .data$({ first_name: 'Elvis', last_name: 'Presley' }) + .save$((err, user) => { + if (err) { + return reject(err) + } + + Assert.ok(user, 'user') + target_user_id = fetchProp(user, 'id') + + return resolve() + }) + })) + + + let target_user + + beforeEach(() => new Promise((resolve, reject) => { + // Do a fresh fetch from the db. + // + si.make('user') + .load$(target_user_id, (err, user) => { + if (err) { + return reject(err) + } + + Assert.ok(user, 'user') + target_user = user + + return resolve() + }) + })) + + + afterEach(clearDb) + + it('updates the fields and ignores the id$ qualifier', fin => { + si.test(fin) + + + const new_id = 'bbbba6f73a861890cc1f4e23' + + si.make('user') + .data$({ first_name: 'Elvis', last_name: 'PRESLEY' }) + .save$({ id$: new_id, upsert$: ['first_name'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + + expect(users.length).to.equal(1) + + expect(users[0]).to.contain({ + first_name: 'Elvis', + last_name: 'PRESLEY' + }) + + expect(users[0].id).not.to.equal(new_id) + + return fin() + }) + }) + }) + }) }) describe('matches on 2 upsert$ fields', () => { @@ -1692,60 +1768,97 @@ function upserttest(settings) { describe('no matching entity exists', () => { describe('1 upsert$ field', () => { - let id_of_macchiato - - beforeEach(() => new Promise(fin => { - si.make('product') - .data$({ label: 'a macchiato espressionado', price: '3.40' }) - .save$((err, product) => { - if (err) { - return fin(err) - } + describe('normally', () => { + let id_of_macchiato - try { - id_of_macchiato = fetchProp(product, 'id') + beforeEach(() => new Promise(fin => { + si.make('product') + .data$({ label: 'a macchiato espressionado', price: '3.40' }) + .save$((err, product) => { + if (err) { + return fin(err) + } - return fin() - } catch (err) { - return fin(err) - } - }) - })) + try { + id_of_macchiato = fetchProp(product, 'id') + return fin() + } catch (err) { + return fin(err) + } + }) + })) - it('creates a new entity', fin => { - si.test(fin) - si.make('product') - .data$({ label: 'b toothbrush', price: '3.40' }) - .save$({ upsert$: ['label'] }, err => { - if (err) { - return fin(err) - } + it('creates a new entity', fin => { + si.test(fin) - si.make('product').list$({}, (err, products) => { + si.make('product') + .data$({ label: 'b toothbrush', price: '3.40' }) + .save$({ upsert$: ['label'] }, err => { if (err) { return fin(err) } - expect(products.length).to.equal(2) + si.make('product').list$({}, (err, products) => { + if (err) { + return fin(err) + } - expect(products[0]).to.contain({ - id: id_of_macchiato, - label: 'a macchiato espressionado', - price: '3.40' - }) + expect(products.length).to.equal(2) - expect(products[1]).to.contain({ - label: 'b toothbrush', - price: '3.40' + expect(products[0]).to.contain({ + id: id_of_macchiato, + label: 'a macchiato espressionado', + price: '3.40' + }) + + expect(products[1]).to.contain({ + label: 'b toothbrush', + price: '3.40' + }) + + expect(products[1].id).not.to.equal(id_of_macchiato) + + return fin() }) + }) + }) + }) - expect(products[1].id).not.to.equal(id_of_macchiato) + describe('the save$ query includes the id$ field', () => { + beforeEach(clearDb) - return fin() + afterEach(clearDb) + + it('creates a new entity with the given id', fin => { + si.test(fin) + + + const new_id = '6095a6f73a861890cc1f4e23' + + si.make('user') + .data$({ first_name: 'Frank', last_name: 'Sinatra' }) + .save$({ id$: new_id, upsert$: ['first_name'] }, err => { + if (err) { + return fin(err) + } + + si.make('user').list$({}, (err, users) => { + if (err) { + return fin(err) + } + + expect(users.length).to.equal(1) + + const user = users[0] + + expect(user.id).to.equal(new_id) + + return fin() + }) }) - }) + }) }) }) From 4dc3f36315d51808d4acf0eb2af89d89dff56b5b Mon Sep 17 00:00:00 2001 From: lilsweetcaligula Date: Mon, 10 May 2021 20:10:54 +0300 Subject: [PATCH 9/9] Pluralize the entity names to avoid potential db conflicts --- store-test.js | 140 +++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/store-test.js b/store-test.js index fce9a31..4856938 100644 --- a/store-test.js +++ b/store-test.js @@ -82,11 +82,11 @@ function clearDb(si) { }, function clearUser(next) { - si.make('user').remove$({ all$: true }, next) + si.make('users').remove$({ all$: true }, next) }, function clearProduct(next) { - si.make('product').remove$({ all$: true }, next) + si.make('products').remove$({ all$: true }, next) } ], done @@ -1352,7 +1352,7 @@ function upserttest(settings) { let id_of_richard beforeEach(() => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'richard', points: 0 }) .save$((err, user) => { if (err) { @@ -1373,7 +1373,7 @@ function upserttest(settings) { let id_of_bob beforeEach(fin => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'bob', points: 0 }) .save$((err, user) => { if (err) { @@ -1394,14 +1394,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('user') + si.make('users') .data$({ username: 'richard', points: 9999 }) .save$({ upsert$: ['username'] }, err => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + si.make('users').list$({}, (err, users) => { if (err) { return fin(err) } @@ -1433,7 +1433,7 @@ function upserttest(settings) { let id_of_richard beforeEach(() => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'richard', points: 37, favorite_car: 'land rover' }) .save$((err, user) => { if (err) { @@ -1454,7 +1454,7 @@ function upserttest(settings) { let id_of_bob beforeEach(fin => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'bob', points: 20, favorite_car: 'peugeot 307' }) .save$((err, user) => { if (err) { @@ -1475,14 +1475,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('user') + si.make('users') .data$({ username: 'richard', favorite_car: 'bmw m3 e46' }) .save$({ upsert$: ['username'] }, err => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + si.make('users').list$({}, (err, users) => { if (err) { return fin(err) } @@ -1519,7 +1519,7 @@ function upserttest(settings) { let target_user_id beforeEach(() => new Promise((resolve, reject) => { - si.make('user') + si.make('users') .data$({ first_name: 'Elvis', last_name: 'Presley' }) .save$((err, user) => { if (err) { @@ -1539,7 +1539,7 @@ function upserttest(settings) { beforeEach(() => new Promise((resolve, reject) => { // Do a fresh fetch from the db. // - si.make('user') + si.make('users') .load$(target_user_id, (err, user) => { if (err) { return reject(err) @@ -1561,14 +1561,14 @@ function upserttest(settings) { const new_id = 'bbbba6f73a861890cc1f4e23' - si.make('user') + si.make('users') .data$({ first_name: 'Elvis', last_name: 'PRESLEY' }) .save$({ id$: new_id, upsert$: ['first_name'] }, err => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + si.make('users').list$({}, (err, users) => { if (err) { return fin(err) } @@ -1591,13 +1591,13 @@ function upserttest(settings) { describe('matches on 2 upsert$ fields', () => { beforeEach(() => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'richard', skill: 9999, points: 0 }) .save$(fin) })) beforeEach(() => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'bob', skill: 9999, points: 0 }) .save$(fin) })) @@ -1606,14 +1606,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('user') + si.make('users') .data$({ username: 'richard', skill: 9999, points: 1234 }) .save$({ upsert$: ['username', 'skill'] }, err => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + si.make('users').list$({}, (err, users) => { if (err) { return fin(err) } @@ -1646,19 +1646,19 @@ function upserttest(settings) { describe('many matching entities exist', () => { describe('matches on 1 upsert$ field', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '3.95' }) .save$(fin) })) beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '3.70' }) .save$(fin) })) beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'bbs tires', price: '4.10' }) .save$(fin) })) @@ -1667,14 +1667,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '4.95' }) .save$({ upsert$: ['label'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -1705,19 +1705,19 @@ function upserttest(settings) { describe('matches on 2 upsert$ fields', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '3.95', coolness_factor: 2 }) .save$(fin) })) beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '3.70', coolness_factor: 3 }) .save$(fin) })) beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'bbs tires', price: '4.10', coolness_factor: 7 }) .save$(fin) })) @@ -1726,14 +1726,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '3.95', coolness_factor: 4 }) .save$({ upsert$: ['label', 'price'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -1772,7 +1772,7 @@ function upserttest(settings) { let id_of_macchiato beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a macchiato espressionado', price: '3.40' }) .save$((err, product) => { if (err) { @@ -1793,14 +1793,14 @@ function upserttest(settings) { it('creates a new entity', fin => { si.test(fin) - si.make('product') + si.make('products') .data$({ label: 'b toothbrush', price: '3.40' }) .save$({ upsert$: ['label'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -1837,14 +1837,14 @@ function upserttest(settings) { const new_id = '6095a6f73a861890cc1f4e23' - si.make('user') + si.make('users') .data$({ first_name: 'Frank', last_name: 'Sinatra' }) .save$({ id$: new_id, upsert$: ['first_name'] }, err => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + si.make('users').list$({}, (err, users) => { if (err) { return fin(err) } @@ -1864,7 +1864,7 @@ function upserttest(settings) { describe('2 upsert$ fields', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'frapuccino', price: '2.40', coolness_factor: 5 }) .save$(fin) })) @@ -1872,14 +1872,14 @@ function upserttest(settings) { it('creates a new entity', fin => { si.test(fin) - si.make('product') + si.make('products') .data$({ label: 'frapuccino', price: '3.40', coolness_factor: 7 }) .save$({ upsert$: ['label', 'price'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -1953,7 +1953,7 @@ function upserttest(settings) { describe('edge cases', () => { describe('entity matches on a private field', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'toothbrush', price: '3.95', psst$: 'private' }) .save$(fin) })) @@ -1962,14 +1962,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('product') + si.make('products') .data$({ label: 'a new toothbrush', price: '5.95', psst$: 'private' }) .save$({ upsert$: ['psst$'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -1995,7 +1995,7 @@ function upserttest(settings) { describe('empty upsert$ array', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'toothbrush', price: '3.95' }) .save$(fin) })) @@ -2004,14 +2004,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('product') + si.make('products') .data$({ label: 'toothbrush', price: '5.95' }) .save$({ upsert$: [] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -2037,7 +2037,7 @@ function upserttest(settings) { describe('entity matches on a field with the `undefined` value', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: undefined, price: '3.95' }) .save$(fin) })) @@ -2046,14 +2046,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('product') + si.make('products') .data$({ label: undefined, price: '5.95' }) .save$({ upsert$: ['label'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -2087,13 +2087,13 @@ function upserttest(settings) { describe('entity matches on a field with the null value', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: null, price: '3.95' }) .save$(fin) })) beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'CS101 textbook', price: '134.95' }) .save$(fin) })) @@ -2102,14 +2102,14 @@ function upserttest(settings) { si.test(fin) si.ready(() => { - si.make('product') + si.make('products') .data$({ label: null, price: '5.95' }) .save$({ upsert$: ['label'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -2135,7 +2135,7 @@ function upserttest(settings) { describe('some fields in data$/upsert$ are not present in existing entities', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '3.40' }) .save$(fin) })) @@ -2143,14 +2143,14 @@ function upserttest(settings) { it('creates a new entity', fin => { si.test(fin) - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '2.95', coolness_factor: '0.95' }) .save$({ upsert$: ['label', 'coolness_factor'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -2172,7 +2172,7 @@ function upserttest(settings) { describe('fields in upsert$ are not present in the data$ object', () => { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '3.40' }) .save$(fin) })) @@ -2180,14 +2180,14 @@ function upserttest(settings) { it('creates a new entity because it can never match', fin => { si.test(fin) - si.make('product') + si.make('products') .data$({ label: 'a toothbrush', price: '2.95' }) .save$({ upsert$: ['label', 'coolness_factor'] }, err => { if (err) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -2215,14 +2215,14 @@ function upserttest(settings) { const id_of_richard = 'some_id' beforeEach(() => new Promise(fin => { - si.make('user') + si.make('users') .data$({ id: id_of_richard, username: 'richard', points: 8000 }) .save$(fin) })) beforeEach(() => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'bob', points: 1000 }) .save$(fin) })) @@ -2230,14 +2230,14 @@ function upserttest(settings) { it('updates the matching entity', fin => { si.test(fin) - si.make('user') + si.make('users') .data$({ id: id_of_richard, username: 'richard', points: 9999 }) .save$({ upsert$: ['id'] }, err => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + si.make('users').list$({}, (err, users) => { if (err) { return fin(err) } @@ -2263,14 +2263,14 @@ function upserttest(settings) { it('works with load$ after the update', fin => { si.test(fin) - si.make('user') + si.make('users') .data$({ id: id_of_richard, username: 'richard', points: 9999 }) .save$({ upsert$: ['id'] }, err => { if (err) { return fin(err) } - si.make('user').load$(id_of_richard, (err, user) => { + si.make('users').load$(id_of_richard, (err, user) => { if (err) { return fin(err) } @@ -2291,7 +2291,7 @@ function upserttest(settings) { const some_id = 'some_id' beforeEach(() => new Promise(fin => { - si.make('user') + si.make('users') .data$({ username: 'richard' }) .save$(fin) })) @@ -2299,14 +2299,14 @@ function upserttest(settings) { it('creates a new document with that id', fin => { si.test(fin) - si.make('user') + si.make('users') .data$({ id: some_id, username: 'jim' }) .save$({ upsert$: ['id'] }, err => { if (err) { return fin(err) } - si.make('user').list$({}, (err, users) => { + si.make('users').list$({}, (err, users) => { if (err) { return fin(err) } @@ -2330,14 +2330,14 @@ function upserttest(settings) { it('works with load$ after the creation', fin => { si.test(fin) - si.make('user') + si.make('users') .data$({ id: some_id, username: 'jim' }) .save$({ upsert$: ['id'] }, err => { if (err) { return fin(err) } - si.make('user').load$(some_id, (err, user) => { + si.make('users').load$(some_id, (err, user) => { if (err) { return fin(err) } @@ -2361,7 +2361,7 @@ function upserttest(settings) { let existing_product beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a macchiato espressionado', price: '3.40' }) .save$((err, new_product) => { if (err) { @@ -2376,7 +2376,7 @@ function upserttest(settings) { beforeEach(() => new Promise(fin => { - si.make('product') + si.make('products') .data$({ label: 'a macchiato espressionado', price: '7.99' }) .save$(fin) })) @@ -2392,7 +2392,7 @@ function upserttest(settings) { return fin(err) } - si.make('product').list$({}, (err, products) => { + si.make('products').list$({}, (err, products) => { if (err) { return fin(err) } @@ -2428,7 +2428,7 @@ function sqltest(settings) { var before = script.before var it = make_it(script) - var Product = si.make('product') + var Product = si.make('products') describe('Sql support', function () { before(function before(done) { before(clearDb(si))