├── .gitignore ├── .npmignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── LICENSE.md ├── README.md ├── infrastructure ├── package_scripts │ ├── build.mjs │ ├── build_infrastructure.mjs │ ├── clean.mjs │ ├── format.mjs │ ├── prepack.mjs │ ├── test.mjs │ └── utilities │ │ └── spawn_promise.mjs ├── prettier │ ├── .prettierignore │ └── prettier.config.json └── typescript │ ├── tsconfig.base.json │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ └── tsconfig.types.json ├── package-lock.json ├── package.json ├── src └── instantiator.ts └── tests └── tests.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | npm-debug.log 3 | node_modules 4 | dist 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | src 3 | tests 4 | infrastructure 5 | .gitignore -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "build", 6 | "program": "infrastructure/package_scripts/build.mjs", 7 | "env": { "NODE_OPTIONS": "--inspect" }, 8 | "request": "launch", 9 | "outputCapture": "std", 10 | "skipFiles": ["/**"], 11 | "type": "node", 12 | "internalConsoleOptions": "openOnSessionStart" 13 | }, 14 | { 15 | "name": "build_infrastructure", 16 | "program": "infrastructure/package_scripts/build_infrastructure.mjs", 17 | "env": { "NODE_OPTIONS": "--inspect" }, 18 | "request": "launch", 19 | "outputCapture": "std", 20 | "skipFiles": ["/**"], 21 | "type": "node", 22 | "internalConsoleOptions": "openOnSessionStart" 23 | }, 24 | { 25 | "name": "clean", 26 | "program": "infrastructure/package_scripts/clean.mjs", 27 | "env": { "NODE_OPTIONS": "--inspect" }, 28 | "request": "launch", 29 | "outputCapture": "std", 30 | "skipFiles": ["/**"], 31 | "type": "node", 32 | "internalConsoleOptions": "openOnSessionStart" 33 | }, 34 | { 35 | "name": "format", 36 | "program": "infrastructure/package_scripts/format.mjs", 37 | "env": { "NODE_OPTIONS": "--inspect" }, 38 | "request": "launch", 39 | "outputCapture": "std", 40 | "skipFiles": ["/**"], 41 | "type": "node", 42 | "internalConsoleOptions": "openOnSessionStart" 43 | }, 44 | { 45 | "name": "prepack", 46 | "program": "infrastructure/package_scripts/prepack.mjs", 47 | "env": { "NODE_OPTIONS": "--inspect" }, 48 | "request": "launch", 49 | "outputCapture": "std", 50 | "skipFiles": ["/**"], 51 | "type": "node", 52 | "internalConsoleOptions": "openOnSessionStart" 53 | }, 54 | { 55 | "name": "test", 56 | "program": "infrastructure/package_scripts/test.mjs", 57 | "env": { "NODE_OPTIONS": "--inspect" }, 58 | "request": "launch", 59 | "outputCapture": "std", 60 | "skipFiles": ["/**"], 61 | "type": "node", 62 | "internalConsoleOptions": "openOnSessionStart" 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.eol": "\n", 3 | "editor.tabSize": 2, 4 | "editor.defaultFormatter": "esbenp.prettier-vscode", 5 | "prettier.configPath": "infrastructure/prettier/prettier.config.json", 6 | "prettier.ignorePath": "infrastructure/prettier/.prettierignore", 7 | "editor.formatOnSave": true, 8 | "editor.codeActionsOnSave": { 9 | "source.organizeImports": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "shell", 6 | "command": "node --unhandled-rejections=strict infrastructure/package_scripts/build.mjs", 7 | "label": "build", 8 | "group": { "kind": "build", "isDefault": true } 9 | }, 10 | { 11 | "type": "shell", 12 | "command": "node --unhandled-rejections=strict infrastructure/package_scripts/build_infrastructure.mjs", 13 | "label": "build - infrastructure", 14 | "group": "build" 15 | }, 16 | { 17 | "type": "shell", 18 | "command": "node --unhandled-rejections=strict infrastructure/package_scripts/clean.mjs", 19 | "label": "clean", 20 | "group": "build" 21 | }, 22 | { 23 | "type": "shell", 24 | "command": "node --unhandled-rejections=strict infrastructure/package_scripts/format.mjs", 25 | "label": "format", 26 | "group": "build" 27 | }, 28 | { 29 | "type": "shell", 30 | "command": "node --unhandled-rejections=strict infrastructure/package_scripts/prepack.mjs", 31 | "label": "prepack", 32 | "group": "build" 33 | }, 34 | { 35 | "type": "shell", 36 | "command": "node --unhandled-rejections=strict infrastructure/package_scripts/test.mjs", 37 | "label": "test", 38 | "group": "build" 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Tom Arad 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSON-Schema-Instantiator 2 | A simple tool for instantiating JSON Schemas, with Angular support! 3 | 4 | ## Installing 5 | 6 | ### Node.js 7 | 8 | ``` 9 | npm install json-schema-instantiator 10 | ``` 11 | 12 | ### AngularJS 13 | 14 | ``` 15 | bower install angular-schema-instantiator 16 | ``` 17 | 18 | ## Using 19 | 20 | ### Node.js 21 | ``` javascript 22 | var instantiator = require('json-schema-instantiator'); 23 | 24 | ... 25 | 26 | var schema = { 27 | "type": "object", 28 | "properties": { 29 | "title": { 30 | "type": "string", 31 | "default": "Example" 32 | }, 33 | "description": { 34 | "type": "string" 35 | }, 36 | "quantity": { 37 | "type": "number" 38 | }, 39 | "endDate": { 40 | "type": "string", 41 | "format": "date" 42 | } 43 | }, 44 | "required": ["title"] 45 | }; 46 | 47 | instance = instantiator.instantiate(schema); 48 | // instance === { title: "Example", description: "", quantity: 0, endDate: "" } 49 | 50 | instance = instantiator.instantiate(schema, {requiredPropertiesOnly: false}); 51 | // instance === { title: "Example", description: "", quantity: 0, endDate: "" } 52 | 53 | instance = instantiator.instantiate(schema, {requiredPropertiesOnly: true}); 54 | // instance === { title: "Example" } 55 | 56 | // Override default values for a given type with a static value 57 | instance = instantiator.instantiate(schema, { defaults: { number: 42 } }); 58 | // instance === { title: "Example", description: "", quantity: 42, endDate: "" } 59 | 60 | // Override default values for a given type function that returns a value 61 | instance = instantiator.instantiate(schema, { 62 | defaults: { 63 | // Function that receives current property/val and returns a value 64 | string: function (val) { 65 | var format = val.format; 66 | 67 | if (format && format === "date") { 68 | return new Date(2021, 0, 1); 69 | } 70 | 71 | return ""; 72 | }, 73 | }, 74 | }); 75 | // instance === { title: "Example", description: "", quantity: 0, endDate: new Date(2021, 0, 1) } 76 | ``` 77 | 78 | ### AngularJS 79 | Add the sources to index.html: 80 | 81 | 82 | 83 | 84 | Include the module: 85 | ``` javascript 86 | angular.module('myApp', ['schemaInstantiator']) 87 | 88 | ... 89 | ``` 90 | 91 | Inject the InstantiatorService and use it: 92 | ``` javascript 93 | ... 94 | 95 | .controller({ 96 | MyCtrl: ['InstantiatorService', function(Instantiator) { 97 | var schema = { 98 | type: "string", 99 | default: "Hello!" 100 | }; 101 | 102 | console.log(Instantiator.instantiate(schema)); 103 | // Hello! 104 | }] 105 | }) 106 | 107 | ... 108 | ``` 109 | 110 | ### Note 111 | This does not replace schema validation! Invalid schemas will yield unexpected results. 112 | -------------------------------------------------------------------------------- /infrastructure/package_scripts/build.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import { spawnPromise } from './utilities/spawn_promise.mjs'; 3 | 4 | const tsConfigs = [ 5 | './infrastructure/typescript/tsconfig.cjs.json', 6 | './infrastructure/typescript/tsconfig.esm.json', 7 | './infrastructure/typescript/tsconfig.types.json' 8 | ]; 9 | 10 | await spawnPromise(`npx tsc -b ${tsConfigs.join(' ')}`, { 11 | outputPrefix: '[build]: ' 12 | }); 13 | 14 | // Rename file so it's correctly handled as an ESModule 15 | fs.rename('dist/esm/instantiator.js', 'dist/esm/instantiator.mjs', (err) => { 16 | if (err) { 17 | console.error(err); 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /infrastructure/package_scripts/build_infrastructure.mjs: -------------------------------------------------------------------------------- 1 | //@ts-nocheck 2 | import fs from 'fs/promises'; 3 | import { resolve } from 'path'; 4 | import prettier from 'prettier'; 5 | 6 | const DEFAULT_BUILD_SCRIPT = 'build'; 7 | const CLI_DIR = 'infrastructure/package_scripts'; 8 | 9 | const style = await fs 10 | .readFile(resolve(process.cwd(), 'infrastructure/prettier/prettier.config.json')) 11 | .then((file) => JSON.parse(file.toString())); 12 | 13 | (async function buildVsCodeAndPackageJson() { 14 | // get a list of unique file names in the 'src/cli' folder 15 | /** @type {Set<{name: string; extension: string}>} */ 16 | const uniqueFileNames = new Set(); 17 | const directoryContents = await fs.readdir(CLI_DIR); 18 | await Promise.all( 19 | directoryContents.map(async (subPath) => { 20 | const stat = await fs.stat(resolve(CLI_DIR, subPath)); 21 | if (stat.isFile()) { 22 | uniqueFileNames.add({ 23 | name: subPath.substring(0, subPath.lastIndexOf('.')), 24 | extension: subPath.substring(subPath.lastIndexOf('.') + 1) 25 | }); 26 | } 27 | }) 28 | ); 29 | 30 | // convert it to an array so we can work with it later 31 | const scripts = [...uniqueFileNames].sort((a, b) => a.name.localeCompare(b.name)); 32 | 33 | // read package.json 34 | const packageJson = JSON.parse((await fs.readFile(resolve(process.cwd(), 'package.json'))).toString()); 35 | 36 | // sort the scripts record to ensure the file doesn't keep changing because of order changes 37 | packageJson.scripts = scripts.reduce((accumulator, { name, extension }) => { 38 | accumulator[name] = `node --unhandled-rejections=strict ${CLI_DIR}/${name}.${extension}`; 39 | return accumulator; 40 | }, {}); 41 | 42 | // format & write package.json 43 | await fs.writeFile( 44 | resolve(process.cwd(), 'package.json'), 45 | prettier.format(JSON.stringify(packageJson), { 46 | ...style, 47 | filepath: 'package.json' 48 | }) 49 | ); 50 | 51 | // .vscode/launch.json & .vscode/tasts.json 52 | const [launch, tasks] = await Promise.all([ 53 | (() => fs.readFile(resolve(process.cwd(), '.vscode/launch.json')).then((res) => JSON.parse(res.toString())))(), 54 | (() => fs.readFile(resolve(process.cwd(), '.vscode/tasks.json')).then((res) => JSON.parse(res.toString())))() 55 | ]); 56 | 57 | tasks.tasks = []; 58 | launch.configurations = []; 59 | 60 | scripts.forEach(({ name, extension }) => { 61 | const program = `${CLI_DIR}/${name}.${extension}`; 62 | launch.configurations.push({ 63 | name, 64 | program, 65 | env: { 66 | NODE_OPTIONS: '--inspect' 67 | }, 68 | request: 'launch', 69 | outputCapture: 'std', 70 | skipFiles: ['/**'], 71 | type: 'node', 72 | internalConsoleOptions: 'openOnSessionStart' 73 | }); 74 | tasks.tasks.push({ 75 | type: 'shell', 76 | command: `node --unhandled-rejections=strict ${program}`, 77 | label: name.replace('_', ' - '), 78 | group: 79 | name === DEFAULT_BUILD_SCRIPT 80 | ? { 81 | kind: 'build', 82 | isDefault: true 83 | } 84 | : 'build' 85 | }); 86 | }); 87 | 88 | // sort the records to ensure the files doesn't keep changing because of order changes 89 | launch.configurations.sort((a, b) => a.name.localeCompare(b.name)); 90 | tasks.tasks.sort((a, b) => a.label.localeCompare(b.label)); 91 | 92 | // format & write launch.json 93 | let styled = prettier.format(JSON.stringify(launch), { 94 | ...style, 95 | filepath: 'launch.json' 96 | }); 97 | fs.writeFile(resolve(process.cwd(), '.vscode/launch.json'), styled); 98 | 99 | // format & write tasks.json 100 | styled = prettier.format(JSON.stringify(tasks), { 101 | ...style, 102 | filepath: 'tasks.json' 103 | }); 104 | fs.writeFile(resolve(process.cwd(), '.vscode/tasks.json'), styled); 105 | })(); 106 | -------------------------------------------------------------------------------- /infrastructure/package_scripts/clean.mjs: -------------------------------------------------------------------------------- 1 | import { spawnPromise } from './utilities/spawn_promise.mjs'; 2 | 3 | await spawnPromise('rm -rf dist', { 4 | outputPrefix: '[clean]: ' 5 | }); 6 | -------------------------------------------------------------------------------- /infrastructure/package_scripts/format.mjs: -------------------------------------------------------------------------------- 1 | import { spawnPromise } from './utilities/spawn_promise.mjs'; 2 | 3 | await spawnPromise( 4 | 'npx prettier --config ./infrastructure/prettier/prettier.config.json --ignore-path ./infrastructure/prettier/.prettierignore --write *.json src infrastructure', 5 | { 6 | outputPrefix: '[format]: ' 7 | } 8 | ); 9 | -------------------------------------------------------------------------------- /infrastructure/package_scripts/prepack.mjs: -------------------------------------------------------------------------------- 1 | await import('./build.mjs'); 2 | -------------------------------------------------------------------------------- /infrastructure/package_scripts/test.mjs: -------------------------------------------------------------------------------- 1 | import { spawnPromise } from './utilities/spawn_promise.mjs'; 2 | 3 | await import('./build.mjs'); 4 | 5 | await spawnPromise('npx mocha tests/tests.js', { 6 | outputPrefix: '[test]: ' 7 | }); 8 | -------------------------------------------------------------------------------- /infrastructure/package_scripts/utilities/spawn_promise.mjs: -------------------------------------------------------------------------------- 1 | import { spawn } from 'child_process'; 2 | 3 | /** 4 | * @param {number} startTime 5 | */ 6 | function printDuration(startTime) { 7 | const elapsedMs = performance.now() - startTime; 8 | if (elapsedMs < 60_000) { 9 | return `${(elapsedMs / 1_000).toFixed(2)}s`; 10 | } 11 | const minutes = Math.floor(elapsedMs / 60000); 12 | const seconds = ((elapsedMs % 60000) / 1000).toFixed(0); 13 | return seconds === '60' ? `${minutes + 1}m:00s` : `${minutes}m:${(Number(seconds) < 10 ? '0' : '') + seconds}s`; 14 | } 15 | 16 | /** 17 | * @param {string} command 18 | * @param {import('child_process').SpawnOptionsWithoutStdio & { 19 | * silent?: boolean, 20 | * outputPrefix?: string, 21 | * forwardParams?: boolean 22 | * }} [options] 23 | */ 24 | export const spawnPromise = (command, options) => 25 | new Promise((resolve, reject) => { 26 | /** @type {string} */ 27 | let cmd; 28 | if (options?.forwardParams !== false) { 29 | const args = process.argv.slice(2); 30 | cmd = `${command}${args.length > 0 ? ` ${args.join(' ')}` : ''}`; 31 | } else { 32 | cmd = command; 33 | } 34 | 35 | if (!options?.silent) { 36 | console.log(`${options?.outputPrefix ?? ''}${cmd}`); 37 | } 38 | const startTime = performance.now(); 39 | spawn('sh', ['-c', cmd], { 40 | stdio: 'inherit', 41 | ...options 42 | }).on('close', (code) => { 43 | if (code) { 44 | reject(`${options?.outputPrefix ?? ''}'${cmd}' failed with code ${code} (${printDuration(startTime)})`); 45 | } else { 46 | if (!options?.silent) { 47 | console.log(`${options?.outputPrefix ?? ''}${cmd} completed in ${printDuration(startTime)}`); 48 | } 49 | resolve(code); 50 | } 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /infrastructure/prettier/.prettierignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /infrastructure/prettier/prettier.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "arrowParens": "always", 5 | "trailingComma": "none", 6 | "tabWidth": 2, 7 | "printWidth": 120, 8 | "endOfLine": "lf" 9 | } 10 | -------------------------------------------------------------------------------- /infrastructure/typescript/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "strict": true, 5 | "noImplicitAny": false, 6 | "typeRoots": ["node_modules/@types"] 7 | }, 8 | "include": ["../../src"] 9 | } 10 | -------------------------------------------------------------------------------- /infrastructure/typescript/tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/cjs", 5 | "module": "commonjs" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /infrastructure/typescript/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/esm", 5 | "module": "esnext" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /infrastructure/typescript/tsconfig.types.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/types", 5 | "declaration": true, 6 | "emitDeclarationOnly": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-schema-instantiator", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "json-schema-instantiator", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "chai": "^4.5.0", 13 | "mocha": "^10.8.2", 14 | "prettier": "^3.3.3", 15 | "typescript": "^5.6.3" 16 | } 17 | }, 18 | "node_modules/ansi-colors": { 19 | "version": "4.1.3", 20 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", 21 | "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", 22 | "dev": true, 23 | "license": "MIT", 24 | "engines": { 25 | "node": ">=6" 26 | } 27 | }, 28 | "node_modules/ansi-regex": { 29 | "version": "5.0.1", 30 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 31 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 32 | "dev": true, 33 | "engines": { 34 | "node": ">=8" 35 | } 36 | }, 37 | "node_modules/ansi-styles": { 38 | "version": "4.3.0", 39 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 40 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 41 | "dev": true, 42 | "dependencies": { 43 | "color-convert": "^2.0.1" 44 | }, 45 | "engines": { 46 | "node": ">=8" 47 | }, 48 | "funding": { 49 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 50 | } 51 | }, 52 | "node_modules/anymatch": { 53 | "version": "3.1.3", 54 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 55 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 56 | "dev": true, 57 | "dependencies": { 58 | "normalize-path": "^3.0.0", 59 | "picomatch": "^2.0.4" 60 | }, 61 | "engines": { 62 | "node": ">= 8" 63 | } 64 | }, 65 | "node_modules/argparse": { 66 | "version": "2.0.1", 67 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 68 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 69 | "dev": true 70 | }, 71 | "node_modules/assertion-error": { 72 | "version": "1.1.0", 73 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 74 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 75 | "dev": true, 76 | "engines": { 77 | "node": "*" 78 | } 79 | }, 80 | "node_modules/balanced-match": { 81 | "version": "1.0.2", 82 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 83 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 84 | "dev": true, 85 | "license": "MIT" 86 | }, 87 | "node_modules/binary-extensions": { 88 | "version": "2.2.0", 89 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 90 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 91 | "dev": true, 92 | "engines": { 93 | "node": ">=8" 94 | } 95 | }, 96 | "node_modules/brace-expansion": { 97 | "version": "2.0.1", 98 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 99 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 100 | "dev": true, 101 | "license": "MIT", 102 | "dependencies": { 103 | "balanced-match": "^1.0.0" 104 | } 105 | }, 106 | "node_modules/braces": { 107 | "version": "3.0.3", 108 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 109 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 110 | "dev": true, 111 | "license": "MIT", 112 | "dependencies": { 113 | "fill-range": "^7.1.1" 114 | }, 115 | "engines": { 116 | "node": ">=8" 117 | } 118 | }, 119 | "node_modules/browser-stdout": { 120 | "version": "1.3.1", 121 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 122 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 123 | "dev": true 124 | }, 125 | "node_modules/camelcase": { 126 | "version": "6.3.0", 127 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 128 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 129 | "dev": true, 130 | "engines": { 131 | "node": ">=10" 132 | }, 133 | "funding": { 134 | "url": "https://github.com/sponsors/sindresorhus" 135 | } 136 | }, 137 | "node_modules/chai": { 138 | "version": "4.5.0", 139 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", 140 | "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", 141 | "dev": true, 142 | "license": "MIT", 143 | "dependencies": { 144 | "assertion-error": "^1.1.0", 145 | "check-error": "^1.0.3", 146 | "deep-eql": "^4.1.3", 147 | "get-func-name": "^2.0.2", 148 | "loupe": "^2.3.6", 149 | "pathval": "^1.1.1", 150 | "type-detect": "^4.1.0" 151 | }, 152 | "engines": { 153 | "node": ">=4" 154 | } 155 | }, 156 | "node_modules/chalk": { 157 | "version": "4.1.2", 158 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 159 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 160 | "dev": true, 161 | "dependencies": { 162 | "ansi-styles": "^4.1.0", 163 | "supports-color": "^7.1.0" 164 | }, 165 | "engines": { 166 | "node": ">=10" 167 | }, 168 | "funding": { 169 | "url": "https://github.com/chalk/chalk?sponsor=1" 170 | } 171 | }, 172 | "node_modules/chalk/node_modules/supports-color": { 173 | "version": "7.2.0", 174 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 175 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 176 | "dev": true, 177 | "dependencies": { 178 | "has-flag": "^4.0.0" 179 | }, 180 | "engines": { 181 | "node": ">=8" 182 | } 183 | }, 184 | "node_modules/check-error": { 185 | "version": "1.0.3", 186 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", 187 | "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", 188 | "dev": true, 189 | "license": "MIT", 190 | "dependencies": { 191 | "get-func-name": "^2.0.2" 192 | }, 193 | "engines": { 194 | "node": "*" 195 | } 196 | }, 197 | "node_modules/chokidar": { 198 | "version": "3.5.3", 199 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 200 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 201 | "dev": true, 202 | "funding": [ 203 | { 204 | "type": "individual", 205 | "url": "https://paulmillr.com/funding/" 206 | } 207 | ], 208 | "dependencies": { 209 | "anymatch": "~3.1.2", 210 | "braces": "~3.0.2", 211 | "glob-parent": "~5.1.2", 212 | "is-binary-path": "~2.1.0", 213 | "is-glob": "~4.0.1", 214 | "normalize-path": "~3.0.0", 215 | "readdirp": "~3.6.0" 216 | }, 217 | "engines": { 218 | "node": ">= 8.10.0" 219 | }, 220 | "optionalDependencies": { 221 | "fsevents": "~2.3.2" 222 | } 223 | }, 224 | "node_modules/cliui": { 225 | "version": "7.0.4", 226 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 227 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 228 | "dev": true, 229 | "dependencies": { 230 | "string-width": "^4.2.0", 231 | "strip-ansi": "^6.0.0", 232 | "wrap-ansi": "^7.0.0" 233 | } 234 | }, 235 | "node_modules/color-convert": { 236 | "version": "2.0.1", 237 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 238 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 239 | "dev": true, 240 | "dependencies": { 241 | "color-name": "~1.1.4" 242 | }, 243 | "engines": { 244 | "node": ">=7.0.0" 245 | } 246 | }, 247 | "node_modules/color-name": { 248 | "version": "1.1.4", 249 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 250 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 251 | "dev": true 252 | }, 253 | "node_modules/debug": { 254 | "version": "4.4.0", 255 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 256 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 257 | "dev": true, 258 | "license": "MIT", 259 | "dependencies": { 260 | "ms": "^2.1.3" 261 | }, 262 | "engines": { 263 | "node": ">=6.0" 264 | }, 265 | "peerDependenciesMeta": { 266 | "supports-color": { 267 | "optional": true 268 | } 269 | } 270 | }, 271 | "node_modules/decamelize": { 272 | "version": "4.0.0", 273 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 274 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 275 | "dev": true, 276 | "engines": { 277 | "node": ">=10" 278 | }, 279 | "funding": { 280 | "url": "https://github.com/sponsors/sindresorhus" 281 | } 282 | }, 283 | "node_modules/deep-eql": { 284 | "version": "4.1.3", 285 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", 286 | "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", 287 | "dev": true, 288 | "dependencies": { 289 | "type-detect": "^4.0.0" 290 | }, 291 | "engines": { 292 | "node": ">=6" 293 | } 294 | }, 295 | "node_modules/diff": { 296 | "version": "5.2.0", 297 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", 298 | "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", 299 | "dev": true, 300 | "license": "BSD-3-Clause", 301 | "engines": { 302 | "node": ">=0.3.1" 303 | } 304 | }, 305 | "node_modules/emoji-regex": { 306 | "version": "8.0.0", 307 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 308 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 309 | "dev": true 310 | }, 311 | "node_modules/escalade": { 312 | "version": "3.1.1", 313 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 314 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 315 | "dev": true, 316 | "engines": { 317 | "node": ">=6" 318 | } 319 | }, 320 | "node_modules/escape-string-regexp": { 321 | "version": "4.0.0", 322 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 323 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 324 | "dev": true, 325 | "engines": { 326 | "node": ">=10" 327 | }, 328 | "funding": { 329 | "url": "https://github.com/sponsors/sindresorhus" 330 | } 331 | }, 332 | "node_modules/fill-range": { 333 | "version": "7.1.1", 334 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 335 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 336 | "dev": true, 337 | "license": "MIT", 338 | "dependencies": { 339 | "to-regex-range": "^5.0.1" 340 | }, 341 | "engines": { 342 | "node": ">=8" 343 | } 344 | }, 345 | "node_modules/find-up": { 346 | "version": "5.0.0", 347 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 348 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 349 | "dev": true, 350 | "dependencies": { 351 | "locate-path": "^6.0.0", 352 | "path-exists": "^4.0.0" 353 | }, 354 | "engines": { 355 | "node": ">=10" 356 | }, 357 | "funding": { 358 | "url": "https://github.com/sponsors/sindresorhus" 359 | } 360 | }, 361 | "node_modules/flat": { 362 | "version": "5.0.2", 363 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 364 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 365 | "dev": true, 366 | "bin": { 367 | "flat": "cli.js" 368 | } 369 | }, 370 | "node_modules/fs.realpath": { 371 | "version": "1.0.0", 372 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 373 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 374 | "dev": true, 375 | "license": "ISC" 376 | }, 377 | "node_modules/fsevents": { 378 | "version": "2.3.2", 379 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 380 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 381 | "dev": true, 382 | "hasInstallScript": true, 383 | "optional": true, 384 | "os": [ 385 | "darwin" 386 | ], 387 | "engines": { 388 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 389 | } 390 | }, 391 | "node_modules/get-caller-file": { 392 | "version": "2.0.5", 393 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 394 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 395 | "dev": true, 396 | "engines": { 397 | "node": "6.* || 8.* || >= 10.*" 398 | } 399 | }, 400 | "node_modules/get-func-name": { 401 | "version": "2.0.2", 402 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", 403 | "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", 404 | "dev": true, 405 | "license": "MIT", 406 | "engines": { 407 | "node": "*" 408 | } 409 | }, 410 | "node_modules/glob": { 411 | "version": "8.1.0", 412 | "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", 413 | "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", 414 | "deprecated": "Glob versions prior to v9 are no longer supported", 415 | "dev": true, 416 | "license": "ISC", 417 | "dependencies": { 418 | "fs.realpath": "^1.0.0", 419 | "inflight": "^1.0.4", 420 | "inherits": "2", 421 | "minimatch": "^5.0.1", 422 | "once": "^1.3.0" 423 | }, 424 | "engines": { 425 | "node": ">=12" 426 | }, 427 | "funding": { 428 | "url": "https://github.com/sponsors/isaacs" 429 | } 430 | }, 431 | "node_modules/glob-parent": { 432 | "version": "5.1.2", 433 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 434 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 435 | "dev": true, 436 | "dependencies": { 437 | "is-glob": "^4.0.1" 438 | }, 439 | "engines": { 440 | "node": ">= 6" 441 | } 442 | }, 443 | "node_modules/has-flag": { 444 | "version": "4.0.0", 445 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 446 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 447 | "dev": true, 448 | "engines": { 449 | "node": ">=8" 450 | } 451 | }, 452 | "node_modules/he": { 453 | "version": "1.2.0", 454 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 455 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 456 | "dev": true, 457 | "bin": { 458 | "he": "bin/he" 459 | } 460 | }, 461 | "node_modules/inflight": { 462 | "version": "1.0.6", 463 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 464 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 465 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 466 | "dev": true, 467 | "license": "ISC", 468 | "dependencies": { 469 | "once": "^1.3.0", 470 | "wrappy": "1" 471 | } 472 | }, 473 | "node_modules/inherits": { 474 | "version": "2.0.4", 475 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 476 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 477 | "dev": true, 478 | "license": "ISC" 479 | }, 480 | "node_modules/is-binary-path": { 481 | "version": "2.1.0", 482 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 483 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 484 | "dev": true, 485 | "dependencies": { 486 | "binary-extensions": "^2.0.0" 487 | }, 488 | "engines": { 489 | "node": ">=8" 490 | } 491 | }, 492 | "node_modules/is-extglob": { 493 | "version": "2.1.1", 494 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 495 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 496 | "dev": true, 497 | "engines": { 498 | "node": ">=0.10.0" 499 | } 500 | }, 501 | "node_modules/is-fullwidth-code-point": { 502 | "version": "3.0.0", 503 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 504 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 505 | "dev": true, 506 | "engines": { 507 | "node": ">=8" 508 | } 509 | }, 510 | "node_modules/is-glob": { 511 | "version": "4.0.3", 512 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 513 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 514 | "dev": true, 515 | "dependencies": { 516 | "is-extglob": "^2.1.1" 517 | }, 518 | "engines": { 519 | "node": ">=0.10.0" 520 | } 521 | }, 522 | "node_modules/is-number": { 523 | "version": "7.0.0", 524 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 525 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 526 | "dev": true, 527 | "license": "MIT", 528 | "engines": { 529 | "node": ">=0.12.0" 530 | } 531 | }, 532 | "node_modules/is-plain-obj": { 533 | "version": "2.1.0", 534 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 535 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 536 | "dev": true, 537 | "engines": { 538 | "node": ">=8" 539 | } 540 | }, 541 | "node_modules/is-unicode-supported": { 542 | "version": "0.1.0", 543 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 544 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 545 | "dev": true, 546 | "engines": { 547 | "node": ">=10" 548 | }, 549 | "funding": { 550 | "url": "https://github.com/sponsors/sindresorhus" 551 | } 552 | }, 553 | "node_modules/js-yaml": { 554 | "version": "4.1.0", 555 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 556 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 557 | "dev": true, 558 | "dependencies": { 559 | "argparse": "^2.0.1" 560 | }, 561 | "bin": { 562 | "js-yaml": "bin/js-yaml.js" 563 | } 564 | }, 565 | "node_modules/locate-path": { 566 | "version": "6.0.0", 567 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 568 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 569 | "dev": true, 570 | "dependencies": { 571 | "p-locate": "^5.0.0" 572 | }, 573 | "engines": { 574 | "node": ">=10" 575 | }, 576 | "funding": { 577 | "url": "https://github.com/sponsors/sindresorhus" 578 | } 579 | }, 580 | "node_modules/log-symbols": { 581 | "version": "4.1.0", 582 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 583 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 584 | "dev": true, 585 | "dependencies": { 586 | "chalk": "^4.1.0", 587 | "is-unicode-supported": "^0.1.0" 588 | }, 589 | "engines": { 590 | "node": ">=10" 591 | }, 592 | "funding": { 593 | "url": "https://github.com/sponsors/sindresorhus" 594 | } 595 | }, 596 | "node_modules/loupe": { 597 | "version": "2.3.6", 598 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", 599 | "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", 600 | "dev": true, 601 | "dependencies": { 602 | "get-func-name": "^2.0.0" 603 | } 604 | }, 605 | "node_modules/minimatch": { 606 | "version": "5.1.6", 607 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", 608 | "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", 609 | "dev": true, 610 | "license": "ISC", 611 | "dependencies": { 612 | "brace-expansion": "^2.0.1" 613 | }, 614 | "engines": { 615 | "node": ">=10" 616 | } 617 | }, 618 | "node_modules/mocha": { 619 | "version": "10.8.2", 620 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", 621 | "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", 622 | "dev": true, 623 | "license": "MIT", 624 | "dependencies": { 625 | "ansi-colors": "^4.1.3", 626 | "browser-stdout": "^1.3.1", 627 | "chokidar": "^3.5.3", 628 | "debug": "^4.3.5", 629 | "diff": "^5.2.0", 630 | "escape-string-regexp": "^4.0.0", 631 | "find-up": "^5.0.0", 632 | "glob": "^8.1.0", 633 | "he": "^1.2.0", 634 | "js-yaml": "^4.1.0", 635 | "log-symbols": "^4.1.0", 636 | "minimatch": "^5.1.6", 637 | "ms": "^2.1.3", 638 | "serialize-javascript": "^6.0.2", 639 | "strip-json-comments": "^3.1.1", 640 | "supports-color": "^8.1.1", 641 | "workerpool": "^6.5.1", 642 | "yargs": "^16.2.0", 643 | "yargs-parser": "^20.2.9", 644 | "yargs-unparser": "^2.0.0" 645 | }, 646 | "bin": { 647 | "_mocha": "bin/_mocha", 648 | "mocha": "bin/mocha.js" 649 | }, 650 | "engines": { 651 | "node": ">= 14.0.0" 652 | } 653 | }, 654 | "node_modules/ms": { 655 | "version": "2.1.3", 656 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 657 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 658 | "dev": true 659 | }, 660 | "node_modules/normalize-path": { 661 | "version": "3.0.0", 662 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 663 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 664 | "dev": true, 665 | "engines": { 666 | "node": ">=0.10.0" 667 | } 668 | }, 669 | "node_modules/once": { 670 | "version": "1.4.0", 671 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 672 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 673 | "dev": true, 674 | "license": "ISC", 675 | "dependencies": { 676 | "wrappy": "1" 677 | } 678 | }, 679 | "node_modules/p-limit": { 680 | "version": "3.1.0", 681 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 682 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 683 | "dev": true, 684 | "dependencies": { 685 | "yocto-queue": "^0.1.0" 686 | }, 687 | "engines": { 688 | "node": ">=10" 689 | }, 690 | "funding": { 691 | "url": "https://github.com/sponsors/sindresorhus" 692 | } 693 | }, 694 | "node_modules/p-locate": { 695 | "version": "5.0.0", 696 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 697 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 698 | "dev": true, 699 | "dependencies": { 700 | "p-limit": "^3.0.2" 701 | }, 702 | "engines": { 703 | "node": ">=10" 704 | }, 705 | "funding": { 706 | "url": "https://github.com/sponsors/sindresorhus" 707 | } 708 | }, 709 | "node_modules/path-exists": { 710 | "version": "4.0.0", 711 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 712 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 713 | "dev": true, 714 | "engines": { 715 | "node": ">=8" 716 | } 717 | }, 718 | "node_modules/pathval": { 719 | "version": "1.1.1", 720 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", 721 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", 722 | "dev": true, 723 | "engines": { 724 | "node": "*" 725 | } 726 | }, 727 | "node_modules/picomatch": { 728 | "version": "2.3.1", 729 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 730 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 731 | "dev": true, 732 | "engines": { 733 | "node": ">=8.6" 734 | }, 735 | "funding": { 736 | "url": "https://github.com/sponsors/jonschlinkert" 737 | } 738 | }, 739 | "node_modules/prettier": { 740 | "version": "3.4.2", 741 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", 742 | "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", 743 | "dev": true, 744 | "license": "MIT", 745 | "bin": { 746 | "prettier": "bin/prettier.cjs" 747 | }, 748 | "engines": { 749 | "node": ">=14" 750 | }, 751 | "funding": { 752 | "url": "https://github.com/prettier/prettier?sponsor=1" 753 | } 754 | }, 755 | "node_modules/randombytes": { 756 | "version": "2.1.0", 757 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 758 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 759 | "dev": true, 760 | "license": "MIT", 761 | "dependencies": { 762 | "safe-buffer": "^5.1.0" 763 | } 764 | }, 765 | "node_modules/readdirp": { 766 | "version": "3.6.0", 767 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 768 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 769 | "dev": true, 770 | "dependencies": { 771 | "picomatch": "^2.2.1" 772 | }, 773 | "engines": { 774 | "node": ">=8.10.0" 775 | } 776 | }, 777 | "node_modules/require-directory": { 778 | "version": "2.1.1", 779 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 780 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 781 | "dev": true, 782 | "engines": { 783 | "node": ">=0.10.0" 784 | } 785 | }, 786 | "node_modules/safe-buffer": { 787 | "version": "5.2.1", 788 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 789 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 790 | "dev": true, 791 | "funding": [ 792 | { 793 | "type": "github", 794 | "url": "https://github.com/sponsors/feross" 795 | }, 796 | { 797 | "type": "patreon", 798 | "url": "https://www.patreon.com/feross" 799 | }, 800 | { 801 | "type": "consulting", 802 | "url": "https://feross.org/support" 803 | } 804 | ], 805 | "license": "MIT" 806 | }, 807 | "node_modules/serialize-javascript": { 808 | "version": "6.0.2", 809 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", 810 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", 811 | "dev": true, 812 | "license": "BSD-3-Clause", 813 | "dependencies": { 814 | "randombytes": "^2.1.0" 815 | } 816 | }, 817 | "node_modules/string-width": { 818 | "version": "4.2.3", 819 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 820 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 821 | "dev": true, 822 | "dependencies": { 823 | "emoji-regex": "^8.0.0", 824 | "is-fullwidth-code-point": "^3.0.0", 825 | "strip-ansi": "^6.0.1" 826 | }, 827 | "engines": { 828 | "node": ">=8" 829 | } 830 | }, 831 | "node_modules/strip-ansi": { 832 | "version": "6.0.1", 833 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 834 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 835 | "dev": true, 836 | "dependencies": { 837 | "ansi-regex": "^5.0.1" 838 | }, 839 | "engines": { 840 | "node": ">=8" 841 | } 842 | }, 843 | "node_modules/strip-json-comments": { 844 | "version": "3.1.1", 845 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 846 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 847 | "dev": true, 848 | "engines": { 849 | "node": ">=8" 850 | }, 851 | "funding": { 852 | "url": "https://github.com/sponsors/sindresorhus" 853 | } 854 | }, 855 | "node_modules/supports-color": { 856 | "version": "8.1.1", 857 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 858 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 859 | "dev": true, 860 | "dependencies": { 861 | "has-flag": "^4.0.0" 862 | }, 863 | "engines": { 864 | "node": ">=10" 865 | }, 866 | "funding": { 867 | "url": "https://github.com/chalk/supports-color?sponsor=1" 868 | } 869 | }, 870 | "node_modules/to-regex-range": { 871 | "version": "5.0.1", 872 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 873 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 874 | "dev": true, 875 | "license": "MIT", 876 | "dependencies": { 877 | "is-number": "^7.0.0" 878 | }, 879 | "engines": { 880 | "node": ">=8.0" 881 | } 882 | }, 883 | "node_modules/type-detect": { 884 | "version": "4.1.0", 885 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", 886 | "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", 887 | "dev": true, 888 | "license": "MIT", 889 | "engines": { 890 | "node": ">=4" 891 | } 892 | }, 893 | "node_modules/typescript": { 894 | "version": "5.7.2", 895 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", 896 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", 897 | "dev": true, 898 | "license": "Apache-2.0", 899 | "bin": { 900 | "tsc": "bin/tsc", 901 | "tsserver": "bin/tsserver" 902 | }, 903 | "engines": { 904 | "node": ">=14.17" 905 | } 906 | }, 907 | "node_modules/workerpool": { 908 | "version": "6.5.1", 909 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", 910 | "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", 911 | "dev": true, 912 | "license": "Apache-2.0" 913 | }, 914 | "node_modules/wrap-ansi": { 915 | "version": "7.0.0", 916 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 917 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 918 | "dev": true, 919 | "dependencies": { 920 | "ansi-styles": "^4.0.0", 921 | "string-width": "^4.1.0", 922 | "strip-ansi": "^6.0.0" 923 | }, 924 | "engines": { 925 | "node": ">=10" 926 | }, 927 | "funding": { 928 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 929 | } 930 | }, 931 | "node_modules/wrappy": { 932 | "version": "1.0.2", 933 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 934 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 935 | "dev": true, 936 | "license": "ISC" 937 | }, 938 | "node_modules/y18n": { 939 | "version": "5.0.8", 940 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 941 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 942 | "dev": true, 943 | "engines": { 944 | "node": ">=10" 945 | } 946 | }, 947 | "node_modules/yargs": { 948 | "version": "16.2.0", 949 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 950 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 951 | "dev": true, 952 | "dependencies": { 953 | "cliui": "^7.0.2", 954 | "escalade": "^3.1.1", 955 | "get-caller-file": "^2.0.5", 956 | "require-directory": "^2.1.1", 957 | "string-width": "^4.2.0", 958 | "y18n": "^5.0.5", 959 | "yargs-parser": "^20.2.2" 960 | }, 961 | "engines": { 962 | "node": ">=10" 963 | } 964 | }, 965 | "node_modules/yargs-parser": { 966 | "version": "20.2.9", 967 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", 968 | "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", 969 | "dev": true, 970 | "license": "ISC", 971 | "engines": { 972 | "node": ">=10" 973 | } 974 | }, 975 | "node_modules/yargs-unparser": { 976 | "version": "2.0.0", 977 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 978 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 979 | "dev": true, 980 | "dependencies": { 981 | "camelcase": "^6.0.0", 982 | "decamelize": "^4.0.0", 983 | "flat": "^5.0.2", 984 | "is-plain-obj": "^2.1.0" 985 | }, 986 | "engines": { 987 | "node": ">=10" 988 | } 989 | }, 990 | "node_modules/yocto-queue": { 991 | "version": "0.1.0", 992 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 993 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 994 | "dev": true, 995 | "engines": { 996 | "node": ">=10" 997 | }, 998 | "funding": { 999 | "url": "https://github.com/sponsors/sindresorhus" 1000 | } 1001 | } 1002 | } 1003 | } 1004 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-schema-instantiator", 3 | "version": "1.0.0", 4 | "description": "A simple instantiator for json schemas.", 5 | "main": "dist/cjs/instantiator.js", 6 | "module": "dist/esm/instantiator.mjs", 7 | "types": "dist/types/instantiator.d.ts", 8 | "exports": { 9 | ".": { 10 | "types": "./dist/types/instantiator.d.ts", 11 | "import": "./dist/esm/instantiator.mjs", 12 | "require": "./dist/cjs/instantiator.js" 13 | } 14 | }, 15 | "scripts": { 16 | "build": "node --unhandled-rejections=strict infrastructure/package_scripts/build.mjs", 17 | "build_infrastructure": "node --unhandled-rejections=strict infrastructure/package_scripts/build_infrastructure.mjs", 18 | "clean": "node --unhandled-rejections=strict infrastructure/package_scripts/clean.mjs", 19 | "format": "node --unhandled-rejections=strict infrastructure/package_scripts/format.mjs", 20 | "prepack": "node --unhandled-rejections=strict infrastructure/package_scripts/prepack.mjs", 21 | "test": "node --unhandled-rejections=strict infrastructure/package_scripts/test.mjs" 22 | }, 23 | "keywords": [ 24 | "JSON", 25 | "schema", 26 | "instantiate", 27 | "instantiator", 28 | "JSON-Schema", 29 | "Generator", 30 | "Generate", 31 | "Data Generation" 32 | ], 33 | "authors": [ 34 | "Tom Arad", 35 | "Samuel Batista (https://sambatista.com) " 36 | ], 37 | "license": "MIT", 38 | "repository": { 39 | "type": "git", 40 | "url": "https://github.com/tomarad/JSON-Schema-Instantiator" 41 | }, 42 | "devDependencies": { 43 | "chai": "^4.5.0", 44 | "mocha": "^10.8.2", 45 | "prettier": "^3.3.3", 46 | "typescript": "^5.6.3" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/instantiator.ts: -------------------------------------------------------------------------------- 1 | // The JSON Object that defines the default values of certain types. 2 | var typesInstantiator = { 3 | string: '', 4 | number: 0, 5 | integer: 0, 6 | null: null, 7 | boolean: false, // Always stay positive? 8 | object: {} 9 | }; 10 | 11 | type InstanciatorTypes = keyof typeof typesInstantiator; 12 | 13 | /** 14 | * Checks whether a variable is a primitive. 15 | * @param obj - an object. 16 | * @returns {boolean} 17 | */ 18 | function isPrimitive(obj) { 19 | var type = obj.type; 20 | 21 | return typesInstantiator[type] !== undefined; 22 | } 23 | 24 | /** 25 | * Checks whether a property is on required array. 26 | * @param property - the property to check. 27 | * @param requiredArray - the required array 28 | * @returns {boolean} 29 | */ 30 | function isPropertyRequired(property, requiredArray) { 31 | var found = false; 32 | requiredArray = requiredArray || []; 33 | for (var requiredProperty of requiredArray) { 34 | if (requiredProperty === property) { 35 | found = true; 36 | } 37 | } 38 | return found; 39 | } 40 | 41 | function shouldVisit(property, obj, options) { 42 | return ( 43 | !options.requiredPropertiesOnly || (options.requiredPropertiesOnly && isPropertyRequired(property, obj.required)) 44 | ); 45 | } 46 | 47 | /** 48 | * Instantiate a primitive. 49 | * @param {Object} val - The object that represents the primitive. 50 | * @param {String} val.type 51 | * @param {Any} [val.default] 52 | * @param {Object.} [defaults] 53 | * @returns {*} 54 | */ 55 | function instantiatePrimitive(val, defaults) { 56 | defaults = defaults || {}; 57 | 58 | var type = val.type; 59 | 60 | // Support for default values in the JSON Schema. 61 | if (Object.prototype.hasOwnProperty.call(val, 'default')) { 62 | return val.default; 63 | } 64 | 65 | // Support for provided default values. 66 | if (Object.prototype.hasOwnProperty.call(defaults, type)) { 67 | if (typeof defaults[type] === 'function') { 68 | return defaults[type](val); 69 | } 70 | return defaults[type]; 71 | } 72 | 73 | return typesInstantiator[type]; 74 | } 75 | 76 | function instantiateArray(val, visit, defaults) { 77 | defaults = defaults || {}; 78 | 79 | var type = val.type; 80 | 81 | // Support for default values in the JSON Schema. 82 | if (Object.prototype.hasOwnProperty.call(val, 'default')) { 83 | return val.default; 84 | } 85 | 86 | // Support for provided default values. 87 | if (Object.prototype.hasOwnProperty.call(defaults, type)) { 88 | if (typeof defaults[type] === 'function') { 89 | return defaults[type](val); 90 | } 91 | 92 | return defaults[type]; 93 | } 94 | 95 | var result = []; 96 | var len = 0; 97 | if (val.minItems || val.minItems > 0) { 98 | len = val.minItems; 99 | } 100 | 101 | // Instantiate 'len' items. 102 | for (var i = 0; i < len; i++) { 103 | visit(val.items, i, result); 104 | } 105 | 106 | return result; 107 | } 108 | 109 | /** 110 | * Checks whether a variable is an enum. 111 | * @param obj - an object. 112 | * @returns {boolean} 113 | */ 114 | function isEnum(obj) { 115 | return Object.prototype.toString.call(obj.enum) === '[object Array]'; 116 | } 117 | 118 | /** 119 | * Checks whether a variable is an array. 120 | * @param obj - an object. 121 | * @returns {boolean} 122 | */ 123 | function isArray(obj) { 124 | return Array.isArray(obj); 125 | } 126 | 127 | /** 128 | * Extracts the type of the object. 129 | * If the type is an array, set type to first in list of types. 130 | * If obj.type is not overridden, it will fail the isPrimitive check. 131 | * Which internally also checks obj.type. 132 | * @param obj - An object. 133 | */ 134 | function getObjectType(obj) { 135 | // Check if type is array of types. 136 | if (isArray(obj.type)) { 137 | obj.type = obj.type[0]; 138 | } 139 | if (obj.type) { 140 | return obj.type; 141 | } 142 | if (obj.const !== undefined) { 143 | return 'const'; 144 | } 145 | return undefined; 146 | } 147 | 148 | /** 149 | * Instantiate an enum. 150 | * @param val - The object that represents the primitive. 151 | * @returns {*} 152 | */ 153 | function instantiateEnum(val) { 154 | // Support for default values in the JSON Schema. 155 | if (val.default) { 156 | return val.default; 157 | } 158 | if (!val.enum.length) { 159 | return undefined; 160 | } 161 | return val.enum[0]; 162 | } 163 | 164 | /** 165 | * Finds a definition in a schema. 166 | * Useful for finding references. 167 | * 168 | * @param schema The full schema object. 169 | * @param ref The reference to find. 170 | * @return {*} The object representing the ref. 171 | */ 172 | function findDefinition(schema, ref) { 173 | var propertyPath = ref.split('/').slice(1); // Ignore the #/uri at the beginning. 174 | var currentProperty = propertyPath.splice(0, 1)[0]; 175 | var currentValue = schema; 176 | 177 | while (currentProperty) { 178 | currentValue = currentValue[currentProperty]; 179 | currentProperty = propertyPath.splice(0, 1)[0]; 180 | } 181 | 182 | return currentValue; 183 | } 184 | 185 | /** 186 | * The main function. 187 | * Calls sub-objects recursively, depth first, using the sub-function 'visit'. 188 | * 189 | * @param {Object} schema - The schema to instantiate. 190 | * @param {Object} [options] 191 | * @param {Boolean} [options.requiredPropertiesOnly] 192 | * @param {Object.} [options.defaults] 193 | * @returns {*} 194 | */ 195 | export function instantiate( 196 | schema: object, 197 | options: { 198 | defaults?: Record; 199 | requiredPropertiesOnly?: boolean; 200 | } = {} 201 | ): T { 202 | /** 203 | * Visits each sub-object using recursion. 204 | * If it reaches a primitive, instantiate it. 205 | * @param obj - The object that represents the schema. 206 | * @param name - The name of the current object. 207 | * @param data - The instance data that represents the current object. 208 | */ 209 | function visit(obj, name, data) { 210 | if (!obj) { 211 | return; 212 | } 213 | 214 | var type = getObjectType(obj); 215 | 216 | // We want non-primitives objects (primitive === object w/o properties). 217 | if (type === 'object' && obj.properties) { 218 | data[name] = data[name] || {}; 219 | 220 | // Visit each property. 221 | for (var property in obj.properties) { 222 | if (Object.prototype.hasOwnProperty.call(obj.properties, property)) { 223 | if (shouldVisit(property, obj, options)) { 224 | visit(obj.properties[property], property, data[name]); 225 | } 226 | } 227 | } 228 | } else if (obj.allOf) { 229 | for (var i = 0; i < obj.allOf.length; i++) { 230 | visit(obj.allOf[i], name, data); 231 | } 232 | } else if (obj.$ref) { 233 | obj = findDefinition(schema, obj.$ref); 234 | visit(obj, name, data); 235 | } else if (type === 'array') { 236 | data[name] = instantiateArray(obj, visit, options.defaults); 237 | } else if (isEnum(obj)) { 238 | data[name] = instantiateEnum(obj); 239 | } else if (isPrimitive(obj)) { 240 | data[name] = instantiatePrimitive(obj, options.defaults); 241 | } else if (type === 'const') { 242 | data[name] = obj.const; 243 | } 244 | } 245 | 246 | var data = { __temp__: null }; 247 | visit(schema, '__temp__', data); 248 | return data['__temp__'] as T; 249 | } 250 | 251 | export default instantiate; 252 | -------------------------------------------------------------------------------- /tests/tests.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | 3 | var instantiate = require('../dist/cjs/instantiator').instantiate; 4 | 5 | var schema, expected, result; 6 | 7 | describe('Primitives', function () { 8 | it('should instantiate string', function () { 9 | schema = { 10 | type: 'string' 11 | }; 12 | result = instantiate(schema); 13 | expected = ''; 14 | expect(result).to.deep.equal(expected); 15 | }); 16 | 17 | it('should instantiate number', function () { 18 | schema = { 19 | type: 'number' 20 | }; 21 | result = instantiate(schema); 22 | expected = 0; 23 | expect(result).to.deep.equal(expected); 24 | }); 25 | 26 | it('should instantiate boolean', function () { 27 | schema = { 28 | type: 'boolean' 29 | }; 30 | result = instantiate(schema); 31 | expected = false; 32 | expect(result).to.deep.equal(expected); 33 | }); 34 | 35 | it('should instantiate null', function () { 36 | schema = { 37 | type: 'null' 38 | }; 39 | result = instantiate(schema); 40 | expected = null; 41 | expect(result).to.deep.equal(expected); 42 | }); 43 | 44 | it('should use default property', function () { 45 | schema = { 46 | type: 'number', 47 | default: 100 48 | }; 49 | result = instantiate(schema); 50 | expected = 100; 51 | expect(result).to.deep.equal(expected); 52 | }); 53 | 54 | it('should support array of types', function () { 55 | schema = { 56 | type: ['string', 'null'] 57 | }; 58 | result = instantiate(schema); 59 | expected = ''; 60 | expect(result).to.deep.equal(expected); 61 | }); 62 | }); 63 | 64 | describe('Objects', function () { 65 | it('should instantiate object without properties', function () { 66 | schema = { 67 | type: 'object' 68 | }; 69 | result = instantiate(schema); 70 | expected = {}; 71 | expect(result).to.deep.equal(expected); 72 | }); 73 | 74 | it('should instantiate object with property', function () { 75 | schema = { 76 | type: 'object', 77 | properties: { 78 | title: { 79 | type: 'string' 80 | } 81 | } 82 | }; 83 | result = instantiate(schema); 84 | expected = { 85 | title: '' 86 | }; 87 | expect(result).to.deep.equal(expected); 88 | }); 89 | 90 | it('should instantiate object with property with default value', function () { 91 | schema = { 92 | type: 'object', 93 | properties: { 94 | title: { 95 | type: 'string', 96 | default: 'Example' 97 | } 98 | } 99 | }; 100 | result = instantiate(schema); 101 | expected = { 102 | title: 'Example' 103 | }; 104 | expect(result).to.deep.equal(expected); 105 | }); 106 | 107 | it('should instantiate object with more than one property', function () { 108 | schema = { 109 | type: 'object', 110 | properties: { 111 | title: { 112 | type: 'string', 113 | default: 'Example' 114 | }, 115 | amount: { 116 | type: 'number', 117 | default: 10 118 | } 119 | } 120 | }; 121 | result = instantiate(schema); 122 | expected = { 123 | title: 'Example', 124 | amount: 10 125 | }; 126 | expect(result).to.deep.equal(expected); 127 | }); 128 | }); 129 | 130 | describe('AllOf', function () { 131 | it('should instantiate schema with allOf', function () { 132 | schema = { 133 | allOf: [ 134 | { 135 | type: 'object', 136 | properties: { 137 | title: { 138 | type: 'string' 139 | } 140 | } 141 | }, 142 | { 143 | type: 'object', 144 | properties: { 145 | amount: { 146 | type: 'number', 147 | default: 1 148 | } 149 | } 150 | } 151 | ] 152 | }; 153 | result = instantiate(schema); 154 | expected = { 155 | title: '', 156 | amount: 1 157 | }; 158 | expect(result).to.deep.equal(expected); 159 | }); 160 | }); 161 | 162 | describe('Options', function () { 163 | it('should instantiate object without properties', function () { 164 | schema = { 165 | type: 'object' 166 | }; 167 | result = instantiate(schema, { requiredPropertiesOnly: true }); 168 | expected = {}; 169 | expect(result).to.deep.equal(expected); 170 | }); 171 | 172 | it('should instantiate object without property', function () { 173 | schema = { 174 | type: 'object', 175 | properties: { 176 | title: { 177 | type: 'string' 178 | } 179 | } 180 | }; 181 | result = instantiate(schema, { requiredPropertiesOnly: true }); 182 | expected = {}; 183 | expect(result).to.deep.equal(expected); 184 | }); 185 | 186 | it('should instantiate object with only property', function () { 187 | schema = { 188 | type: 'object', 189 | properties: { 190 | title: { 191 | type: 'string' 192 | }, 193 | description: { 194 | type: 'string' 195 | } 196 | }, 197 | required: ['title'] 198 | }; 199 | result = instantiate(schema, { requiredPropertiesOnly: true }); 200 | expected = { 201 | title: '' 202 | }; 203 | expect(result).to.deep.equal(expected); 204 | }); 205 | 206 | it('should instantiate object with all properties', function () { 207 | schema = { 208 | type: 'object', 209 | properties: { 210 | title: { 211 | type: 'string' 212 | }, 213 | description: { 214 | type: 'string' 215 | } 216 | }, 217 | required: ['title'] 218 | }; 219 | result = instantiate(schema, { requiredPropertiesOnly: false }); 220 | expected = { 221 | title: '', 222 | description: '' 223 | }; 224 | expect(result).to.deep.equal(expected); 225 | }); 226 | 227 | it('should instantiate object with all properties when empty options', function () { 228 | schema = { 229 | type: 'object', 230 | properties: { 231 | title: { 232 | type: 'string' 233 | }, 234 | description: { 235 | type: 'string' 236 | } 237 | }, 238 | required: ['title'] 239 | }; 240 | result = instantiate(schema, {}); 241 | expected = { 242 | title: '', 243 | description: '' 244 | }; 245 | expect(result).to.deep.equal(expected); 246 | }); 247 | 248 | it('should instantiate object with an empty array', function () { 249 | expected = { 250 | todos: [] 251 | }; 252 | schema = { 253 | title: 'todo', 254 | type: 'object', 255 | properties: { 256 | todos: { 257 | type: 'array', 258 | items: { 259 | type: 'integer' 260 | } 261 | } 262 | }, 263 | required: ['todos'] 264 | }; 265 | result = instantiate(schema, {}); 266 | 267 | expect(result).to.deep.equal(expected); 268 | }); 269 | 270 | it('should instantiate object with an array using minItems', function () { 271 | expected = { 272 | todos: [0, 0] 273 | }; 274 | schema = { 275 | title: 'todo', 276 | type: 'object', 277 | properties: { 278 | todos: { 279 | type: 'array', 280 | items: { 281 | type: 'integer' 282 | }, 283 | minItems: 2 284 | } 285 | }, 286 | required: ['todos'] 287 | }; 288 | result = instantiate(schema, {}); 289 | 290 | expect(result).to.deep.equal(expected); 291 | }); 292 | 293 | it('should instantiate array with provided defaults', function () { 294 | expected = { 295 | todos: [1, 2, 3] 296 | }; 297 | schema = { 298 | title: 'todo', 299 | type: 'object', 300 | properties: { 301 | todos: { 302 | type: 'array', 303 | default: [1, 2, 3], 304 | items: { 305 | type: 'integer' 306 | } 307 | } 308 | }, 309 | required: ['todos'] 310 | }; 311 | result = instantiate(schema); 312 | 313 | expect(result).to.deep.equal(expected); 314 | }); 315 | 316 | it('should instantiate array with provided function defaults', function () { 317 | expected = { 318 | todos: [1, 2, 3] 319 | }; 320 | schema = { 321 | title: 'todo', 322 | type: 'object', 323 | properties: { 324 | todos: { 325 | type: 'array', 326 | items: { 327 | type: 'integer' 328 | } 329 | } 330 | }, 331 | required: ['todos'] 332 | }; 333 | result = instantiate(schema, { 334 | defaults: { 335 | array: function () { 336 | return [1, 2, 3]; 337 | } 338 | } 339 | }); 340 | 341 | expect(result).to.deep.equal(expected); 342 | }); 343 | 344 | it('should instantiate object with provided defaults', function () { 345 | schema = { 346 | type: 'object', 347 | properties: { 348 | title: { 349 | type: 'string' 350 | }, 351 | quantity: { 352 | type: 'number' 353 | } 354 | }, 355 | required: ['title'] 356 | }; 357 | result = instantiate(schema, { 358 | defaults: { 359 | string: 'foo', 360 | number: 21 361 | } 362 | }); 363 | expected = { 364 | title: 'foo', 365 | quantity: 21 366 | }; 367 | expect(result).to.deep.equal(expected); 368 | }); 369 | 370 | it('should instantiate object with provided function defaults', function () { 371 | schema = { 372 | type: 'object', 373 | properties: { 374 | title: { 375 | type: 'string' 376 | }, 377 | birthday: { 378 | type: 'string', 379 | format: 'date' 380 | } 381 | }, 382 | required: ['start'] 383 | }; 384 | result = instantiate(schema, { 385 | defaults: { 386 | string: function (val) { 387 | var format = val.format; 388 | 389 | if (format && format === 'date') { 390 | return new Date(2021, 0, 1); 391 | } 392 | 393 | return ''; 394 | } 395 | } 396 | }); 397 | expected = { 398 | title: '', 399 | birthday: new Date(2021, 0, 1) 400 | }; 401 | expect(result).to.deep.equal(expected); 402 | }); 403 | }); 404 | 405 | describe('References', function () { 406 | // Taken from https://spacetelescope.github.io/understanding-json-schema/structuring. 407 | it('should intantiate a simple reference', function () { 408 | schema = { 409 | definitions: { 410 | address: { 411 | type: 'object', 412 | properties: { 413 | street_address: { type: 'string' }, 414 | city: { type: 'string' }, 415 | state: { type: 'string' } 416 | }, 417 | required: ['street_address', 'city', 'state'] 418 | } 419 | }, 420 | 421 | type: 'object', 422 | 423 | properties: { 424 | billing_address: { $ref: '#/definitions/address' }, 425 | shipping_address: { $ref: '#/definitions/address' } 426 | } 427 | }; 428 | 429 | result = instantiate(schema); 430 | expected = { 431 | billing_address: { street_address: '', city: '', state: '' }, 432 | shipping_address: { street_address: '', city: '', state: '' } 433 | }; 434 | 435 | expect(result).to.deep.equal(expected); 436 | }); 437 | 438 | it('should intantiate a simple reference', function () { 439 | schema = { 440 | definitions: { 441 | a: { 442 | type: 'object', 443 | properties: { 444 | x: { type: 'string', default: 'tomas' }, 445 | y: { type: 'string' }, 446 | z: { type: 'string' } 447 | } 448 | }, 449 | b: { 450 | type: 'object', 451 | properties: { 452 | aaa: { type: 'string' }, 453 | bbb: { $ref: '#/definitions/a' } 454 | } 455 | } 456 | }, 457 | 458 | type: 'object', 459 | 460 | properties: { 461 | yo: { $ref: '#/definitions/b' } 462 | } 463 | }; 464 | 465 | result = instantiate(schema); 466 | expected = { 467 | yo: { aaa: '', bbb: { x: 'tomas', y: '', z: '' } } 468 | }; 469 | 470 | expect(result).to.deep.equal(expected); 471 | }); 472 | 473 | // Taken from https://cswr.github.io/JsonSchema/spec/definitions_references. 474 | it('should instantiate a simple allOf reference', function () { 475 | schema = { 476 | definitions: { 477 | person: { 478 | type: 'object', 479 | required: ['first_name', 'last_name', 'age'], 480 | properties: { 481 | first_name: { type: 'string' }, 482 | last_name: { type: 'string' }, 483 | age: { type: 'integer' } 484 | } 485 | }, 486 | football_team: { 487 | type: 'object', 488 | required: ['name', 'league'], 489 | properties: { 490 | name: { type: 'string' }, 491 | league: { type: 'string' }, 492 | year_founded: { type: 'integer' } 493 | } 494 | } 495 | }, 496 | allOf: [{ $ref: '#/definitions/person' }, { $ref: '#/definitions/football_team' }] 497 | }; 498 | 499 | result = instantiate(schema); 500 | expected = { 501 | first_name: '', 502 | last_name: '', 503 | age: 0, 504 | name: '', 505 | league: '', 506 | year_founded: 0 507 | }; 508 | 509 | expect(result).to.deep.equal(expected); 510 | }); 511 | 512 | it('should instantiate a complex allOf reference', function () { 513 | schema = { 514 | definitions: { 515 | person: { 516 | type: 'object', 517 | required: ['first_name', 'last_name', 'age'], 518 | properties: { 519 | first_name: { type: 'string' }, 520 | last_name: { type: 'string' }, 521 | age: { type: 'integer' } 522 | } 523 | }, 524 | football_team: { 525 | type: 'object', 526 | required: ['name', 'league'], 527 | properties: { 528 | name: { type: 'string' }, 529 | league: { type: 'string' }, 530 | year_founded: { type: 'integer' } 531 | } 532 | } 533 | }, 534 | allOf: [ 535 | { $ref: '#/definitions/person' }, 536 | { 537 | type: 'object', 538 | required: ['current_club'], 539 | properties: { 540 | current_club: { $ref: '#/definitions/football_team' } 541 | } 542 | } 543 | ] 544 | }; 545 | 546 | result = instantiate(schema); 547 | expected = { 548 | first_name: '', 549 | last_name: '', 550 | age: 0, 551 | current_club: { 552 | name: '', 553 | league: '', 554 | year_founded: 0 555 | } 556 | }; 557 | 558 | expect(result).to.deep.equal(expected); 559 | }); 560 | 561 | it('should instantiate consts', function () { 562 | schema = { 563 | type: 'object', 564 | required: ['not_const', 'required_string_const', 'number_const', 'array_const', 'object_const'], 565 | properties: { 566 | not_const: { 567 | type: 'object', 568 | required: ['const'], 569 | properties: { 570 | const: { type: 'string', default: 'test' } 571 | } 572 | }, 573 | required_string_const: { 574 | const: 'test' 575 | }, 576 | not_required_string_const: { 577 | const: 'test' 578 | }, 579 | number_const: { 580 | const: 0 581 | }, 582 | array_const: { 583 | const: [1, 2, 3] 584 | }, 585 | object_const: { 586 | const: { 587 | test: 'test' 588 | } 589 | } 590 | } 591 | }; 592 | 593 | result = instantiate(schema); 594 | expected = { 595 | not_const: { 596 | const: 'test' 597 | }, 598 | required_string_const: 'test', 599 | not_required_string_const: 'test', 600 | number_const: 0, 601 | array_const: [1, 2, 3], 602 | object_const: { 603 | test: 'test' 604 | } 605 | }; 606 | 607 | expect(result).to.deep.equal(expected); 608 | }); 609 | }); 610 | --------------------------------------------------------------------------------