diff --git a/OnJsonAttribute.js b/OnJsonAttribute.js new file mode 100644 index 0000000..34dba7a --- /dev/null +++ b/OnJsonAttribute.js @@ -0,0 +1,313 @@ +const {DataObjectState} = require('./types'); +const {eachSeries} = require('async'); +const {DataConfigurationStrategy} = require('./data-configuration'); +const {DataError} = require('@themost/common'); + + +function edmTypeToJsonType(edmType) { + switch (edmType) { + case 'Edm.String': + return 'string'; + case 'Edm.Boolean': + return 'boolean'; + case 'Edm.Byte': + case 'Edm.SByte': + case 'Edm.Int16': + case 'Edm.Int32': + case 'Edm.Int64': + return 'integer'; + case 'Edm.Decimal': + case 'Edm.Double': + return 'number'; + case 'Edm.DateTime': + case 'Edm.EdmDateTimeOffset': + case 'Edm.Duration': + return 'string'; + case 'Edm.Guid': + return 'string'; + case 'Edm.Binary': + case 'Edm.Stream': + return 'string'; + default: + return 'string'; + } +} + +class OnJsonAttribute { + + /** + * @param {import('./data-model').DataModel} model + */ + static getJsonSchema(model) { + const { context } = model; + const {dataTypes} = context.getConfiguration().getStrategy(DataConfigurationStrategy); + const additionalProperties = false; + const properties = model.attributes.reduce((prev, attr) => { + /** + * @type {{edmtype: string,type:string}} + */ + const dataType = attr.type !== 'Json' ? dataTypes[attr.type] : null; + let type = 'object'; + let assign = {}; + if (dataType != null) { + type = edmTypeToJsonType(dataType.edmtype); + assign = { + [attr.name]: { + type + } + } + } else { + // try to get related model + let relatedModel = attr.additionalType != null ? context.model(attr.additionalType) : context.model(attr.type); + // if related model exists + if (relatedModel) { + // get json schema for related model + assign = { + [attr.name]: Object.assign(OnJsonAttribute.getJsonSchema(relatedModel), { + type + }) + } + } else { + // if related model does not exist + assign = { + [attr.name]: { + type + } + }; + } + } + // set property + Object.assign(prev, assign); + return prev; + }, {}); + const required = model.attributes.filter((attr) => { + const primary = attr.primary === true; + const many = attr.many === true; + return attr.nullable === false && many === false && primary === false; + }).map((attr) => attr.name); + return { + properties, + required, + additionalProperties + } + } + + /** + * @param {import('./data-model').DataModel} model + * @returns {Array} + */ + static getJsonAttributes(model) { + return model.attributes.filter((attr) => { + return attr.type === 'Json' && attr.additionalType != null; + }); + } + + /** + * @param {import('./types').DataEventArgs} event + * @param {function(err?:Error)} callback + * @returns {Promise | Promise} + */ + beforeSave(event, callback) { + try { + // get json attributes if any + const attributes= event.model.attributes.filter((attr) => { + const editable = attr.editable !== false; + const insertable = attr.insertable !== false; + const include = event.state === DataObjectState.Insert ? insertable : editable; + return include && attr.type === 'Json' && attr.additionalType != null && attr.model === event.model.name; + }).filter((attr) => { + return Object.prototype.hasOwnProperty.call(event.target, attr.name); + }); + // exit if there are no json attributes + if (attributes.length === 0) { + return callback(); + } + // iterate over json attributes + void eachSeries(attributes, (attr, cb) => { + // get attribute name + const {name} = attr; + const {[name]: value} = event.target; + if (value == null) { + return cb(); + } + try { + const targetModel = event.model.context.model(attr.additionalType); + if (targetModel == null) { + return cb(new DataError('ERR_INVALID_MODEL', 'Property additional type cannot be determined.', 'The target model cannot be found.', event.model.name, attr.name)); + } + // execute beforeSave event + // this operation will add calculated values and validate the object against the current state of the model + void targetModel.emit('before.save', { + target: value, + state: event.state, + model: targetModel + }, (err) => { + if (err) { + return cb(err); + } + // get object properties + const properties = Object.getOwnPropertyNames(value); + // get target model attributes + const attributes = targetModel.attributeNames; + // check if all properties are defined in the target model + const additionalProperty = properties.find((prop) => attributes.indexOf(prop) < 0); + if (additionalProperty != null) { + return cb(new DataError('ERR_INVALID_PROPERTY', `The given structured value seems to be invalid. The property '${additionalProperty}' is not defined in the target model.`, null, event.model.name, attr.name)); + } + return cb(); + }); + + } catch(err) { + return cb(err); + } + }, (err) => { + if (err) { + return callback(err); + } + return callback(); + }); + } catch (err) { + return callback(err); + } + } + + /** + * @protected + * @param {{model: DataModel, result: any, emitter?: import('./data-queryable').DataQueryable}} event + * @param {function(err?:Error): void} callback + * @returns void + */ + static afterSelect(event, callback) { + const jsonAttributes = event.model.attributes.filter((attr) => { + return attr.type === 'Json' && attr.additionalType != null; + }).map((attr) => { + return attr.name + }); + if (jsonAttributes.length === 0) { + return callback(); + } + let select = []; + const { viewAdapter: entity } = event.model; + if (event.emitter && event.emitter.query && event.emitter.query.$select) { + const querySelect = event.emitter.query.$select[entity] || []; + select.push(...querySelect); + } + let attributes = select.reduce((prev, element) => { + // if select element is a typical query field with $name property + if (element && typeof element.$name === 'string') { + // split $name property by dot + const matches = element.$name.split('.'); + // if there are more than one parts + if (matches && matches.length > 1) { + // get last part + if (jsonAttributes.indexOf(matches[1]) >= 0) { + prev.push(matches.pop()); + } + } + } else { + // try to get first property which should be attribute alias + const [key] = Object.keys(element); + if (Object.hasOwnProperty.call(element, key)) { + /** + * @type {{$jsonGet?: any[]}} + */ + const selectField = element[key]; + // if select field has $jsonGet property + if (selectField.$jsonGet) { + const [jsonGet] = selectField.$jsonGet; + // if jsonGet has $name property + if (jsonGet && typeof jsonGet.$name === 'string') { + // split $name property by dot + const matches = jsonGet.$name.split('.'); + if (matches && matches.length > 1) { + let index = 1; + let nextModel = event.model; + // iterate over matches + while(index < matches.length) { + let attribute = nextModel.getAttribute(matches[index]); + if (attribute && attribute.type === 'Json') { + // get next model + nextModel = event.model.context.model(attribute.additionalType) + // if this is the last match + if (index + 1 === matches.length) { + // add attribute + prev.push(matches[index]); + // and exit + break; + } + } else { + break; + } + index++; + } + } + } + } + } + } + return prev + }, []); + if (select.length === 0) { + attributes = jsonAttributes; + } + if (attributes.length === 0) { + return callback(); + } + // define json converter + const parseJson = (item) => { + attributes.forEach((name) => { + if (Object.prototype.hasOwnProperty.call(item, name)) { + const value = item[name]; + if (typeof value === 'string') { + item[name] = JSON.parse(value); + } + } + }); + }; + // iterate over result + const {result} = event; + if (result == null) { + return callback(); + } + if (Array.isArray(result)) { + result.forEach((item) => parseJson(item)); + } else { + // or parse json for single item + parseJson(result) + } + return callback(); + } + + /** + * @param {import('./types').DataEventArgs} event + * @param {function(err?:Error): void} callback + * @returns void + */ + afterSave(event, callback) { + return OnJsonAttribute.afterSelect({ + model: event.model, + result: event.target + }, callback); + } + + /** + * @param {import('./types').DataEventArgs} event + * @param {function(err?:Error): void} callback + * @returns void + */ + afterExecute(event, callback) { + try { + if (event.emitter && event.emitter.query && event.emitter.query.$select && event.result) { + return OnJsonAttribute.afterSelect(event, callback); + } + return callback(); + } catch (err) { + return callback(err); + } + } + +} + +module.exports = { + OnJsonAttribute +} \ No newline at end of file diff --git a/data-attribute-resolver.js b/data-attribute-resolver.js index 0f32fb6..1e11a2f 100644 --- a/data-attribute-resolver.js +++ b/data-attribute-resolver.js @@ -28,7 +28,7 @@ DataAttributeResolver.prototype.orderByNestedAttribute = function(attr) { return new DataAttributeResolver().resolveNestedAttribute.call(this, attr); }; -DataAttributeResolver.prototype.selecteNestedAttribute = function(attr, alias) { +DataAttributeResolver.prototype.selectNestedAttribute = function(attr, alias) { var expr = new DataAttributeResolver().resolveNestedAttribute.call(this, attr); if (expr) { if (_.isNil(alias)) @@ -47,7 +47,7 @@ DataAttributeResolver.prototype.selecteNestedAttribute = function(attr, alias) { DataAttributeResolver.prototype.selectAggregatedAttribute = function(aggregation, attribute, alias) { var self=this, result; if (new DataAttributeResolver().testNestedAttribute(attribute)) { - result = new DataAttributeResolver().selecteNestedAttribute.call(self,attribute, alias); + result = new DataAttributeResolver().selectNestedAttribute.call(self,attribute, alias); } else { result = self.fieldOf(attribute); @@ -91,35 +91,39 @@ DataAttributeResolver.prototype.resolveNestedAttribute = function(attr) { expr = new DataAttributeResolver().resolveNestedAttributeJoin.call(self.model, memberExpr); // if expr.$select is an instance of Expression then return it // important note: this operation is very important in cases where a json object is selected - if (expr && expr.$select instanceof Expression) { - return expr.$select; - } - //select field - if (member.length>2) { - if (memberExpr.name !== attr) { - // get member segments again because they have been modified - member = memberExpr.name.split('/'); - } - select = QueryField.select(member[member.length-1]).from(member[member.length-2]); - } - else { - if (memberExpr.name !== attr) { - // get member segments again because they have been modified - member = memberExpr.name.split('/'); + if (expr && expr.$select && Object.prototype.hasOwnProperty.call(expr.$select, '$value')) { + var {$value} = expr.$select; + select = new QueryField({ + $value + }); + } else { + //select field + if (member.length>2) { + if (memberExpr.name !== attr) { + // get member segments again because they have been modified + member = memberExpr.name.split('/'); + } + select = QueryField.select(member[member.length-1]).from(member[member.length-2]); } - // if attribute has been resolved by the previous attribute resolver (for join) - // use the returned value which is also a query field expression - // - // important note: this operation is very important in cases where - // we are trying to select or filter zero-or-one associated items that are - // defined by an association of type junction (a typical many-to-many association) - // e.g. $select=orderedItem/madeId as madeInCountry&$filter=orderedItem/madeId ne null - // where Product.madeId is a zero-or-one associated country with a product - if (expr && expr.$select) { - select = expr.$select; - } else { - // otherwise build query field expression - select = QueryField.select(member[1]).from(member[0]); + else { + if (memberExpr.name !== attr) { + // get member segments again because they have been modified + member = memberExpr.name.split('/'); + } + // if attribute has been resolved by the previous attribute resolver (for join) + // use the returned value which is also a query field expression + // + // important note: this operation is very important in cases where + // we are trying to select or filter zero-or-one associated items that are + // defined by an association of type junction (a typical many-to-many association) + // e.g. $select=orderedItem/madeId as madeInCountry&$filter=orderedItem/madeId ne null + // where Product.madeId is a zero-or-one associated country with a product + if (expr && expr.$select) { + select = expr.$select; + } else { + // otherwise build query field expression + select = QueryField.select(member[1]).from(member[0]); + } } } } @@ -191,7 +195,9 @@ DataAttributeResolver.prototype.resolveNestedAttributeJoin = function(memberExpr new MemberExpression(collection + '.' + objectPath) ]); return { - $select: objectGet, + $select: new QueryField({ + $value: objectGet.exprOf() + }), $expand: [] } } diff --git a/data-model-filter.parser.js b/data-model-filter.parser.js index d987c29..c222422 100644 --- a/data-model-filter.parser.js +++ b/data-model-filter.parser.js @@ -1,5 +1,5 @@ const { AsyncSeriesEventEmitter } = require('@themost/events'); -const { OpenDataParser } = require('@themost/query'); +const { OpenDataParser, Expression } = require('@themost/query'); const { DataAttributeResolver } = require('./data-attribute-resolver'); const { DataFilterResolver } = require('./data-filter-resolver'); @@ -55,7 +55,10 @@ class DataModelFilterParser { } else { expr = DataAttributeResolver.prototype.resolveNestedAttributeJoin.call(thisModel, member); - if (expr.$select) { + if (expr && expr.$select instanceof Expression) { + // // use it as select expression after converting it to query field + return cb(null, expr.$select); + } else if (expr.$select) { member = expr.$select.$name.replace(/\./g,'/'); } } diff --git a/data-model.js b/data-model.js index a185c26..c1350ce 100644 --- a/data-model.js +++ b/data-model.js @@ -4,7 +4,7 @@ var {sprintf} = require('sprintf-js'); var Symbol = require('symbol'); var pluralize = require('pluralize'); var async = require('async'); -var {QueryUtils, Expression} = require('@themost/query'); +var {QueryUtils, MethodCallExpression} = require('@themost/query'); var {OpenDataParser} = require('@themost/query'); var types = require('./types'); var {DataAssociationMapping} = require('./types'); @@ -38,6 +38,8 @@ var {hasOwnProperty} = require('./has-own-property'); var { SyncSeriesEventEmitter } = require('@themost/events'); require('@themost/promise-sequence'); var DataObjectState = types.DataObjectState; +var { OnJsonAttribute } = require('./OnJsonAttribute'); +var { isObjectDeep } = require('./is-object'); /** * @this DataModel * @param {DataField} field @@ -640,7 +642,10 @@ function unregisterContextListeners() { //migration listeners this.on('after.upgrade',DataModelCreateViewListener.prototype.afterUpgrade); this.on('after.upgrade',DataModelSeedListener.prototype.afterUpgrade); - + // json listener + this.on('after.save', OnJsonAttribute.prototype.afterSave); + this.on('after.execute', OnJsonAttribute.prototype.afterExecute); + this.on('before.save', OnJsonAttribute.prototype.beforeSave); //get module loader /** * @type {ModuleLoader|*} @@ -786,12 +791,23 @@ function filterInternal(params, callback) { } else { expr = DataAttributeResolver.prototype.resolveNestedAttributeJoin.call(self, member); - if (expr.$select) { - if (expr.$select instanceof Expression) { - member = expr.$select; + // get member expression + if (expr && expr.$select && Object.prototype.hasOwnProperty.call(expr.$select, '$value')) { + // get value + var {$value} = expr.$select; + // get first property + var [property] = Object.keys($value); + // check if property starts with $ (e.g. $concat, $jsonGet etc) + if (property && property.startsWith('$')) { + // get arguments + var {[property]: args} = $value; + // create method call expression + member = new MethodCallExpression(property.substring(1), args); } else { - member = expr.$select.$name.replace(/\./g, '/'); + return cb(new Error('Invalid member expression. Expected a method call expression.')); } + } else if (expr && expr.$select) { + member = expr.$select.$name.replace(/\./g, '/'); } } if (expr && expr.$expand) { @@ -1556,10 +1572,14 @@ function cast_(obj, state) { mapping = superModel.inferMapping(name); } } - if (_.isNil(mapping)) { - result[x.name] = obj[name]; - } - else if (mapping.associationType==='association') { + if (mapping == null) { + var {[name]: value} = obj; + if (x.type === 'Json') { + result[x.name] = isObjectDeep(value) ? JSON.stringify(value) : null; + } else { + result[x.name] = value; + } + } else if (mapping.associationType==='association') { if (typeof obj[name] === 'object' && obj[name] !== null) //set associated key value (e.g. primary key value) result[x.name] = obj[name][mapping.parentField]; diff --git a/data-pluralize.d.ts b/data-pluralize.d.ts new file mode 100644 index 0000000..e4ce093 --- /dev/null +++ b/data-pluralize.d.ts @@ -0,0 +1 @@ +export declare function setSingularRules(pluralize: any): void; \ No newline at end of file diff --git a/data-pluralize.js b/data-pluralize.js new file mode 100644 index 0000000..7ba75d6 --- /dev/null +++ b/data-pluralize.js @@ -0,0 +1,20 @@ + +const singularRules = [ + [ + /data$/, + 'data' + ] +] + +/** + * @param {*} pluralize + */ +function setSingularRules(pluralize) { + singularRules.forEach(rule => { + pluralize.addSingularRule(rule[0], rule[1]) + }); +} + +export { + setSingularRules +} \ No newline at end of file diff --git a/data-queryable.js b/data-queryable.js index 624fc4c..1b36b44 100644 --- a/data-queryable.js +++ b/data-queryable.js @@ -820,7 +820,7 @@ function select_(arg) { else { a = DataAttributeResolver.prototype.testNestedAttribute.call(self,arg); if (a) { - return DataAttributeResolver.prototype.selecteNestedAttribute.call(self, a.name, a.property); + return DataAttributeResolver.prototype.selectNestedAttribute.call(self, a.name, a.property); } else { a = DataAttributeResolver.prototype.testAttribute.call(self,arg); @@ -910,7 +910,7 @@ DataQueryable.prototype.select = function(attr) { else { b = DataAttributeResolver.prototype.testNestedAttribute.call(self,name); if (b) { - expr = DataAttributeResolver.prototype.selecteNestedAttribute.call(self, b.name, x.property); + expr = DataAttributeResolver.prototype.selectNestedAttribute.call(self, b.name, x.property); if (expr) { arr.push(expr); } } else { diff --git a/data-value-resolver.js b/data-value-resolver.js index 834ecb7..2ca5564 100644 --- a/data-value-resolver.js +++ b/data-value-resolver.js @@ -1,6 +1,7 @@ const {DataAttributeResolver} = require('./data-attribute-resolver'); const {isObjectDeep} = require('./is-object'); const {sprintf} = require('sprintf-js'); +var {Expression} = require('@themost/query'); /** * @class DataValueResolver @@ -30,6 +31,11 @@ DataValueResolver.prototype.resolve = function(value) { } } } + // if value is an instance of Expression e.g. an instance if MemberExpression + if (value instanceof Expression) { + // return the expression + return value; + } if (isObjectDeep(value)) { // try to get in-process left operand // noinspection JSUnresolvedReference diff --git a/dataTypes.json b/dataTypes.json index 7be1a9b..16cb4e3 100644 --- a/dataTypes.json +++ b/dataTypes.json @@ -421,5 +421,17 @@ "type": "string", "sqltype":"Text", "version":"1.0" + }, + "Json": { + "comment": "A string which represents a JSON object.", + "label": "Json", + "supertypes": [ + "Text" + ], + "url": "https://www.json.org/json-en.html", + "edmtype": "Edm.String", + "type": "string", + "sqltype":"Text", + "version":"1.0" } } \ No newline at end of file diff --git a/jest.setup.js b/jest.setup.js index c999f93..842812b 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -3,4 +3,4 @@ const JestLogger = require('./jest.logger'); // noinspection JSCheckFunctionSignatures TraceUtils.useLogger(new JestLogger()); /* global jest */ -jest.setTimeout(30000); +jest.setTimeout(60000); diff --git a/model-schema.json b/model-schema.json index 7b0a5bd..f867131 100644 --- a/model-schema.json +++ b/model-schema.json @@ -9,7 +9,7 @@ "Time", "URL", "Language", "Model", "Guid", "Object", "NegativeInteger", "NegativeNumber", "NonNegativeInteger", "NonNegativeNumber", "NonPositiveInteger", "NonPositiveNumber", "PositiveInteger", - "PositiveNumber", "Email", "AbsoluteURI", "RelativeURI" + "PositiveNumber", "Email", "AbsoluteURI", "RelativeURI", "Json" ] }, "unknownTypes": { @@ -178,6 +178,10 @@ "type": "boolean", "description": "A boolean which indicates whether this attribute defines an association between two models where child objects are always treated as a part of the parent object." }, + "additionalType": { + "type": "string", + "description": "A string which represents the additional type of this property e.g. Person, Order etc. This attribute is used for properties marked as \"Json\" where a specific type should be defined for validating entities." + }, "mapping": { "type": "object", "properties": { diff --git a/package-lock.json b/package-lock.json index 228da0c..21a888b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@themost/data", - "version": "2.16.1", + "version": "2.17.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@themost/data", - "version": "2.16.1", + "version": "2.17.0", "license": "BSD-3-Clause", "dependencies": { "@themost/events": "^1.0.5", @@ -27,7 +27,7 @@ "@themost/common": "^2.10.4", "@themost/peers": "^1.0.2", "@themost/query": "^2.14.7", - "@themost/sqlite": "^2.6.16", + "@themost/sqlite": "^2.8.4", "@themost/xml": "^2.5.2", "@types/core-js": "^2.5.0", "@types/jest": "^27.4.1", @@ -2806,41 +2806,6 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dev": true, - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2888,14 +2853,11 @@ } }, "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -2976,7 +2938,6 @@ "resolved": "https://registry.npmjs.org/@themost/query/-/query-2.14.7.tgz", "integrity": "sha512-VpW6ad64IRVHk+wY+FINbppblushOGIOb9TCwcNfr930o82IjTMhbOkGnIM2hx3x68T3iWoK0YiGaZxegAfWkg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@themost/events": "^1.0.5", "async": "^3.2.3", @@ -2995,14 +2956,16 @@ "dev": true }, "node_modules/@themost/sqlite": { - "version": "2.6.16", - "resolved": "https://registry.npmjs.org/@themost/sqlite/-/sqlite-2.6.16.tgz", - "integrity": "sha512-6Mgj7516YC9+IINGCgBl9IpIMXVO+ZRWYKsrA/PdTo2cs1yYYgaoYNVifO42PZionW+WRMYETVAJuPKpEYhG2A==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/@themost/sqlite/-/sqlite-2.8.4.tgz", + "integrity": "sha512-pmkf18CUqnJ1dqZwVdCZtS9LU9xsgVvKitjuTh9xX0Ym2L02iBTPWcPx7uemZCwUOaXi9cw5mikdpi2pPsMIlA==", "dev": true, + "hasInstallScript": true, "dependencies": { "async": "^2.6.4", "sprintf-js": "^1.1.2", - "sqlite3": "^5.1.6" + "sqlite3": "^5.1.7", + "unzipper": "^0.12.3" }, "engines": { "node": ">=12" @@ -3201,7 +3164,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "dev": true, + "optional": true }, "node_modules/acorn": { "version": "8.8.0", @@ -3363,20 +3327,22 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true + "dev": true, + "optional": true }, "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", "deprecated": "This package is no longer supported.", "dev": true, + "optional": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/arg": { @@ -3630,6 +3596,52 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/blueimp-md5": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", @@ -3701,6 +3713,30 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3737,19 +3773,6 @@ "node": ">= 10" } }, - "node_modules/cacache/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -3907,6 +3930,7 @@ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, + "optional": true, "bin": { "color-support": "bin.js" } @@ -3933,7 +3957,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true + "dev": true, + "optional": true }, "node_modules/convert-source-map": { "version": "1.8.0", @@ -3957,6 +3982,12 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -3964,9 +3995,9 @@ "dev": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -4038,12 +4069,36 @@ "integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==", "dev": true }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4088,12 +4143,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true + "dev": true, + "optional": true }, "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "dev": true, "engines": { "node": ">=8" @@ -4181,6 +4237,39 @@ "node": ">=12" } }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.270", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz", @@ -4228,6 +4317,15 @@ "node": ">=0.10.0" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -4765,6 +4863,15 @@ "node": ">= 0.8.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/expect": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", @@ -4856,6 +4963,12 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4917,28 +5030,45 @@ "node": ">= 6" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, "dependencies": { - "minipass": "^3.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">= 8" + "node": ">=14.14" } }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, "node_modules/fs.realpath": { @@ -4968,24 +5098,24 @@ "dev": true }, "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "deprecated": "This package is no longer supported.", "dev": true, + "optional": true, "dependencies": { "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", + "signal-exit": "^3.0.7", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" + "wide-align": "^1.1.5" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/gensync": { @@ -5041,6 +5171,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5164,7 +5300,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true + "dev": true, + "optional": true }, "node_modules/hashmap": { "version": "2.4.0", @@ -5258,6 +5395,26 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -5345,6 +5502,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", @@ -5456,6 +5619,12 @@ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -7355,6 +7524,27 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -7485,19 +7675,6 @@ "node": ">= 10" } }, - "node_modules/make-fetch-happen/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -7566,23 +7743,47 @@ "node": ">=6" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { "node": ">=8" } @@ -7600,19 +7801,6 @@ "node": ">= 8" } }, - "node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-fetch": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", @@ -7631,19 +7819,6 @@ "encoding": "^0.1.12" } }, - "node_modules/minipass-fetch/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", @@ -7657,19 +7832,6 @@ "node": ">= 8" } }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", @@ -7683,19 +7845,6 @@ "node": ">=8" } }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minipass-sized": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", @@ -7709,19 +7858,6 @@ "node": ">=8" } }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", @@ -7735,18 +7871,6 @@ "node": ">= 8" } }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -7759,6 +7883,12 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "node_modules/module-alias": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", @@ -7779,6 +7909,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "dev": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -7786,73 +7922,55 @@ "dev": true }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "dev": true, "optional": true, "engines": { "node": ">= 0.6" } }, - "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "dev": true - }, - "node_modules/node-cache": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", - "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", - "license": "MIT", + "node_modules/node-abi": { + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", + "dev": true, "dependencies": { - "clone": "2.x" + "semver": "^7.3.5" }, "engines": { - "node": ">= 8.0.0" + "node": ">=10" } }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "node_modules/node-abi/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "node": ">=10" } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, + "node_modules/node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "license": "MIT", "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "clone": "2.x" + }, + "engines": { + "node": ">= 8.0.0" } }, "node_modules/node-gyp": { @@ -7880,68 +7998,12 @@ "node": ">= 10.12.0" } }, - "node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "optional": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "optional": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/node-gyp/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -7966,6 +8028,7 @@ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "dev": true, + "optional": true, "dependencies": { "abbrev": "1" }, @@ -7998,16 +8061,20 @@ } }, "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", "deprecated": "This package is no longer supported.", "dev": true, + "optional": true, "dependencies": { - "are-we-there-yet": "^2.0.0", + "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", + "gauge": "^4.0.3", "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/nwsapi": { @@ -8016,15 +8083,6 @@ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -8325,6 +8383,32 @@ "node": ">=4" } }, + "node_modules/prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8360,6 +8444,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -8400,6 +8490,16 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -8445,6 +8545,30 @@ } ] }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -8721,7 +8845,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "dev": true, + "optional": true }, "node_modules/shebang-command": { "version": "2.0.0", @@ -8750,6 +8875,51 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -8837,14 +9007,15 @@ "dev": true }, "node_modules/sqlite3": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz", - "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", + "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", "dev": true, "hasInstallScript": true, "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "node-addon-api": "^4.2.0", + "bindings": "^1.5.0", + "node-addon-api": "^7.0.0", + "prebuild-install": "^7.1.1", "tar": "^6.1.11" }, "optionalDependencies": { @@ -8872,19 +9043,6 @@ "node": ">= 8" } }, - "node_modules/ssri/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/stack-utils": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", @@ -9090,6 +9248,49 @@ "node": ">=10" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -9212,6 +9413,18 @@ "typescript": ">=2.7" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9336,6 +9549,19 @@ "node": ">= 4.0.0" } }, + "node_modules/unzipper": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.3.tgz", + "integrity": "sha512-PZ8hTS+AqcGxsaQntl3IRBw65QrBI6lxzqDEL7IAo/XCEqRTKGfOX56Vea5TH9SZczRVxuzk1re04z/YjuYCJA==", + "dev": true, + "dependencies": { + "bluebird": "~3.7.2", + "duplexer2": "~0.1.4", + "fs-extra": "^11.2.0", + "graceful-fs": "^4.2.2", + "node-int64": "^0.4.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", @@ -9499,6 +9725,7 @@ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "dev": true, + "optional": true, "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } diff --git a/package.json b/package.json index 4b14267..1ef2bf3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@themost/data", - "version": "2.16.1", + "version": "2.17.0", "description": "MOST Web Framework Codename Blueshift - Data module", "main": "index.js", "scripts": { @@ -44,7 +44,7 @@ "@themost/common": "^2.10.4", "@themost/peers": "^1.0.2", "@themost/query": "^2.14.7", - "@themost/sqlite": "^2.6.16", + "@themost/sqlite": "^2.8.4", "@themost/xml": "^2.5.2", "@types/core-js": "^2.5.0", "@types/jest": "^27.4.1", diff --git a/spec/JsonAttribute.spec.ts b/spec/JsonAttribute.spec.ts new file mode 100644 index 0000000..34b6554 --- /dev/null +++ b/spec/JsonAttribute.spec.ts @@ -0,0 +1,153 @@ +import {TestApplication2} from './TestApplication'; +import {DataContext} from '../types'; +import { TestUtils } from "./adapter/TestUtils"; + +describe('JsonAttribute', () => { + + let app: TestApplication2; + let context: DataContext; + beforeAll((done) => { + app = new TestApplication2(); + context = app.createContext(); + return done(); + }); + afterAll(async () => { + await context.finalizeAsync(); + await app.finalize(); + }); + + it('should select json attribute', async () => { + const Products = context.model('Product').silent(); + const items = await Products.asQueryable().select( + 'id', 'name', 'metadata/color as color' + ).take(10).getItems(); + expect(items).toBeTruthy(); + expect(items.length).toBeGreaterThan(0); + }); + + it('should update json attribute', async () => { + await TestUtils.executeInTransaction(context, async () => { + const Products = context.model('Product').silent(); + let item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem() + expect(item).toBeTruthy(); + item.metadata = { + color: 'silver' + } + await Products.save(item); + expect(item.dateCreated).toBeTruthy(); + item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)') + .select('metadata/color as color','metadata/dateCreated as dateCreated').getItem(); + expect(item).toBeTruthy(); + expect(item.color).toBe('silver'); + expect(item.dateCreated).toBeTruthy(); + item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem(); + expect(item).toBeTruthy(); + expect(item.metadata).toBeTruthy(); + }); + }); + + it('should update json structured value', async () => { + await TestUtils.executeInTransaction(context, async () => { + const Products = context.model('Product').silent(); + let item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem() + expect(item).toBeTruthy(); + item.metadata = { + color: 'silver', + audience: { + name: 'New customers', + description: 'New customers who have never purchased before', + audienceType: 'B2C', + geographicArea: 'Worldwide' + } + } + await Products.save(item); + item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem(); + expect(item).toBeTruthy(); + expect(item.metadata).toBeTruthy(); + expect(item.metadata.audience).toBeTruthy(); + item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)') + .select('metadata/audience/name as audienceName').getItem(); + expect(item).toBeTruthy(); + expect(item.audienceName).toBe('New customers'); + }); + }); + + it('should select json nested value', async () => { + await TestUtils.executeInTransaction(context, async () => { + const Products = context.model('Product').silent(); + let item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem() + expect(item).toBeTruthy(); + item.metadata = { + color: 'silver', + audience: { + name: 'New customers', + description: 'New customers who have never purchased before', + audienceType: 'B2C', + geographicArea: 'Worldwide' + } + } + await Products.save(item); + item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem(); + expect(item).toBeTruthy(); + expect(item.metadata).toBeTruthy(); + expect(item.metadata.audience).toBeTruthy(); + item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)') + .select('metadata/audience as audience').getItem(); + expect(item).toBeTruthy(); + expect(item.audience.name).toBe('New customers'); + }); + }); + + it('should throw error on invalid json', async () => { + await TestUtils.executeInTransaction(context, async () => { + const Products = context.model('Product').silent(); + let item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem() + expect(item).toBeTruthy(); + item.metadata = { + color: 'silver', + message : 'hello' + } + await expect(Products.save(item)).rejects.toThrow('The given structured value seems to be invalid. The property \'message\' is not defined in the target model.'); + }); + }); + + it('should select json attribute from $select', async () => { + const Products = context.model('Product').silent(); + const options = { + $select: 'id,name,metadata/color as color', + $top: 10 + } + const q = await Products.filterAsync(options); + const items = await q.getItems(); + expect(items).toBeTruthy(); + expect(items.length).toBeGreaterThan(0); + }); + + it('should use json attribute in aggregate functions', async () => { + await TestUtils.executeInTransaction(context, async () => { + const Products = context.model('Product').silent(); + let items = await Products.asQueryable().select('id', 'metadata').where('category').equal('Laptops') + //.and('id').equal(19) + //.take(20) + .getItems(); + expect(items).toBeTruthy(); + const colors = ['silver', 'black', 'white', 'red', 'blue']; + items.forEach(item => { + item.metadata = { + color: colors[Math.floor(Math.random() * colors.length)] + } + }); + for (const item of items) { + await Products.save(item); + } + items = await Products.asQueryable().select( + 'count(metadata/color) as total', + 'metadata/color as color' + ).groupBy( + 'metadata/color' + ).getItems(); + expect(items).toBeTruthy(); + }); + }); + +}); diff --git a/spec/test2/config/models/Audience.json b/spec/test2/config/models/Audience.json new file mode 100644 index 0000000..68f23ca --- /dev/null +++ b/spec/test2/config/models/Audience.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://themost-framework.github.io/themost/models/2018/2/schema.json", + "@id": "https://schema.org/Audience", + "name": "Audience", + "description": "Intended audience for an item, i.e. the group for whom the item was created.", + "title": "Audience", + "abstract": false, + "sealed": false, + "implements": "Intangible", + "version": "1.0", + "fields": [ + { + "name": "audienceType", + "title": "Audience Type", + "description": "The target group associated with a given audience (e.g. veterans, car owners, musicians, etc.).", + "type": "Text" + }, + { + "name": "geographicArea", + "title": "Geographic Area", + "description": "The geographic area associated with the audience.", + "type": "Text" + } + ], + "privileges": [ + { + "mask": 15, + "type": "global" + }, + { + "mask": 15, + "type": "global", + "account": "Administrators" + } + ] +} diff --git a/spec/test2/config/models/Product.json b/spec/test2/config/models/Product.json index 2cb3275..c32219f 100644 --- a/spec/test2/config/models/Product.json +++ b/spec/test2/config/models/Product.json @@ -223,6 +223,12 @@ "associationType": "association", "cascade": "delete" } + }, + { + "name": "metadata", + "many": false, + "type": "Json", + "additionalType": "ProductMetadata" } ], "constraints": [ diff --git a/spec/test2/config/models/ProductMetadata.json b/spec/test2/config/models/ProductMetadata.json new file mode 100644 index 0000000..2de0e53 --- /dev/null +++ b/spec/test2/config/models/ProductMetadata.json @@ -0,0 +1,71 @@ +{ + "$schema": "https://themost-framework.github.io/themost/models/2018/2/schema.json", + "title": "Product Metadata", + "name": "ProductMetadata", + "abstract": true, + "version": "1.0.0", + "fields": [ + { + "name": "color", + "title": "Color", + "description": "A color related to the product.", + "type": "Text" + }, + { + "name": "mpn", + "title": "Manufacturer Part Number", + "description": "The manufacturer part number (MPN) of the product.", + "type": "Text" + }, + { + "name": "slogan", + "title": "Slogan", + "description": "A slogan or tagline associated with the product.", + "type": "Text" + }, + { + "@id": "https://themost.io/schemas/dateCreated", + "name": "dateCreated", + "title": "dateCreated", + "description": "The date on which this item was created.", + "type": "DateTime", + "readonly": true, + "value": "javascript:return new Date();", + "calculation": "javascript:return (new Date());" + }, + { + "@id": "https://themost.io/schemas/dateModified", + "name": "dateModified", + "title": "dateModified", + "description": "The date on which this item was most recently modified.", + "type": "DateTime", + "readonly": true, + "value": "javascript:return (new Date());", + "calculation": "javascript:return (new Date());" + }, + { + "@id": "https://schema.org/Audience", + "name": "audience", + "title": "Audience", + "description": "An intended audience associated with the product.", + "type": "Json", + "additionalType": "Audience" + } + ], + "privileges": [ + { + "mask": 1, + "type": "global", + "account": "*" + }, + { + "mask": 15, + "type": "global" + }, + { + "mask": 15, + "type": "global", + "account": "Administrators" + } + ] +} \ No newline at end of file