From 9424a8102fc062622dc5009c00b895a4199054c1 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Wed, 31 Jan 2024 23:14:48 +0000 Subject: [PATCH 01/24] feat(models): adds benchmark model generator Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- .../benchmarkModelGenerator.js | 407 ++++++++++++++++++ lib/codegen/codegen.js | 5 +- package-lock.json | 11 +- package.json | 3 +- 4 files changed, 423 insertions(+), 3 deletions(-) create mode 100644 lib/codegen/benchmarkModelGenerator/benchmarkModelGenerator.js diff --git a/lib/codegen/benchmarkModelGenerator/benchmarkModelGenerator.js b/lib/codegen/benchmarkModelGenerator/benchmarkModelGenerator.js new file mode 100644 index 00000000..701362ea --- /dev/null +++ b/lib/codegen/benchmarkModelGenerator/benchmarkModelGenerator.js @@ -0,0 +1,407 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const { + uniqueNamesGenerator, adjectives, colors, animals +} = require('unique-names-generator'); + +const DEFAULT_CONCERTO_METAMODEL_VERSION = '1.0.0'; +const DEFAULT_MODEL_NAMESPACE = 'big.benchmark.model'; +const DEFAULT_MODEL_VERSION = '1.0.0'; + +/** + * Generate a benchmark model. + * + * @private + * @class + */ +class BenchmarkModelGenerator { + /** + * Formats the given byte size into a human-readable string. + * @param {number} bytes The number of bytes. + * @param {number} [decimals=2] The number of decimal places to include. + * @returns {string} A formatted string representing the byte size. + */ + formatBytes(bytes, decimals = 2) { + if (!+bytes) {return '0 Bytes';} + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; + } + + /** + * Calculates the size of a JSON object in bytes. + * @param {Object} json The JSON object to measure. + * @returns {number} The size of the JSON object in bytes. + */ + jsonSize(json) { + return new Blob( + [JSON.stringify(json)] + ).size; + } + + /** + * Gathers statistics about the number of properties in declarations. + * @param {Array} declarations An array of declaration objects. + * @returns {Object} An object containing statistics about the properties. + */ + gatherPropertiesNStats(declarations) { + const propertiesNInDeclarations = declarations.map( + declaration => declaration.properties.length + ); + + return { + propertiesNInSmallestDeclaration: Math.min(...propertiesNInDeclarations), + propertiesNInLargestDeclaration: Math.max(...propertiesNInDeclarations), + }; + } + + /** + * Generates a unique name based on a seed value. + * @param {string} seed A seed value to generate the name. + * @returns {string} A unique name. + */ + generateName(seed) { + return uniqueNamesGenerator({ + dictionaries: [adjectives, colors, animals], + style: 'capital', + separator: '', + seed, + }); + } + + /** + * Generates a property object. + * @param {Object} params An object containing indices for model, declaration, and property. + * @returns {Object} A property object. + */ + generateProperty({ + modelI, + declarationI, + propertyI, + }) { + return { + $class: 'concerto.metamodel@1.0.0.StringProperty', + name: this.generateName(`${modelI}.${declarationI}.${propertyI}`), + isArray: false, + isOptional: false, + }; + } + + /** + * Generates multiple property objects. + * @param {Object} params An object containing model index, declaration index, and the number of properties. + * @returns {Array<Object>} An array of property objects. + */ + generateNProperties({ + modelI, + declarationI, + nProperties, + }) { + let properties = []; + + for (let propertyI = 0; propertyI < nProperties; propertyI++) { + properties = [ + ...properties, + this.generateProperty({ + modelI, + declarationI, + propertyI, + }) + ]; + } + + return properties; + } + + /** + * Generates property objects up to a specified size. + * @param {Object} params An object containing model index, declaration index, and a size budget for properties. + * @returns {Array<Object>} An array of property objects within the specified size budget. + */ + generatePropertiesUpToSize({ + modelI, + declarationI, + propertiesSizeBudget, + }) { + let properties = []; + let oversized = false; + let propertyI = 0; + + while (!oversized) { + const propertiesWithNewAddition = [ + ...properties, + this.generateProperty({ + modelI, + declarationI, + propertyI, + }) + ]; + + if (this.jsonSize(propertiesWithNewAddition) <= propertiesSizeBudget) { + propertyI++; + properties = propertiesWithNewAddition; + } else { + oversized = true; + } + } + + return properties; + } + + /** + * Generates a declaration object with a specified number of properties. + * @param {Object} params An object containing model index, declaration index, and the number of properties. + * @returns {Object} A declaration object. + */ + generateDeclarationWithNProperties({ + modelI, + declarationI, + nProperties, + }) { + return { + $class: 'concerto.metamodel@1.0.0.ConceptDeclaration', + name: this.generateName(`${modelI}.${declarationI}`), + isAbstract: false, + properties: this.generateNProperties({ + modelI, + declarationI, + nProperties, + }) + }; + } + + /** + * Generates a declaration object to a specified size. + * @param {Object} params An object containing model index, declaration index, and a size budget for the declaration. + * @returns {Object} A declaration object within the specified size budget. + */ + generateDeclarationToSize({ + modelI, + declarationI, + declarationSizeBudget, + }) { + let declaration = { + $class: 'concerto.metamodel@1.0.0.ConceptDeclaration', + name: this.generateName(`${modelI}.${declarationI}`), + isAbstract: false, + properties: [], + }; + + declaration.properties = this.generatePropertiesUpToSize({ + modelI, + declarationI, + propertiesSizeBudget: declarationSizeBudget - this.jsonSize(declaration), + }); + + return declaration; + } + + /** + * Generates multiple declarations with properties, aiming to fit within a size budget by adding declarations. + * @param {Object} params An object containing model index, a size budget for declarations, and the number of properties per declaration. + * @returns {Array<Object>} An array of declaration objects. + */ + generateDeclarationsToSizeGrowByDeclarations({ + modelI, + declarationsSizeBudget, + nProperties, + }) { + let declarations = []; + let oversized = false; + let declarationI = 0; + + while (!oversized) { + const declarationsWithNewAddition = [ + ...declarations, + this.generateDeclarationWithNProperties({ + modelI, + declarationI, + nProperties, + }) + ]; + + if (this.jsonSize(declarationsWithNewAddition) <= declarationsSizeBudget) { + declarationI++; + declarations = declarationsWithNewAddition; + } else { + oversized = true; + } + } + + return declarations; + } + + /** + * Generates multiple declarations with properties, distributing the size budget across properties within declarations. + * @param {Object} params An object containing model index, a size budget for declarations, and the number of declarations. + * @returns {Array<Object>} An array of declaration objects. + */ + generateDeclarationsToSizeGrowByProperties({ + modelI, + declarationsSizeBudget, + nDeclarations, + }) { + let declarations = []; + let remainingDeclarationSizeBudget; + let declarationI = 0; + + while (nDeclarations - declarationI > 0) { + remainingDeclarationSizeBudget = ( + declarationsSizeBudget - this.jsonSize(declarations) + ) / (nDeclarations - declarationI); + + const declaration = this.generateDeclarationToSize({ + modelI, + declarationI, + declarationSizeBudget: remainingDeclarationSizeBudget, + }); + declarationI++; + declarations = [ ...declarations, declaration ]; + } + + return declarations; + } + + /** + * Generates declarations according to a specified size budget and growth strategy. + * @param {Object} params An object containing model index, size budget, number of declarations, number of properties, and growth strategy. + * @returns {Array<Object>} An array of declaration objects according to the specified growth strategy. + */ + generateDeclarationsToSize({ + modelI, + declarationsSizeBudget, + nDeclarations, + nProperties, + growBy, + }) { + switch(growBy) { + case 'declarations': + return this.generateDeclarationsToSizeGrowByDeclarations({ + modelI, + declarationsSizeBudget, + nProperties, + }); + case 'properties': + return this.generateDeclarationsToSizeGrowByProperties({ + modelI, + declarationsSizeBudget, + nDeclarations, + }); + default: + throw new Error('growBy can be either set to "declarations" or "properties".'); + } + } + + /** + * Generates a specified number of declarations, each with a fixed number of properties. + * @param {Object} params An object containing model index, the number of declarations, and the number of properties per declaration. + * @returns {Array<Object>} An array of declaration objects. + */ + generateNDeclarations({ + modelI, + nDeclarations, + nProperties, + }) { + let declarations = []; + + for (let declarationI = 0; declarationI < nDeclarations; declarationI++) { + declarations = [ + ...declarations, + this.generateDeclarationWithNProperties({ + modelI, + declarationI, + nProperties, + }) + ]; + } + + return declarations; + } + + /** + * Generates a Concerto model with specified parameters, optionally generating up to a size limit. + * @param {Object} params An object containing parameters for the model generation, such as metamodel version, namespace, version, indices, and size constraints. + * @returns {Object} An object containing the generated model and metadata about the generation process. + * @public + */ + generateConcertoModel({ + concertoMetamodelVersion = DEFAULT_CONCERTO_METAMODEL_VERSION, + modelNamespace = DEFAULT_MODEL_NAMESPACE, + modelVersion = DEFAULT_MODEL_VERSION, + modelI = 0, + nDeclarations = 1, + nProperties = 1, + generateUpToSize, + growBy = 'declarations' + }) { + const model = { + $class: `concerto.metamodel@${concertoMetamodelVersion}.Model`, + decorators: [], + namespace: `${modelNamespace}@${modelVersion}`, + imports: [], + declarations: [] + }; + + if (generateUpToSize) { + const modelSizeWithoutDeclarations = this.jsonSize(model); + + if (modelSizeWithoutDeclarations < generateUpToSize) { + model.declarations = this.generateDeclarationsToSize({ + modelI, + declarationsSizeBudget: generateUpToSize - modelSizeWithoutDeclarations, + nDeclarations, + nProperties, + growBy, + }); + } + } else { + model.declarations = this.generateNDeclarations({ + modelI, + nDeclarations, + nProperties, + }); + } + + const generatedModelSizeInBytes = this.jsonSize(model); + + this.gatherPropertiesNStats(model.declarations); + const { + propertiesNInSmallestDeclaration, + propertiesNInLargestDeclaration, + } = this.gatherPropertiesNStats(model.declarations); + + return { + model, + metadata: { + requestedModelSizeInBytes: generateUpToSize, + humanReadableRequestedModelSize: this.formatBytes(generateUpToSize, 2), + generatedModelSizeInBytes, + humanReadableGeneratedModelSize: this.formatBytes(generatedModelSizeInBytes, 2), + declarationsN: model.declarations.length, + propertiesNInSmallestDeclaration, + propertiesNInLargestDeclaration, + } + }; + } +} + +module.exports = BenchmarkModelGenerator; diff --git a/lib/codegen/codegen.js b/lib/codegen/codegen.js index 646b372f..0c5320ac 100644 --- a/lib/codegen/codegen.js +++ b/lib/codegen/codegen.js @@ -36,6 +36,7 @@ const JSONSchemaToConcertoVisitor = require( const OpenApiToConcertoVisitor = require('./fromOpenApi/cto/openApiVisitor'); const RustVisitor = require('./fromcto/rust/rustvisitor'); const VocabularyVisitor = require('./fromcto/vocabulary/vocabularyvisitor'); +const BenchmarkModelGenerator = require('./benchmarkModelGenerator/benchmarkModelGenerator'); module.exports = { AbstractPlugin, @@ -57,6 +58,7 @@ module.exports = { OpenApiToConcertoVisitor, RustVisitor, VocabularyVisitor, + BenchmarkModelGenerator, formats: { golang: GoLangVisitor, jsonschema: JSONSchemaVisitor, @@ -73,6 +75,7 @@ module.exports = { openapi: OpenApiVisitor, avro: AvroVisitor, rust: RustVisitor, - vocabulary: VocabularyVisitor + vocabulary: VocabularyVisitor, + benchmarkModelGenerator: BenchmarkModelGenerator, } }; diff --git a/package-lock.json b/package-lock.json index 61a1ad01..4aff933d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,8 @@ "debug": "4.3.1", "get-value": "3.0.1", "json-schema-migrate": "2.0.0", - "pluralize": "8.0.0" + "pluralize": "8.0.0", + "unique-names-generator": "4.7.1" }, "devDependencies": { "@accordproject/concerto-cto": "3.16.4", @@ -8059,6 +8060,14 @@ "node": ">=4" } }, + "node_modules/unique-names-generator": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz", + "integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==", + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", diff --git a/package.json b/package.json index 43a6f245..8296750a 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,8 @@ "debug": "4.3.1", "get-value": "3.0.1", "json-schema-migrate": "2.0.0", - "pluralize": "8.0.0" + "pluralize": "8.0.0", + "unique-names-generator": "4.7.1" }, "license-check-and-add-config": { "folder": "./lib", From b079930075e5b9b9c688231372146499580be2d1 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 11:05:03 +0000 Subject: [PATCH 02/24] feat(models): move benchmark model generator code Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/codegen/codegen.js | 3 +-- .../benchmarkModelGenerator.js | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename lib/{codegen/benchmarkModelGenerator => common}/benchmarkModelGenerator.js (100%) diff --git a/lib/codegen/codegen.js b/lib/codegen/codegen.js index 0c5320ac..e331204a 100644 --- a/lib/codegen/codegen.js +++ b/lib/codegen/codegen.js @@ -36,7 +36,7 @@ const JSONSchemaToConcertoVisitor = require( const OpenApiToConcertoVisitor = require('./fromOpenApi/cto/openApiVisitor'); const RustVisitor = require('./fromcto/rust/rustvisitor'); const VocabularyVisitor = require('./fromcto/vocabulary/vocabularyvisitor'); -const BenchmarkModelGenerator = require('./benchmarkModelGenerator/benchmarkModelGenerator'); +const BenchmarkModelGenerator = require('../common/benchmarkModelGenerator'); module.exports = { AbstractPlugin, @@ -76,6 +76,5 @@ module.exports = { avro: AvroVisitor, rust: RustVisitor, vocabulary: VocabularyVisitor, - benchmarkModelGenerator: BenchmarkModelGenerator, } }; diff --git a/lib/codegen/benchmarkModelGenerator/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js similarity index 100% rename from lib/codegen/benchmarkModelGenerator/benchmarkModelGenerator.js rename to lib/common/benchmarkModelGenerator.js From cf88979c87b12932811c11ffc85964f904099afe Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 12:21:37 +0000 Subject: [PATCH 03/24] feat(models): minor tweaks Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 701362ea..287e7ec2 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -36,8 +36,6 @@ class BenchmarkModelGenerator { * @returns {string} A formatted string representing the byte size. */ formatBytes(bytes, decimals = 2) { - if (!+bytes) {return '0 Bytes';} - const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; @@ -343,15 +341,15 @@ class BenchmarkModelGenerator { * @returns {Object} An object containing the generated model and metadata about the generation process. * @public */ - generateConcertoModel({ + generateConcertoModels({ concertoMetamodelVersion = DEFAULT_CONCERTO_METAMODEL_VERSION, modelNamespace = DEFAULT_MODEL_NAMESPACE, modelVersion = DEFAULT_MODEL_VERSION, modelI = 0, + generateUpToSize, + growBy = 'declarations', nDeclarations = 1, nProperties = 1, - generateUpToSize, - growBy = 'declarations' }) { const model = { $class: `concerto.metamodel@${concertoMetamodelVersion}.Model`, @@ -390,10 +388,12 @@ class BenchmarkModelGenerator { } = this.gatherPropertiesNStats(model.declarations); return { - model, + models: [model], metadata: { - requestedModelSizeInBytes: generateUpToSize, - humanReadableRequestedModelSize: this.formatBytes(generateUpToSize, 2), + ...(generateUpToSize ? { + requestedModelSizeInBytes: generateUpToSize, + humanReadableRequestedModelSize: this.formatBytes(generateUpToSize, 2), + } : {}), generatedModelSizeInBytes, humanReadableGeneratedModelSize: this.formatBytes(generatedModelSizeInBytes, 2), declarationsN: model.declarations.length, From a7f13db02f792df5158901a59967bf4cf10ef6a9 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 12:22:05 +0000 Subject: [PATCH 04/24] test(models): adds unit tests Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- test/common/benchmarkModelGenerator.js | 235 +++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 test/common/benchmarkModelGenerator.js diff --git a/test/common/benchmarkModelGenerator.js b/test/common/benchmarkModelGenerator.js new file mode 100644 index 00000000..1e4171d6 --- /dev/null +++ b/test/common/benchmarkModelGenerator.js @@ -0,0 +1,235 @@ +/* eslint-disable no-unreachable */ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const BenchmarkModelGenerator = require('../../lib/common/benchmarkModelGenerator.js'); +const { expect } = require('expect'); + +describe('benchmarkModelGenerator', function () { + describe('generateConcertoModels', function () { + it('should generate a benchmark Concerto model up to a specified number of declarations and properties', function () { + const benchmarkModelGenerator = new BenchmarkModelGenerator(); + benchmarkModelGenerator.should.not.be.null; + + const generated = benchmarkModelGenerator.generateConcertoModels({ + nDeclarations: 5, + nProperties: 5, + }); + + expect(generated.models[0].declarations.length).toEqual(5); + expect(generated.models[0].declarations[0].properties.length).toEqual(5); + expect(generated.models[0].declarations[0]).toEqual({ + '$class': 'concerto.metamodel@1.0.0.ConceptDeclaration', + name: 'TotalTealDolphin', + isAbstract: false, + properties: [ + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'PrimaryIndigoOrangutan', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'TiredTealBear', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'ChronicCrimsonOtter', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'InternationalSilverQuelea', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'ConsistentBlueEarthworm', + isArray: false, + isOptional: false + } + ] + }); + delete generated.models[0].declarations; + expect(generated.models[0]).toEqual({ + '$class': 'concerto.metamodel@1.0.0.Model', + decorators: [], + namespace: 'big.benchmark.model@1.0.0', + imports: [] + }); + expect(generated.metadata).toEqual({ + generatedModelSizeInBytes: 3665, + humanReadableGeneratedModelSize: '3.58 KiB', + declarationsN: 5, + propertiesNInSmallestDeclaration: 5, + propertiesNInLargestDeclaration: 5 + }); + }); + + it('should generate a benchmark Concerto model up to a specified size in bytes growing it by the number of declarations', function () { + const benchmarkModelGenerator = new BenchmarkModelGenerator(); + benchmarkModelGenerator.should.not.be.null; + + const generated = benchmarkModelGenerator.generateConcertoModels({ + generateUpToSize: 10000, + growBy: 'declarations', + nProperties: 5, + }); + + expect(generated.models[0].declarations.length).toEqual(14); + expect(generated.models[0].declarations[0].properties.length).toEqual(5); + expect(generated.models[0].declarations[0]).toEqual({ + '$class': 'concerto.metamodel@1.0.0.ConceptDeclaration', + name: 'TotalTealDolphin', + isAbstract: false, + properties: [ + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'PrimaryIndigoOrangutan', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'TiredTealBear', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'ChronicCrimsonOtter', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'InternationalSilverQuelea', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'ConsistentBlueEarthworm', + isArray: false, + isOptional: false + } + ] + }); + delete generated.models[0].declarations; + expect(generated.models[0]).toEqual({ + '$class': 'concerto.metamodel@1.0.0.Model', + decorators: [], + namespace: 'big.benchmark.model@1.0.0', + imports: [] + }); + expect(generated.metadata).toEqual({ + requestedModelSizeInBytes: 10000, + humanReadableRequestedModelSize: '9.77 KiB', + generatedModelSizeInBytes: 9984, + humanReadableGeneratedModelSize: '9.75 KiB', + declarationsN: 14, + propertiesNInSmallestDeclaration: 5, + propertiesNInLargestDeclaration: 5 + }); + }); + + it('should generate a benchmark Concerto model up to a specified size in bytes growing it by the number of properties', function () { + const benchmarkModelGenerator = new BenchmarkModelGenerator(); + benchmarkModelGenerator.should.not.be.null; + + const generated = benchmarkModelGenerator.generateConcertoModels({ + generateUpToSize: 10000, + growBy: 'properties', + nDeclarations: 5, + }); + + expect(generated.models[0].declarations.length).toEqual(5); + expect(generated.models[0].declarations[0].properties.length).toEqual(15); + expect(generated.models[0].declarations[0].properties.slice(0, 5)).toEqual([ + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'PrimaryIndigoOrangutan', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'TiredTealBear', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'ChronicCrimsonOtter', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'InternationalSilverQuelea', + isArray: false, + isOptional: false + }, + { + '$class': 'concerto.metamodel@1.0.0.StringProperty', + name: 'ConsistentBlueEarthworm', + isArray: false, + isOptional: false + } + ]); + delete generated.models[0].declarations[0].properties; + expect(generated.models[0].declarations[0]).toEqual({ + '$class': 'concerto.metamodel@1.0.0.ConceptDeclaration', + name: 'TotalTealDolphin', + isAbstract: false, + }); + delete generated.models[0].declarations; + expect(generated.models[0]).toEqual({ + '$class': 'concerto.metamodel@1.0.0.Model', + decorators: [], + namespace: 'big.benchmark.model@1.0.0', + imports: [] + }); + expect(generated.metadata).toEqual({ + requestedModelSizeInBytes: 10000, + humanReadableRequestedModelSize: '9.77 KiB', + generatedModelSizeInBytes: 9952, + humanReadableGeneratedModelSize: '9.72 KiB', + declarationsN: 5, + propertiesNInSmallestDeclaration: 15, + propertiesNInLargestDeclaration: 16 + }); + }); + + it('should throw an error if an unsupported growBy option is used', function () { + const benchmarkModelGenerator = new BenchmarkModelGenerator(); + benchmarkModelGenerator.should.not.be.null; + + (() => { + benchmarkModelGenerator.generateConcertoModels({ + generateUpToSize: 10000, + growBy: 'foo', + nDeclarations: 5, + }); + }).should.throw('growBy can be either set to "declarations" or "properties".'); + }); + }); +}); From b61aa5923b2bd92b5607fa773a75331e0601bb01 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 12:26:50 +0000 Subject: [PATCH 05/24] feat(models): have Blob imported for Node.js v16 compitability Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 287e7ec2..c26d8c7c 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -14,6 +14,7 @@ 'use strict'; +const { Blob } = require('buffer'); const { uniqueNamesGenerator, adjectives, colors, animals } = require('unique-names-generator'); From 40c2bc316e2717825275364d4eaa0b640e4fd859 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 12:45:02 +0000 Subject: [PATCH 06/24] fix(models): adds buffer dependency needed for Node.js v16 Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- package-lock.json | 62 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 63 insertions(+) diff --git a/package-lock.json b/package-lock.json index 4aff933d..e69cfe18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@openapi-contrib/openapi-schema-to-json-schema": "3.2.0", "ajv": "8.10.0", "ajv-formats": "2.1.1", + "buffer": "6.0.3", "camelcase": "6.3.0", "debug": "4.3.1", "get-value": "3.0.1", @@ -3124,6 +3125,25 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -3217,6 +3237,29 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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.2.1" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -4534,6 +4577,25 @@ "node": ">=10.17.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==", + "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": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", diff --git a/package.json b/package.json index 8296750a..e20b4d6d 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "@openapi-contrib/openapi-schema-to-json-schema": "3.2.0", "ajv": "8.10.0", "ajv-formats": "2.1.1", + "buffer": "6.0.3", "camelcase": "6.3.0", "debug": "4.3.1", "get-value": "3.0.1", From fd46196a38c4b15fff79b9e8359759939beffb7c Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 12:57:46 +0000 Subject: [PATCH 07/24] docs(models generation): adds readme Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- README.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/README.md b/README.md index 088a7c35..9d8584b0 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,83 @@ Model converters and codegen for [Concerto](https://github.com/accordproject/con npm install @accordproject/concerto-codegen --save ``` +## Use + +### Benchmark Model Generator + +This API allows you to generate models of varying sizes which can be used to test the performance of your Concerto-handling code. + +#### Generate a model up to a specified number of declarations and properties + +You can generate a model up to a specified number of declarations and properties using: + +```js +const benchmarkModelGenerator = new BenchmarkModelGenerator(); +const generated = benchmarkModelGenerator.generateConcertoModels({ + nDeclarations: 5, // Number of declarations in the model + nProperties: 5, // Number of properties per declaration +}); +``` + +#### Generate a model up to a specified size in bytes + +You can generate a model up to a specified size in bytes, however you would need to specify how that model should grow. + +##### Grow model by number of declarations + +If you'd like to grow it by number of declarations, you will need to specify the number of properties that you wish the model to have (defaults to `1`): + +```js +const benchmarkModelGenerator = new BenchmarkModelGenerator(); +const generated = benchmarkModelGenerator.generateConcertoModels({ + generateUpToSize: 10000, // Target upper limit of growth in bytes + growBy: 'declarations', // Element type by which the model should grow + nProperties: 5, // Number of properties per declaration +}); +``` + +##### Grow model by number of properties + +If you'd like to grow it by number of properties, you will need to specify the number of declarations that you wish the model to have (defaults to `1`): + +```js +const benchmarkModelGenerator = new BenchmarkModelGenerator(); +const generated = benchmarkModelGenerator.generateConcertoModels({ + generateUpToSize: 10000, // Target upper limit of growth in bytes + growBy: 'properties', // Element type by which the model should grow + nProperties: 5, // Number of declarations in the model +}); +``` + +The expected response will include an array of generated `models` (currently containing only a single model) and a `metadata` object with information about the generated model e.g: + +```js +{ + models: [ + { + '$class': 'concerto.metamodel@1.0.0.Model', + decorators: [], + namespace: 'big.benchmark.model@1.0.0', + imports: [], + declarations: [ + ... + ] + } + ], + metadata: { + requestedModelSizeInBytes: 10000, + humanReadableRequestedModelSize: '9.77 KiB', + generatedModelSizeInBytes: 9952, + humanReadableGeneratedModelSize: '9.72 KiB', + declarationsN: 5, + propertiesNInSmallestDeclaration: 15, + propertiesNInLargestDeclaration: 16 + } +} +``` + +As you can see from the above example model, the generator will try its best to reach the upper `generateUpToSize` reqested size, but may fall short by a few bytes. + ## License <a name="license"></a> Accord Project source code files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the LICENSE file. Accord Project documentation files are made available under the Creative Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/. From 1c9b50b2c83fdf4979f49f2376bcf3418aa30fd0 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 13:39:04 +0000 Subject: [PATCH 08/24] fix(models): polyfill buffer Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- package-lock.json | 5 ++++- package.json | 2 +- webpack.config.js | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e69cfe18..f8a19c6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "@openapi-contrib/openapi-schema-to-json-schema": "3.2.0", "ajv": "8.10.0", "ajv-formats": "2.1.1", - "buffer": "6.0.3", "camelcase": "6.3.0", "debug": "4.3.1", "get-value": "3.0.1", @@ -27,6 +26,7 @@ "@accordproject/concerto-cto": "3.16.4", "@babel/preset-env": "7.16.11", "babel-loader": "8.2.3", + "buffer": "6.0.3", "chai": "4.3.6", "chai-as-promised": "7.1.1", "chai-things": "0.2.0", @@ -3129,6 +3129,7 @@ "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", @@ -3241,6 +3242,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, "funding": [ { "type": "github", @@ -4581,6 +4583,7 @@ "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", diff --git a/package.json b/package.json index e20b4d6d..d675a6a0 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "@accordproject/concerto-cto": "3.16.4", "@babel/preset-env": "7.16.11", "babel-loader": "8.2.3", + "buffer": "6.0.3", "chai": "4.3.6", "chai-as-promised": "7.1.1", "chai-things": "0.2.0", @@ -75,7 +76,6 @@ "@openapi-contrib/openapi-schema-to-json-schema": "3.2.0", "ajv": "8.10.0", "ajv-formats": "2.1.1", - "buffer": "6.0.3", "camelcase": "6.3.0", "debug": "4.3.1", "get-value": "3.0.1", diff --git a/webpack.config.js b/webpack.config.js index 7fd4b0c1..73e10641 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -62,6 +62,7 @@ module.exports = { }, resolve: { fallback: { + 'buffer': require.resolve('buffer/'), 'fs': false, 'tls': false, 'net': false, @@ -71,4 +72,4 @@ module.exports = { 'url': false, } } -}; \ No newline at end of file +}; From 33a58e77c3cf938266a3cdd01efade2a67f24d6d Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 13:42:46 +0000 Subject: [PATCH 09/24] refactor(models): more generic generated model namespace Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- README.md | 2 +- lib/common/benchmarkModelGenerator.js | 2 +- test/common/benchmarkModelGenerator.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9d8584b0..06d367bf 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ The expected response will include an array of generated `models` (currently con { '$class': 'concerto.metamodel@1.0.0.Model', decorators: [], - namespace: 'big.benchmark.model@1.0.0', + namespace: 'generated.model@1.0.0', imports: [], declarations: [ ... diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index c26d8c7c..4190530c 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -20,7 +20,7 @@ const { } = require('unique-names-generator'); const DEFAULT_CONCERTO_METAMODEL_VERSION = '1.0.0'; -const DEFAULT_MODEL_NAMESPACE = 'big.benchmark.model'; +const DEFAULT_MODEL_NAMESPACE = 'generated.model'; const DEFAULT_MODEL_VERSION = '1.0.0'; /** diff --git a/test/common/benchmarkModelGenerator.js b/test/common/benchmarkModelGenerator.js index 1e4171d6..a617a943 100644 --- a/test/common/benchmarkModelGenerator.js +++ b/test/common/benchmarkModelGenerator.js @@ -72,7 +72,7 @@ describe('benchmarkModelGenerator', function () { expect(generated.models[0]).toEqual({ '$class': 'concerto.metamodel@1.0.0.Model', decorators: [], - namespace: 'big.benchmark.model@1.0.0', + namespace: 'generated.model@1.0.0', imports: [] }); expect(generated.metadata).toEqual({ @@ -137,7 +137,7 @@ describe('benchmarkModelGenerator', function () { expect(generated.models[0]).toEqual({ '$class': 'concerto.metamodel@1.0.0.Model', decorators: [], - namespace: 'big.benchmark.model@1.0.0', + namespace: 'generated.model@1.0.0', imports: [] }); expect(generated.metadata).toEqual({ @@ -205,7 +205,7 @@ describe('benchmarkModelGenerator', function () { expect(generated.models[0]).toEqual({ '$class': 'concerto.metamodel@1.0.0.Model', decorators: [], - namespace: 'big.benchmark.model@1.0.0', + namespace: 'generated.model@1.0.0', imports: [] }); expect(generated.metadata).toEqual({ From c39e8deb9a50741ba014b5f48ed4f0909c3ca84b Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 13:43:40 +0000 Subject: [PATCH 10/24] fix(models): changed model generated class to public by JSDoc Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 4190530c..29bc0def 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -26,7 +26,6 @@ const DEFAULT_MODEL_VERSION = '1.0.0'; /** * Generate a benchmark model. * - * @private * @class */ class BenchmarkModelGenerator { From ecdbf8b4f67eecfb6470947211ea5918a3878ac4 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 13:54:56 +0000 Subject: [PATCH 11/24] test(models): amend generated models' stats Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- test/common/benchmarkModelGenerator.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/common/benchmarkModelGenerator.js b/test/common/benchmarkModelGenerator.js index a617a943..8b9a58b8 100644 --- a/test/common/benchmarkModelGenerator.js +++ b/test/common/benchmarkModelGenerator.js @@ -76,7 +76,7 @@ describe('benchmarkModelGenerator', function () { imports: [] }); expect(generated.metadata).toEqual({ - generatedModelSizeInBytes: 3665, + generatedModelSizeInBytes: 3661, humanReadableGeneratedModelSize: '3.58 KiB', declarationsN: 5, propertiesNInSmallestDeclaration: 5, @@ -143,7 +143,7 @@ describe('benchmarkModelGenerator', function () { expect(generated.metadata).toEqual({ requestedModelSizeInBytes: 10000, humanReadableRequestedModelSize: '9.77 KiB', - generatedModelSizeInBytes: 9984, + generatedModelSizeInBytes: 9980, humanReadableGeneratedModelSize: '9.75 KiB', declarationsN: 14, propertiesNInSmallestDeclaration: 5, @@ -211,8 +211,8 @@ describe('benchmarkModelGenerator', function () { expect(generated.metadata).toEqual({ requestedModelSizeInBytes: 10000, humanReadableRequestedModelSize: '9.77 KiB', - generatedModelSizeInBytes: 9952, - humanReadableGeneratedModelSize: '9.72 KiB', + generatedModelSizeInBytes: 9948, + humanReadableGeneratedModelSize: '9.71 KiB', declarationsN: 5, propertiesNInSmallestDeclaration: 15, propertiesNInLargestDeclaration: 16 From 2dabc922756c5554c707e95d4fcb20cb99659335 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 14:13:17 +0000 Subject: [PATCH 12/24] fix(models): remove external dependency for name generation Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 26 ++++++------ package-lock.json | 11 +---- package.json | 3 +- test/common/benchmarkModelGenerator.js | 58 +++++++++++++------------- 4 files changed, 43 insertions(+), 55 deletions(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 29bc0def..4f4e6c5e 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -15,9 +15,6 @@ 'use strict'; const { Blob } = require('buffer'); -const { - uniqueNamesGenerator, adjectives, colors, animals -} = require('unique-names-generator'); const DEFAULT_CONCERTO_METAMODEL_VERSION = '1.0.0'; const DEFAULT_MODEL_NAMESPACE = 'generated.model'; @@ -74,16 +71,17 @@ class BenchmarkModelGenerator { /** * Generates a unique name based on a seed value. - * @param {string} seed A seed value to generate the name. + * @param {Object} params The indexes of the generated components. * @returns {string} A unique name. */ - generateName(seed) { - return uniqueNamesGenerator({ - dictionaries: [adjectives, colors, animals], - style: 'capital', - separator: '', - seed, - }); + generateName({ + modelI, + declarationI, + propertyI, + }) { + return `Model${modelI}Declaration${declarationI}${ + typeof propertyI === 'number' ? `Property${propertyI}` : '' + }`; } /** @@ -98,7 +96,7 @@ class BenchmarkModelGenerator { }) { return { $class: 'concerto.metamodel@1.0.0.StringProperty', - name: this.generateName(`${modelI}.${declarationI}.${propertyI}`), + name: this.generateName({ modelI, declarationI, propertyI }), isArray: false, isOptional: false, }; @@ -177,7 +175,7 @@ class BenchmarkModelGenerator { }) { return { $class: 'concerto.metamodel@1.0.0.ConceptDeclaration', - name: this.generateName(`${modelI}.${declarationI}`), + name: this.generateName({ modelI, declarationI }), isAbstract: false, properties: this.generateNProperties({ modelI, @@ -199,7 +197,7 @@ class BenchmarkModelGenerator { }) { let declaration = { $class: 'concerto.metamodel@1.0.0.ConceptDeclaration', - name: this.generateName(`${modelI}.${declarationI}`), + name: this.generateName({ modelI, declarationI }), isAbstract: false, properties: [], }; diff --git a/package-lock.json b/package-lock.json index f8a19c6b..f8e10261 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,8 +19,7 @@ "debug": "4.3.1", "get-value": "3.0.1", "json-schema-migrate": "2.0.0", - "pluralize": "8.0.0", - "unique-names-generator": "4.7.1" + "pluralize": "8.0.0" }, "devDependencies": { "@accordproject/concerto-cto": "3.16.4", @@ -8125,14 +8124,6 @@ "node": ">=4" } }, - "node_modules/unique-names-generator": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz", - "integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==", - "engines": { - "node": ">=8" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", diff --git a/package.json b/package.json index d675a6a0..6ae4353b 100644 --- a/package.json +++ b/package.json @@ -80,8 +80,7 @@ "debug": "4.3.1", "get-value": "3.0.1", "json-schema-migrate": "2.0.0", - "pluralize": "8.0.0", - "unique-names-generator": "4.7.1" + "pluralize": "8.0.0" }, "license-check-and-add-config": { "folder": "./lib", diff --git a/test/common/benchmarkModelGenerator.js b/test/common/benchmarkModelGenerator.js index 8b9a58b8..333b1ae5 100644 --- a/test/common/benchmarkModelGenerator.js +++ b/test/common/benchmarkModelGenerator.js @@ -33,36 +33,36 @@ describe('benchmarkModelGenerator', function () { expect(generated.models[0].declarations[0].properties.length).toEqual(5); expect(generated.models[0].declarations[0]).toEqual({ '$class': 'concerto.metamodel@1.0.0.ConceptDeclaration', - name: 'TotalTealDolphin', + name: 'Model0Declaration0', isAbstract: false, properties: [ { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'PrimaryIndigoOrangutan', + name: 'Model0Declaration0Property0', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'TiredTealBear', + name: 'Model0Declaration0Property1', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'ChronicCrimsonOtter', + name: 'Model0Declaration0Property2', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'InternationalSilverQuelea', + name: 'Model0Declaration0Property3', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'ConsistentBlueEarthworm', + name: 'Model0Declaration0Property4', isArray: false, isOptional: false } @@ -76,8 +76,8 @@ describe('benchmarkModelGenerator', function () { imports: [] }); expect(generated.metadata).toEqual({ - generatedModelSizeInBytes: 3661, - humanReadableGeneratedModelSize: '3.58 KiB', + generatedModelSizeInBytes: 3845, + humanReadableGeneratedModelSize: '3.75 KiB', declarationsN: 5, propertiesNInSmallestDeclaration: 5, propertiesNInLargestDeclaration: 5 @@ -94,40 +94,40 @@ describe('benchmarkModelGenerator', function () { nProperties: 5, }); - expect(generated.models[0].declarations.length).toEqual(14); + expect(generated.models[0].declarations.length).toEqual(13); expect(generated.models[0].declarations[0].properties.length).toEqual(5); expect(generated.models[0].declarations[0]).toEqual({ '$class': 'concerto.metamodel@1.0.0.ConceptDeclaration', - name: 'TotalTealDolphin', + name: 'Model0Declaration0', isAbstract: false, properties: [ { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'PrimaryIndigoOrangutan', + name: 'Model0Declaration0Property0', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'TiredTealBear', + name: 'Model0Declaration0Property1', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'ChronicCrimsonOtter', + name: 'Model0Declaration0Property2', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'InternationalSilverQuelea', + name: 'Model0Declaration0Property3', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'ConsistentBlueEarthworm', + name: 'Model0Declaration0Property4', isArray: false, isOptional: false } @@ -143,9 +143,9 @@ describe('benchmarkModelGenerator', function () { expect(generated.metadata).toEqual({ requestedModelSizeInBytes: 10000, humanReadableRequestedModelSize: '9.77 KiB', - generatedModelSizeInBytes: 9980, - humanReadableGeneratedModelSize: '9.75 KiB', - declarationsN: 14, + generatedModelSizeInBytes: 9815, + humanReadableGeneratedModelSize: '9.58 KiB', + declarationsN: 13, propertiesNInSmallestDeclaration: 5, propertiesNInLargestDeclaration: 5 }); @@ -162,35 +162,35 @@ describe('benchmarkModelGenerator', function () { }); expect(generated.models[0].declarations.length).toEqual(5); - expect(generated.models[0].declarations[0].properties.length).toEqual(15); + expect(generated.models[0].declarations[0].properties.length).toEqual(14); expect(generated.models[0].declarations[0].properties.slice(0, 5)).toEqual([ { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'PrimaryIndigoOrangutan', + name: 'Model0Declaration0Property0', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'TiredTealBear', + name: 'Model0Declaration0Property1', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'ChronicCrimsonOtter', + name: 'Model0Declaration0Property2', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'InternationalSilverQuelea', + name: 'Model0Declaration0Property3', isArray: false, isOptional: false }, { '$class': 'concerto.metamodel@1.0.0.StringProperty', - name: 'ConsistentBlueEarthworm', + name: 'Model0Declaration0Property4', isArray: false, isOptional: false } @@ -198,7 +198,7 @@ describe('benchmarkModelGenerator', function () { delete generated.models[0].declarations[0].properties; expect(generated.models[0].declarations[0]).toEqual({ '$class': 'concerto.metamodel@1.0.0.ConceptDeclaration', - name: 'TotalTealDolphin', + name: 'Model0Declaration0', isAbstract: false, }); delete generated.models[0].declarations; @@ -211,11 +211,11 @@ describe('benchmarkModelGenerator', function () { expect(generated.metadata).toEqual({ requestedModelSizeInBytes: 10000, humanReadableRequestedModelSize: '9.77 KiB', - generatedModelSizeInBytes: 9948, - humanReadableGeneratedModelSize: '9.71 KiB', + generatedModelSizeInBytes: 9994, + humanReadableGeneratedModelSize: '9.76 KiB', declarationsN: 5, - propertiesNInSmallestDeclaration: 15, - propertiesNInLargestDeclaration: 16 + propertiesNInSmallestDeclaration: 14, + propertiesNInLargestDeclaration: 15 }); }); From d01408f9e08e3e0c5d8d84bf8f9c31d3a27dc56f Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 14:33:52 +0000 Subject: [PATCH 13/24] feat(models): adds a heap size check Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 5 +++++ test/common/benchmarkModelGenerator.js | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 4f4e6c5e..0cd95dc8 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -14,6 +14,7 @@ 'use strict'; +const v8 = require('v8'); const { Blob } = require('buffer'); const DEFAULT_CONCERTO_METAMODEL_VERSION = '1.0.0'; @@ -349,6 +350,10 @@ class BenchmarkModelGenerator { nDeclarations = 1, nProperties = 1, }) { + if (generateUpToSize > v8.getHeapStatistics().total_heap_size) { + throw new Error('The requested model size is exceeding the total_heap_size and cannot be created.'); + } + const model = { $class: `concerto.metamodel@${concertoMetamodelVersion}.Model`, decorators: [], diff --git a/test/common/benchmarkModelGenerator.js b/test/common/benchmarkModelGenerator.js index 333b1ae5..8833c1ae 100644 --- a/test/common/benchmarkModelGenerator.js +++ b/test/common/benchmarkModelGenerator.js @@ -231,5 +231,18 @@ describe('benchmarkModelGenerator', function () { }); }).should.throw('growBy can be either set to "declarations" or "properties".'); }); + + it('should throw an error if the requested model size exceeds the total_heap_size', function () { + const benchmarkModelGenerator = new BenchmarkModelGenerator(); + benchmarkModelGenerator.should.not.be.null; + + (() => { + benchmarkModelGenerator.generateConcertoModels({ + generateUpToSize: 100000000000, + growBy: 'properties', + nDeclarations: 5, + }); + }).should.throw('The requested model size is exceeding the total_heap_size and cannot be created.'); + }); }); }); From 99f0c0fd0c9a9e8c1ccc214b7e422dacf9d5ca7b Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 14:49:49 +0000 Subject: [PATCH 14/24] fix(models): optimised model generation Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 36 ++++++++++++--------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 0cd95dc8..1f513f1d 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -144,18 +144,16 @@ class BenchmarkModelGenerator { let propertyI = 0; while (!oversized) { - const propertiesWithNewAddition = [ - ...properties, - this.generateProperty({ - modelI, - declarationI, - propertyI, - }) - ]; + const generatedProperty = this.generateProperty({ + modelI, + declarationI, + propertyI, + }); - if (this.jsonSize(propertiesWithNewAddition) <= propertiesSizeBudget) { + propertiesSizeBudget = propertiesSizeBudget - this.jsonSize(generatedProperty); + if (propertiesSizeBudget >= 0) { propertyI++; - properties = propertiesWithNewAddition; + properties = [ ...properties, generatedProperty ]; } else { oversized = true; } @@ -227,18 +225,16 @@ class BenchmarkModelGenerator { let declarationI = 0; while (!oversized) { - const declarationsWithNewAddition = [ - ...declarations, - this.generateDeclarationWithNProperties({ - modelI, - declarationI, - nProperties, - }) - ]; + const generatedDeclaration = this.generateDeclarationWithNProperties({ + modelI, + declarationI, + nProperties, + }); - if (this.jsonSize(declarationsWithNewAddition) <= declarationsSizeBudget) { + declarationsSizeBudget = declarationsSizeBudget - this.jsonSize(generatedDeclaration); + if (declarationsSizeBudget >= 0) { declarationI++; - declarations = declarationsWithNewAddition; + declarations = [...declarations, generatedDeclaration]; } else { oversized = true; } From 60199ab993c97f5d3e8d8309871295e3dbd03e45 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 14:54:22 +0000 Subject: [PATCH 15/24] fix(models): added type defs Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- types/index.d.ts | 1 + types/lib/codegen/codegen.d.ts | 3 +- types/lib/common/benchmarkModelGenerator.d.ts | 94 +++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 types/lib/common/benchmarkModelGenerator.d.ts diff --git a/types/index.d.ts b/types/index.d.ts index feedfed7..b153f930 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -18,6 +18,7 @@ export var CodeGen: { OpenApiToConcertoVisitor: typeof import("./lib/codegen/fromOpenApi/cto/openApiVisitor"); RustVisitor: typeof import("./lib/codegen/fromcto/rust/rustvisitor"); VocabularyVisitor: typeof import("./lib/codegen/fromcto/vocabulary/vocabularyvisitor"); + BenchmarkModelGenerator: typeof import("./lib/common/benchmarkModelGenerator"); formats: { golang: typeof import("./lib/codegen/fromcto/golang/golangvisitor"); jsonschema: typeof import("./lib/codegen/fromcto/jsonschema/jsonschemavisitor"); diff --git a/types/lib/codegen/codegen.d.ts b/types/lib/codegen/codegen.d.ts index 09f403ef..3e4fd568 100644 --- a/types/lib/codegen/codegen.d.ts +++ b/types/lib/codegen/codegen.d.ts @@ -17,6 +17,7 @@ import JSONSchemaToConcertoVisitor = require("./fromJsonSchema/cto/jsonSchemaVis import OpenApiToConcertoVisitor = require("./fromOpenApi/cto/openApiVisitor"); import RustVisitor = require("./fromcto/rust/rustvisitor"); import VocabularyVisitor = require("./fromcto/vocabulary/vocabularyvisitor"); +import BenchmarkModelGenerator = require("../common/benchmarkModelGenerator"); export declare namespace formats { export { GoLangVisitor as golang }; export { JSONSchemaVisitor as jsonschema }; @@ -35,4 +36,4 @@ export declare namespace formats { export { RustVisitor as rust }; export { VocabularyVisitor as vocabulary }; } -export { AbstractPlugin, GoLangVisitor, JSONSchemaVisitor, XmlSchemaVisitor, PlantUMLVisitor, TypescriptVisitor, JavaVisitor, GraphQLVisitor, CSharpVisitor, ODataVisitor, MermaidVisitor, MarkdownVisitor, ProtobufVisitor, OpenApiVisitor, AvroVisitor, JSONSchemaToConcertoVisitor, OpenApiToConcertoVisitor, RustVisitor, VocabularyVisitor }; +export { AbstractPlugin, GoLangVisitor, JSONSchemaVisitor, XmlSchemaVisitor, PlantUMLVisitor, TypescriptVisitor, JavaVisitor, GraphQLVisitor, CSharpVisitor, ODataVisitor, MermaidVisitor, MarkdownVisitor, ProtobufVisitor, OpenApiVisitor, AvroVisitor, JSONSchemaToConcertoVisitor, OpenApiToConcertoVisitor, RustVisitor, VocabularyVisitor, BenchmarkModelGenerator }; diff --git a/types/lib/common/benchmarkModelGenerator.d.ts b/types/lib/common/benchmarkModelGenerator.d.ts new file mode 100644 index 00000000..3ca3bb3c --- /dev/null +++ b/types/lib/common/benchmarkModelGenerator.d.ts @@ -0,0 +1,94 @@ +export = BenchmarkModelGenerator; +/** + * Generate a benchmark model. + * + * @class + */ +declare class BenchmarkModelGenerator { + /** + * Formats the given byte size into a human-readable string. + * @param {number} bytes The number of bytes. + * @param {number} [decimals=2] The number of decimal places to include. + * @returns {string} A formatted string representing the byte size. + */ + formatBytes(bytes: number, decimals?: number): string; + /** + * Calculates the size of a JSON object in bytes. + * @param {Object} json The JSON object to measure. + * @returns {number} The size of the JSON object in bytes. + */ + jsonSize(json: any): number; + /** + * Gathers statistics about the number of properties in declarations. + * @param {Array} declarations An array of declaration objects. + * @returns {Object} An object containing statistics about the properties. + */ + gatherPropertiesNStats(declarations: any[]): any; + /** + * Generates a unique name based on a seed value. + * @param {Object} params The indexes of the generated components. + * @returns {string} A unique name. + */ + generateName({ modelI, declarationI, propertyI, }: any): string; + /** + * Generates a property object. + * @param {Object} params An object containing indices for model, declaration, and property. + * @returns {Object} A property object. + */ + generateProperty({ modelI, declarationI, propertyI, }: any): any; + /** + * Generates multiple property objects. + * @param {Object} params An object containing model index, declaration index, and the number of properties. + * @returns {Array<Object>} An array of property objects. + */ + generateNProperties({ modelI, declarationI, nProperties, }: any): Array<any>; + /** + * Generates property objects up to a specified size. + * @param {Object} params An object containing model index, declaration index, and a size budget for properties. + * @returns {Array<Object>} An array of property objects within the specified size budget. + */ + generatePropertiesUpToSize({ modelI, declarationI, propertiesSizeBudget, }: any): Array<any>; + /** + * Generates a declaration object with a specified number of properties. + * @param {Object} params An object containing model index, declaration index, and the number of properties. + * @returns {Object} A declaration object. + */ + generateDeclarationWithNProperties({ modelI, declarationI, nProperties, }: any): any; + /** + * Generates a declaration object to a specified size. + * @param {Object} params An object containing model index, declaration index, and a size budget for the declaration. + * @returns {Object} A declaration object within the specified size budget. + */ + generateDeclarationToSize({ modelI, declarationI, declarationSizeBudget, }: any): any; + /** + * Generates multiple declarations with properties, aiming to fit within a size budget by adding declarations. + * @param {Object} params An object containing model index, a size budget for declarations, and the number of properties per declaration. + * @returns {Array<Object>} An array of declaration objects. + */ + generateDeclarationsToSizeGrowByDeclarations({ modelI, declarationsSizeBudget, nProperties, }: any): Array<any>; + /** + * Generates multiple declarations with properties, distributing the size budget across properties within declarations. + * @param {Object} params An object containing model index, a size budget for declarations, and the number of declarations. + * @returns {Array<Object>} An array of declaration objects. + */ + generateDeclarationsToSizeGrowByProperties({ modelI, declarationsSizeBudget, nDeclarations, }: any): Array<any>; + /** + * Generates declarations according to a specified size budget and growth strategy. + * @param {Object} params An object containing model index, size budget, number of declarations, number of properties, and growth strategy. + * @returns {Array<Object>} An array of declaration objects according to the specified growth strategy. + */ + generateDeclarationsToSize({ modelI, declarationsSizeBudget, nDeclarations, nProperties, growBy, }: any): Array<any>; + /** + * Generates a specified number of declarations, each with a fixed number of properties. + * @param {Object} params An object containing model index, the number of declarations, and the number of properties per declaration. + * @returns {Array<Object>} An array of declaration objects. + */ + generateNDeclarations({ modelI, nDeclarations, nProperties, }: any): Array<any>; + /** + * Generates a Concerto model with specified parameters, optionally generating up to a size limit. + * @param {Object} params An object containing parameters for the model generation, such as metamodel version, namespace, version, indices, and size constraints. + * @returns {Object} An object containing the generated model and metadata about the generation process. + * @public + */ + public generateConcertoModels({ concertoMetamodelVersion, modelNamespace, modelVersion, modelI, generateUpToSize, growBy, nDeclarations, nProperties, }: any): any; +} From 7a0ca0be1a715fbcec7c8ec8d4b01b871a5aa9d3 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 14:59:24 +0000 Subject: [PATCH 16/24] fix(deps): adds v8 polyfill Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- webpack.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/webpack.config.js b/webpack.config.js index 73e10641..54f18dd6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -70,6 +70,7 @@ module.exports = { 'os': false, 'util': false, 'url': false, + 'v8': require.resolve('v8/'), } } }; From 204d0edac1708f1f96a96398dc3a38ecc96e911b Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 15:03:25 +0000 Subject: [PATCH 17/24] feat(deps): trying to polyfill v8 Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 2 +- webpack.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 1f513f1d..51b693f3 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -14,7 +14,7 @@ 'use strict'; -const v8 = require('v8'); +const v8 = require('node:v8'); const { Blob } = require('buffer'); const DEFAULT_CONCERTO_METAMODEL_VERSION = '1.0.0'; diff --git a/webpack.config.js b/webpack.config.js index 54f18dd6..cf5b491e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -70,7 +70,7 @@ module.exports = { 'os': false, 'util': false, 'url': false, - 'v8': require.resolve('v8/'), + 'node:v8': require.resolve('node:v8/'), } } }; From f5b02ebe7bf65be295cc44fb95c426ac3c9101f9 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 15:09:00 +0000 Subject: [PATCH 18/24] feat(models): heap size performance optimization Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 51b693f3..a487c8eb 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -153,7 +153,7 @@ class BenchmarkModelGenerator { propertiesSizeBudget = propertiesSizeBudget - this.jsonSize(generatedProperty); if (propertiesSizeBudget >= 0) { propertyI++; - properties = [ ...properties, generatedProperty ]; + properties.push(generatedProperty); } else { oversized = true; } @@ -234,7 +234,7 @@ class BenchmarkModelGenerator { declarationsSizeBudget = declarationsSizeBudget - this.jsonSize(generatedDeclaration); if (declarationsSizeBudget >= 0) { declarationI++; - declarations = [...declarations, generatedDeclaration]; + declarations.push(generatedDeclaration); } else { oversized = true; } @@ -262,13 +262,13 @@ class BenchmarkModelGenerator { declarationsSizeBudget - this.jsonSize(declarations) ) / (nDeclarations - declarationI); - const declaration = this.generateDeclarationToSize({ + const generatedDeclaration = this.generateDeclarationToSize({ modelI, declarationI, declarationSizeBudget: remainingDeclarationSizeBudget, }); declarationI++; - declarations = [ ...declarations, declaration ]; + declarations.push(generatedDeclaration); } return declarations; From e0131972bc9b6229393c519cf4ed35241f8b13c6 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 15:14:24 +0000 Subject: [PATCH 19/24] fix(models): assign class method accessibility Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 14 +++++++ types/lib/common/benchmarkModelGenerator.d.ts | 40 +++++++++++++------ 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index a487c8eb..877c3970 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -25,6 +25,7 @@ const DEFAULT_MODEL_VERSION = '1.0.0'; * Generate a benchmark model. * * @class + * @public */ class BenchmarkModelGenerator { /** @@ -32,6 +33,7 @@ class BenchmarkModelGenerator { * @param {number} bytes The number of bytes. * @param {number} [decimals=2] The number of decimal places to include. * @returns {string} A formatted string representing the byte size. + * @private */ formatBytes(bytes, decimals = 2) { const k = 1024; @@ -47,6 +49,7 @@ class BenchmarkModelGenerator { * Calculates the size of a JSON object in bytes. * @param {Object} json The JSON object to measure. * @returns {number} The size of the JSON object in bytes. + * @private */ jsonSize(json) { return new Blob( @@ -58,6 +61,7 @@ class BenchmarkModelGenerator { * Gathers statistics about the number of properties in declarations. * @param {Array} declarations An array of declaration objects. * @returns {Object} An object containing statistics about the properties. + * @private */ gatherPropertiesNStats(declarations) { const propertiesNInDeclarations = declarations.map( @@ -74,6 +78,7 @@ class BenchmarkModelGenerator { * Generates a unique name based on a seed value. * @param {Object} params The indexes of the generated components. * @returns {string} A unique name. + * @private */ generateName({ modelI, @@ -89,6 +94,7 @@ class BenchmarkModelGenerator { * Generates a property object. * @param {Object} params An object containing indices for model, declaration, and property. * @returns {Object} A property object. + * @private */ generateProperty({ modelI, @@ -107,6 +113,7 @@ class BenchmarkModelGenerator { * Generates multiple property objects. * @param {Object} params An object containing model index, declaration index, and the number of properties. * @returns {Array<Object>} An array of property objects. + * @private */ generateNProperties({ modelI, @@ -133,6 +140,7 @@ class BenchmarkModelGenerator { * Generates property objects up to a specified size. * @param {Object} params An object containing model index, declaration index, and a size budget for properties. * @returns {Array<Object>} An array of property objects within the specified size budget. + * @private */ generatePropertiesUpToSize({ modelI, @@ -166,6 +174,7 @@ class BenchmarkModelGenerator { * Generates a declaration object with a specified number of properties. * @param {Object} params An object containing model index, declaration index, and the number of properties. * @returns {Object} A declaration object. + * @private */ generateDeclarationWithNProperties({ modelI, @@ -188,6 +197,7 @@ class BenchmarkModelGenerator { * Generates a declaration object to a specified size. * @param {Object} params An object containing model index, declaration index, and a size budget for the declaration. * @returns {Object} A declaration object within the specified size budget. + * @private */ generateDeclarationToSize({ modelI, @@ -214,6 +224,7 @@ class BenchmarkModelGenerator { * Generates multiple declarations with properties, aiming to fit within a size budget by adding declarations. * @param {Object} params An object containing model index, a size budget for declarations, and the number of properties per declaration. * @returns {Array<Object>} An array of declaration objects. + * @private */ generateDeclarationsToSizeGrowByDeclarations({ modelI, @@ -247,6 +258,7 @@ class BenchmarkModelGenerator { * Generates multiple declarations with properties, distributing the size budget across properties within declarations. * @param {Object} params An object containing model index, a size budget for declarations, and the number of declarations. * @returns {Array<Object>} An array of declaration objects. + * @private */ generateDeclarationsToSizeGrowByProperties({ modelI, @@ -278,6 +290,7 @@ class BenchmarkModelGenerator { * Generates declarations according to a specified size budget and growth strategy. * @param {Object} params An object containing model index, size budget, number of declarations, number of properties, and growth strategy. * @returns {Array<Object>} An array of declaration objects according to the specified growth strategy. + * @private */ generateDeclarationsToSize({ modelI, @@ -308,6 +321,7 @@ class BenchmarkModelGenerator { * Generates a specified number of declarations, each with a fixed number of properties. * @param {Object} params An object containing model index, the number of declarations, and the number of properties per declaration. * @returns {Array<Object>} An array of declaration objects. + * @private */ generateNDeclarations({ modelI, diff --git a/types/lib/common/benchmarkModelGenerator.d.ts b/types/lib/common/benchmarkModelGenerator.d.ts index 3ca3bb3c..c9661ec3 100644 --- a/types/lib/common/benchmarkModelGenerator.d.ts +++ b/types/lib/common/benchmarkModelGenerator.d.ts @@ -3,6 +3,7 @@ export = BenchmarkModelGenerator; * Generate a benchmark model. * * @class + * @public */ declare class BenchmarkModelGenerator { /** @@ -10,80 +11,93 @@ declare class BenchmarkModelGenerator { * @param {number} bytes The number of bytes. * @param {number} [decimals=2] The number of decimal places to include. * @returns {string} A formatted string representing the byte size. + * @private */ - formatBytes(bytes: number, decimals?: number): string; + private formatBytes; /** * Calculates the size of a JSON object in bytes. * @param {Object} json The JSON object to measure. * @returns {number} The size of the JSON object in bytes. + * @private */ - jsonSize(json: any): number; + private jsonSize; /** * Gathers statistics about the number of properties in declarations. * @param {Array} declarations An array of declaration objects. * @returns {Object} An object containing statistics about the properties. + * @private */ - gatherPropertiesNStats(declarations: any[]): any; + private gatherPropertiesNStats; /** * Generates a unique name based on a seed value. * @param {Object} params The indexes of the generated components. * @returns {string} A unique name. + * @private */ - generateName({ modelI, declarationI, propertyI, }: any): string; + private generateName; /** * Generates a property object. * @param {Object} params An object containing indices for model, declaration, and property. * @returns {Object} A property object. + * @private */ - generateProperty({ modelI, declarationI, propertyI, }: any): any; + private generateProperty; /** * Generates multiple property objects. * @param {Object} params An object containing model index, declaration index, and the number of properties. * @returns {Array<Object>} An array of property objects. + * @private */ - generateNProperties({ modelI, declarationI, nProperties, }: any): Array<any>; + private generateNProperties; /** * Generates property objects up to a specified size. * @param {Object} params An object containing model index, declaration index, and a size budget for properties. * @returns {Array<Object>} An array of property objects within the specified size budget. + * @private */ - generatePropertiesUpToSize({ modelI, declarationI, propertiesSizeBudget, }: any): Array<any>; + private generatePropertiesUpToSize; /** * Generates a declaration object with a specified number of properties. * @param {Object} params An object containing model index, declaration index, and the number of properties. * @returns {Object} A declaration object. + * @private */ - generateDeclarationWithNProperties({ modelI, declarationI, nProperties, }: any): any; + private generateDeclarationWithNProperties; /** * Generates a declaration object to a specified size. * @param {Object} params An object containing model index, declaration index, and a size budget for the declaration. * @returns {Object} A declaration object within the specified size budget. + * @private */ - generateDeclarationToSize({ modelI, declarationI, declarationSizeBudget, }: any): any; + private generateDeclarationToSize; /** * Generates multiple declarations with properties, aiming to fit within a size budget by adding declarations. * @param {Object} params An object containing model index, a size budget for declarations, and the number of properties per declaration. * @returns {Array<Object>} An array of declaration objects. + * @private */ - generateDeclarationsToSizeGrowByDeclarations({ modelI, declarationsSizeBudget, nProperties, }: any): Array<any>; + private generateDeclarationsToSizeGrowByDeclarations; /** * Generates multiple declarations with properties, distributing the size budget across properties within declarations. * @param {Object} params An object containing model index, a size budget for declarations, and the number of declarations. * @returns {Array<Object>} An array of declaration objects. + * @private */ - generateDeclarationsToSizeGrowByProperties({ modelI, declarationsSizeBudget, nDeclarations, }: any): Array<any>; + private generateDeclarationsToSizeGrowByProperties; /** * Generates declarations according to a specified size budget and growth strategy. * @param {Object} params An object containing model index, size budget, number of declarations, number of properties, and growth strategy. * @returns {Array<Object>} An array of declaration objects according to the specified growth strategy. + * @private */ - generateDeclarationsToSize({ modelI, declarationsSizeBudget, nDeclarations, nProperties, growBy, }: any): Array<any>; + private generateDeclarationsToSize; /** * Generates a specified number of declarations, each with a fixed number of properties. * @param {Object} params An object containing model index, the number of declarations, and the number of properties per declaration. * @returns {Array<Object>} An array of declaration objects. + * @private */ - generateNDeclarations({ modelI, nDeclarations, nProperties, }: any): Array<any>; + private generateNDeclarations; /** * Generates a Concerto model with specified parameters, optionally generating up to a size limit. * @param {Object} params An object containing parameters for the model generation, such as metamodel version, namespace, version, indices, and size constraints. From 9b8838df8140c9a18cc62af0ed9dd10165510a36 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 15:16:07 +0000 Subject: [PATCH 20/24] fix(models): generated model size is compared against total_available_size Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 877c3970..7af57cf3 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -360,7 +360,7 @@ class BenchmarkModelGenerator { nDeclarations = 1, nProperties = 1, }) { - if (generateUpToSize > v8.getHeapStatistics().total_heap_size) { + if (generateUpToSize > v8.getHeapStatistics().total_available_size) { throw new Error('The requested model size is exceeding the total_heap_size and cannot be created.'); } From 70360445522a8e760f13215b212c4754fb373574 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 15:40:49 +0000 Subject: [PATCH 21/24] refactor(models): improve error wording Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 2 +- test/common/benchmarkModelGenerator.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 7af57cf3..f344cde6 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -361,7 +361,7 @@ class BenchmarkModelGenerator { nProperties = 1, }) { if (generateUpToSize > v8.getHeapStatistics().total_available_size) { - throw new Error('The requested model size is exceeding the total_heap_size and cannot be created.'); + throw new Error('The requested model size exceeds the available heap size and cannot be created.'); } const model = { diff --git a/test/common/benchmarkModelGenerator.js b/test/common/benchmarkModelGenerator.js index 8833c1ae..ca7271a5 100644 --- a/test/common/benchmarkModelGenerator.js +++ b/test/common/benchmarkModelGenerator.js @@ -232,7 +232,7 @@ describe('benchmarkModelGenerator', function () { }).should.throw('growBy can be either set to "declarations" or "properties".'); }); - it('should throw an error if the requested model size exceeds the total_heap_size', function () { + it('should throw an error if the requested model size exceeds the available heap size and cannot be created', function () { const benchmarkModelGenerator = new BenchmarkModelGenerator(); benchmarkModelGenerator.should.not.be.null; @@ -242,7 +242,7 @@ describe('benchmarkModelGenerator', function () { growBy: 'properties', nDeclarations: 5, }); - }).should.throw('The requested model size is exceeding the total_heap_size and cannot be created.'); + }).should.throw('The requested model size exceeds the available heap size and cannot be created.'); }); }); }); From 3edb8e2b24619ae0e61a97b5bb1e1a65e49aece9 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 15:45:17 +0000 Subject: [PATCH 22/24] fix(deps): adds node polyfill Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- package-lock.json | 1075 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 2 +- webpack.config.js | 4 +- 3 files changed, 1076 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index f8e10261..4445e795 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,6 @@ "@accordproject/concerto-cto": "3.16.4", "@babel/preset-env": "7.16.11", "babel-loader": "8.2.3", - "buffer": "6.0.3", "chai": "4.3.6", "chai-as-promised": "7.1.1", "chai-things": "0.2.0", @@ -37,6 +36,7 @@ "mocha-expect-snapshot": "6.2.0", "mockery": "2.1.0", "moxios": "0.4.0", + "node-polyfill-webpack-plugin": "3.0.0", "nunjucks": "3.2.4", "nyc": "15.1.0", "sinon": "12.0.0", @@ -2840,6 +2840,18 @@ "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", "dev": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", @@ -2986,6 +2998,37 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -3000,6 +3043,18 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/available-typed-arrays": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz", + "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", @@ -3168,6 +3223,12 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3190,12 +3251,108 @@ "node": ">=8" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, "node_modules/browserslist": { "version": "4.22.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", @@ -3267,6 +3424,18 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, "node_modules/caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -3294,6 +3463,20 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3470,6 +3653,16 @@ "node": ">=8" } }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -3562,6 +3755,18 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -3581,6 +3786,49 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3595,6 +3843,28 @@ "node": ">= 8" } }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", @@ -3658,6 +3928,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3666,6 +3967,16 @@ "node": ">=0.4.0" } }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -3684,6 +3995,23 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3696,6 +4024,18 @@ "node": ">=6.0.0" } }, + "node_modules/domain-browser": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.23.0.tgz", + "integrity": "sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/drange": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", @@ -3710,6 +4050,27 @@ "integrity": "sha512-RyJX0q/zOkAoefZhB9XHghGeATVP0Q3mwA253XD/zj2OeXc+JZB9pCaEv6R578JUYaWM9PRhye0kXvd/V1cQ3Q==", "dev": true }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -4137,6 +4498,15 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -4146,6 +4516,16 @@ "node": ">=0.8.x" } }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -4325,6 +4705,15 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -4433,6 +4822,21 @@ "node": "*" } }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -4512,6 +4916,18 @@ "node": ">=4" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4526,6 +4942,95 @@ "node": ">=4" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, "node_modules/hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", @@ -4563,12 +5068,29 @@ "he": "bin/he" } }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -4685,6 +5207,22 @@ "node": ">= 0.10" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4700,7 +5238,19 @@ "binary-extensions": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-core-module": { @@ -4733,6 +5283,21 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4745,6 +5310,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4787,6 +5368,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -6028,6 +6624,17 @@ "node": ">= 12" } }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -6053,6 +6660,25 @@ "node": ">=8.6" } }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -6081,6 +6707,18 @@ "node": ">=6" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6429,6 +7067,56 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, + "node_modules/node-polyfill-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-QpG496dDBiaelQZu9wDcVvpLbtk7h9Ctz693RaUMZBgl8DUoFToO90ZTLKq57gP7rwKqYtGbMBXkcEgLSag2jQ==", + "dev": true, + "dependencies": { + "assert": "^2.1.0", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", + "console-browserify": "^1.2.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.12.0", + "domain-browser": "^4.22.0", + "events": "^3.3.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "punycode": "^2.3.0", + "querystring-es3": "^0.2.1", + "readable-stream": "^4.4.2", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "string_decoder": "^1.3.0", + "timers-browserify": "^2.0.12", + "tty-browserify": "^0.0.1", + "type-fest": "^4.4.0", + "url": "^0.11.3", + "util": "^0.12.5", + "vm-browserify": "^1.1.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "webpack": ">=5" + } + }, + "node_modules/node-polyfill-webpack-plugin/node_modules/type-fest": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz", + "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -6751,6 +7439,58 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6792,6 +7532,12 @@ "node": ">= 0.8.0" } }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6858,6 +7604,12 @@ "node": ">=8" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6870,6 +7622,19 @@ "node": ">=6" } }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, "node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -6938,6 +7703,22 @@ "node": "*" } }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -7142,6 +7923,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -7168,6 +7958,26 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7176,6 +7986,30 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/randexp": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", @@ -7197,12 +8031,38 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7424,6 +8284,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -7444,6 +8314,12 @@ } ] }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "node_modules/schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", @@ -7538,6 +8414,41 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "node_modules/set-function-length": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -7571,6 +8482,20 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -7698,6 +8623,65 @@ "node": ">=8" } }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "node_modules/stream-http/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7972,6 +8956,18 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -8020,6 +9016,12 @@ "node": ">=8.0" } }, + "node_modules/tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8167,6 +9169,41 @@ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" }, + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.2" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, "node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -8185,6 +9222,12 @@ "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", "dev": true }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -8421,6 +9464,25 @@ "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", @@ -8508,6 +9570,15 @@ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 6ae4353b..e9325e32 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,6 @@ "@accordproject/concerto-cto": "3.16.4", "@babel/preset-env": "7.16.11", "babel-loader": "8.2.3", - "buffer": "6.0.3", "chai": "4.3.6", "chai-as-promised": "7.1.1", "chai-things": "0.2.0", @@ -60,6 +59,7 @@ "mocha-expect-snapshot": "6.2.0", "mockery": "2.1.0", "moxios": "0.4.0", + "node-polyfill-webpack-plugin": "3.0.0", "nunjucks": "3.2.4", "nyc": "15.1.0", "sinon": "12.0.0", diff --git a/webpack.config.js b/webpack.config.js index cf5b491e..a9515343 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -16,6 +16,7 @@ let path = require('path'); const webpack = require('webpack'); +const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); const packageJson = require('./package.json'); module.exports = { @@ -47,6 +48,7 @@ module.exports = { 'NODE_ENV': JSON.stringify('production') } }), + new NodePolyfillPlugin(), ], module: { rules: [{ @@ -62,7 +64,6 @@ module.exports = { }, resolve: { fallback: { - 'buffer': require.resolve('buffer/'), 'fs': false, 'tls': false, 'net': false, @@ -70,7 +71,6 @@ module.exports = { 'os': false, 'util': false, 'url': false, - 'node:v8': require.resolve('node:v8/'), } } }; From 02e2088b414d049a660a1d8e8d5cc08874ac6d50 Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 15:48:13 +0000 Subject: [PATCH 23/24] fix(deps): renamed v8 addressed without node: Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- lib/common/benchmarkModelGenerator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index f344cde6..79422414 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -14,7 +14,7 @@ 'use strict'; -const v8 = require('node:v8'); +const v8 = require('v8'); const { Blob } = require('buffer'); const DEFAULT_CONCERTO_METAMODEL_VERSION = '1.0.0'; From 2ea743f12dd73e3cb51ede086f40270614ce378e Mon Sep 17 00:00:00 2001 From: Stefan Blaginov <Stefan.Blaginov@docusign.com> Date: Thu, 1 Feb 2024 16:31:03 +0000 Subject: [PATCH 24/24] fix(models): limit generated model to a 100 MiB Signed-off-by: Stefan Blaginov <stefan@blaginov.com> Signed-off-by: Stefan Blaginov <stefan.blaginov@docusign.com> --- README.md | 2 +- lib/common/benchmarkModelGenerator.js | 6 +++--- test/common/benchmarkModelGenerator.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 06d367bf..16fa10db 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ npm install @accordproject/concerto-codegen --save ### Benchmark Model Generator -This API allows you to generate models of varying sizes which can be used to test the performance of your Concerto-handling code. +This API allows you to generate models of varying sizes (up to a 100 MiB) which can be used to test the performance of your Concerto-handling code. #### Generate a model up to a specified number of declarations and properties diff --git a/lib/common/benchmarkModelGenerator.js b/lib/common/benchmarkModelGenerator.js index 79422414..144e89ae 100644 --- a/lib/common/benchmarkModelGenerator.js +++ b/lib/common/benchmarkModelGenerator.js @@ -14,12 +14,12 @@ 'use strict'; -const v8 = require('v8'); const { Blob } = require('buffer'); const DEFAULT_CONCERTO_METAMODEL_VERSION = '1.0.0'; const DEFAULT_MODEL_NAMESPACE = 'generated.model'; const DEFAULT_MODEL_VERSION = '1.0.0'; +const MODEL_SIZE_LIMIT = 104857600; // 100 MiB. /** * Generate a benchmark model. @@ -360,8 +360,8 @@ class BenchmarkModelGenerator { nDeclarations = 1, nProperties = 1, }) { - if (generateUpToSize > v8.getHeapStatistics().total_available_size) { - throw new Error('The requested model size exceeds the available heap size and cannot be created.'); + if (generateUpToSize > MODEL_SIZE_LIMIT) { + throw new Error('The requested model size exceeds the 100 MiB limit and cannot be created.'); } const model = { diff --git a/test/common/benchmarkModelGenerator.js b/test/common/benchmarkModelGenerator.js index ca7271a5..834abf9a 100644 --- a/test/common/benchmarkModelGenerator.js +++ b/test/common/benchmarkModelGenerator.js @@ -242,7 +242,7 @@ describe('benchmarkModelGenerator', function () { growBy: 'properties', nDeclarations: 5, }); - }).should.throw('The requested model size exceeds the available heap size and cannot be created.'); + }).should.throw('The requested model size exceeds the 100 MiB limit and cannot be created.'); }); }); });