diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 98528cfb..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,78 +0,0 @@ -/* - Rules Severity - - 0 = off - - 1 = warn - - 2 = error -*/ -{ - "env": { - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaFeatures": { - "impliedStrict": true - }, - "ecmaVersion": "latest", - "project": "./tsconfig.json", - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - // Javscript Specific Rules That Are Applied To Typescript Too - "max-len": [ - "error", - { - "code": 80, - "ignoreComments": true, - "ignorePattern": "^(import)|(it\\()", - "ignoreTemplateLiterals": true - } - ], - "no-console": 1, - "quotes": [ - 2, - "single" - ], - "semi": 2, - "sort-keys": [ - 2, - "asc", - { - "caseSensitive": true, - "natural": false, - "minKeys": 2 - } - ], - // Typescript Specific Rules From This Point On - "typescript-sort-keys/string-enum": 0, - "@typescript-eslint/explicit-function-return-type": 2, - "@typescript-eslint/no-explicit-any": 2, - "@typescript-eslint/no-inferrable-types": 2, - "@typescript-eslint/no-misused-promises": [ - "error", - { - "checksVoidReturn": false - } - ], - "@typescript-eslint/no-non-null-assertion": 2, - "@typescript-eslint/no-unsafe-call": 2, - "@typescript-eslint/no-unsafe-member-access": 2, - "@typescript-eslint/no-unused-vars": [ - 2, - { - "argsIgnorePattern": "_", - "ignoreRestSiblings": true - } - ], - "@typescript-eslint/no-var-requires": 2, - "@typescript-eslint/require-await": 2 - } -} \ No newline at end of file diff --git a/.npmignore b/.npmignore index 0c46b03e..85cce119 100644 --- a/.npmignore +++ b/.npmignore @@ -1,23 +1,15 @@ src -test +src/test typings bundled build coverage docs wiki -bower.json -karma.conf.js tsconfig.json -typings.json CONTRIBUTING.md ISSUE_TEMPLATE.md PULL_REQUEST_TEMPLATE.md -tslint.json -wallaby.js -.travis.yml .gitignore .vscode -type_definitions -.eslintrc.json .github/ diff --git a/.publishrc b/.publishrc deleted file mode 100644 index 53ce782c..00000000 --- a/.publishrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "validations": { - "vulnerableDependencies": true, - "uncommittedChanges": true, - "untrackedFiles": true, - "sensitiveData": true, - "branch": "master", - "gitTag": true - }, - "confirm": true, - "publishTag": "latest", - "prePublishScript": "npm test" -} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ea9cfd3d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: node_js -node_js: -- stable -- 8.8.1 -before_install: -- npm install -g codeclimate-test-reporter -after_success: -- codeclimate-test-reporter < coverage/lcov.info diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index 5358fac7..00000000 --- a/eslint.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = [ - { - ignores: ["lib/", "es/", "es6/", "*.d.ts", "src/**/*.js", "test/**/*.js", ".eslintrc.js", "jest.config.js", "coverage"] - } -]; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..5b0e2572 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,177 @@ +// @ts-check + +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import eslintPrettierConfig from 'eslint-plugin-prettier/recommended'; +import simpleImportSort from 'eslint-plugin-simple-import-sort'; + +/** + * @returns {import('typescript-eslint').ConfigWithExtends} + */ +function buildBaseConfig() { + return { + extends: [ + eslint.configs.recommended, + ...tseslint.configs.strictTypeChecked, + ], + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: './tsconfig.json', + }, + }, + plugins: { + '@typescript-eslint': tseslint.plugin, + 'simple-import-sort': simpleImportSort, + }, + rules: { + '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], + '@typescript-eslint/explicit-member-accessibility': [ + 'error', + { + overrides: { + constructors: 'no-public', + }, + }, + ], + '@typescript-eslint/member-ordering': ['warn'], + '@typescript-eslint/naming-convention': [ + 'error', + { + selector: ['classProperty'], + format: ['strictCamelCase', 'UPPER_CASE', 'snake_case'], + leadingUnderscore: 'allow', + }, + { + selector: 'typeParameter', + format: ['StrictPascalCase'], + prefix: ['T'], + }, + { + selector: ['typeLike'], + format: ['StrictPascalCase'], + }, + { + selector: ['function', 'classMethod'], + format: ['strictCamelCase'], + leadingUnderscore: 'allow', + }, + { + selector: ['parameter'], + format: ['strictCamelCase'], + leadingUnderscore: 'allow', + }, + { + selector: ['variableLike'], + format: ['strictCamelCase', 'UPPER_CASE', 'snake_case'], + }, + ], + '@typescript-eslint/no-deprecated': 'error', + '@typescript-eslint/no-duplicate-type-constituents': 'off', + '@typescript-eslint/no-dynamic-delete': 'error', + '@typescript-eslint/no-extraneous-class': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-empty-interface': 'warn', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-floating-promises': ['error'], + '@typescript-eslint/no-unsafe-enum-comparison': 'off', + 'no-magic-numbers': 'off', + '@typescript-eslint/no-magic-numbers': [ + 'warn', + { + ignore: [0, 1], + ignoreArrayIndexes: true, + ignoreEnums: true, + ignoreReadonlyClassProperties: true, + }, + ], + '@typescript-eslint/no-require-imports': 'error', + '@typescript-eslint/no-unnecessary-type-arguments': 'off', + '@typescript-eslint/no-unused-expressions': ['error'], + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/prefer-for-of': 'error', + '@typescript-eslint/prefer-nullish-coalescing': ['off'], + '@typescript-eslint/prefer-optional-chain': 'off', + '@typescript-eslint/prefer-readonly': ['warn'], + '@typescript-eslint/promise-function-async': ['error'], + '@typescript-eslint/require-await': 'off', + '@typescript-eslint/restrict-plus-operands': [ + 'error', + { + skipCompoundAssignments: false, + }, + ], + '@typescript-eslint/typedef': [ + 'error', + { + arrayDestructuring: true, + arrowParameter: true, + memberVariableDeclaration: true, + objectDestructuring: true, + parameter: true, + propertyDeclaration: true, + variableDeclaration: true, + }, + ], + '@typescript-eslint/unified-signatures': 'error', + '@typescript-eslint/strict-boolean-expressions': 'error', + '@typescript-eslint/switch-exhaustiveness-check': [ + 'error', + { + considerDefaultExhaustiveForUnions: true, + }, + ], + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + args: 'all', + argsIgnorePattern: '^_', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true, + }, + ], + 'simple-import-sort/imports': [ + 'error', + { + groups: [['^\\u0000'], ['^node:'], ['^@?\\w'], ['^'], ['^\\.']], + }, + ], + 'sort-keys': [ + 'error', + 'asc', + { + caseSensitive: false, + natural: true, + }, + ], + }, + }; +} + +const baseRules = buildBaseConfig(); + +const config = tseslint.config( + { + ...baseRules, + files: ['**/*.ts'], + ignores: ['**/*.test.ts'], + }, + { + ...baseRules, + files: ['**/*.test.ts'], + rules: { + ...(baseRules.rules ?? {}), + '@typescript-eslint/no-confusing-void-expression': 'off', + '@typescript-eslint/unbound-method': 'off', + '@typescript-eslint/no-magic-numbers': 'off', + }, + }, + /** @type {import('typescript-eslint').ConfigWithExtends} */ ( + eslintPrettierConfig + ), +); + +export default [...config]; diff --git a/jest.config.json b/jest.config.json index 54aa69bd..c8875aa3 100644 --- a/jest.config.json +++ b/jest.config.json @@ -13,7 +13,7 @@ ], "rootDir": ".", "setupFilesAfterEnv": [ - "/test/helpers/jest.setup.ts" + "/src/test/helpers/jest.setup.ts" ], "testEnvironment": "node", "testPathIgnorePatterns": [ diff --git a/package-lock.json b/package-lock.json index 5b2645e1..7fcfc634 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,29 +12,36 @@ "http-status-codes": "2.3.0" }, "devDependencies": { - "@types/async": "3.2.24", + "@eslint/js": "9.18.0", + "@jest/globals": "29.7.0", + "@rollup/plugin-terser": "0.4.4", + "@rollup/plugin-typescript": "12.1.2", "@types/cookie-parser": "1.4.7", "@types/express": "^4.17.21", - "@types/jest": "29.5.14", - "@types/node": "20.17.1", + "@types/node": "22.10.7", "@types/supertest": "6.0.2", - "@typescript-eslint/eslint-plugin": "8.11.0", - "@typescript-eslint/parser": "8.11.0", - "async": "3.2.6", + "@typescript-eslint/eslint-plugin": "8.20.0", + "@typescript-eslint/parser": "8.20.0", "cookie-parser": "1.4.7", - "eslint": "9.12.0", - "eslint-plugin-import": "2.31.0", + "eslint": "9.18.0", + "eslint-config-prettier": "10.0.1", + "eslint-plugin-prettier": "5.2.2", + "eslint-plugin-simple-import-sort": "12.1.1", "jest": "29.7.0", - "publish-please": "5.5.2", + "prettier": "3.4.2", "reflect-metadata": "0.2.2", + "rimraf": "6.0.1", + "rollup-plugin-dts": "6.1.1", "supertest": "6.3.4", "ts-jest": "29.2.5", + "ts-loader": "9.5.2", "typescript": "5.6.3", - "updates": "15.3.1" + "typescript-eslint": "8.20.0" }, "peerDependencies": { "express": "^4.21.1", - "inversify": "^6.0.3" + "inversify": "^6.0.3", + "reflect-metadata": "~0.2.2" } }, "node_modules/@ampproject/remapping": { @@ -584,9 +591,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { @@ -594,13 +601,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.4", + "@eslint/object-schema": "^2.1.5", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -633,19 +640,22 @@ } }, "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "license": "MIT", "dependencies": { @@ -691,9 +701,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", - "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", "dev": true, "license": "MIT", "engines": { @@ -701,9 +711,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -711,12 +721,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", - "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@eslint/core": "^0.10.0", "levn": "^0.4.1" }, "engines": { @@ -724,9 +735,9 @@ } }, "node_modules/@humanfs/core": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", - "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -734,19 +745,33 @@ } }, "node_modules/@humanfs/node": { - "version": "0.16.5", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", - "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.0", + "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -762,9 +787,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -815,6 +840,109 @@ "reflect-metadata": "0.2.2" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1259,6 +1387,17 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -1315,141 +1454,535 @@ "node": ">= 8" } }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" } }, - "node_modules/@types/async": { - "version": "3.2.24", - "resolved": "https://registry.npmjs.org/@types/async/-/async-3.2.24.tgz", - "integrity": "sha512-8iHVLHsCCOBKjCF2KwFe0p9Z3rfM9mL+sSP8btyR5vTjJRAqpBYD28/ZLgXPf0pjG1VxOvtCV/BgXkQbpSe8Hw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "node_modules/@rollup/plugin-typescript": { + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.2.tgz", + "integrity": "sha512-cdtSp154H5sv637uMr1a8OTWB0L1SWDSm1rDGiyfcGcvQ6cuTs4MDk2BVEBGysUWago4OJN4EQZqOTl/QY3Jgg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.0.0" + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0||^4.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } } }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.31.0.tgz", + "integrity": "sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } + "optional": true, + "os": [ + "android" + ], + "peer": true }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.31.0.tgz", + "integrity": "sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" - } + "optional": true, + "os": [ + "android" + ], + "peer": true }, - "node_modules/@types/cookie-parser": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.7.tgz", - "integrity": "sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.31.0.tgz", + "integrity": "sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@types/express": "*" - } + "optional": true, + "os": [ + "darwin" + ], + "peer": true }, - "node_modules/@types/cookiejar": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", - "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.31.0.tgz", + "integrity": "sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.31.0.tgz", + "integrity": "sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.31.0.tgz", + "integrity": "sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.31.0.tgz", + "integrity": "sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.31.0.tgz", + "integrity": "sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.31.0.tgz", + "integrity": "sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.31.0.tgz", + "integrity": "sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.31.0.tgz", + "integrity": "sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.31.0.tgz", + "integrity": "sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.31.0.tgz", + "integrity": "sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.31.0.tgz", + "integrity": "sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.31.0.tgz", + "integrity": "sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.31.0.tgz", + "integrity": "sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.31.0.tgz", + "integrity": "sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.31.0.tgz", + "integrity": "sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.31.0.tgz", + "integrity": "sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cookie-parser": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.7.tgz", + "integrity": "sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", + "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1516,17 +2049,6 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/jest": { - "version": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", - "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1534,13 +2056,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/methods": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", @@ -1556,13 +2071,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.17.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.1.tgz", - "integrity": "sha512-j2VlPv1NnwPJbaCNv69FO/1z4lId0QmGvpT41YxitRtWlg96g/j8qcv2RKsLKe2F6OJgyXhupN1Xo17b2m139Q==", + "version": "22.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz", + "integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.20.0" } }, "node_modules/@types/qs": { @@ -1651,21 +2166,21 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", - "integrity": "sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.20.0.tgz", + "integrity": "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/type-utils": "8.11.0", - "@typescript-eslint/utils": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/type-utils": "8.20.0", + "@typescript-eslint/utils": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1676,25 +2191,21 @@ }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", - "integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.20.0.tgz", + "integrity": "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/typescript-estree": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/typescript-estree": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", "debug": "^4.3.4" }, "engines": { @@ -1705,23 +2216,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", - "integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", + "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0" + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1732,16 +2239,16 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz", - "integrity": "sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.20.0.tgz", + "integrity": "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.11.0", - "@typescript-eslint/utils": "8.11.0", + "@typescript-eslint/typescript-estree": "8.20.0", + "@typescript-eslint/utils": "8.20.0", "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1750,16 +2257,15 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", - "integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", + "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", "dev": true, "license": "MIT", "engines": { @@ -1771,20 +2277,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", - "integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", + "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/visitor-keys": "8.11.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1793,23 +2299,21 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", - "integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", + "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.11.0", - "@typescript-eslint/types": "8.11.0", - "@typescript-eslint/typescript-estree": "8.11.0" + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/typescript-estree": "8.20.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1819,18 +2323,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", - "integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", + "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.11.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.20.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1840,6 +2345,211 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1855,9 +2565,9 @@ } }, "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", "bin": { @@ -1894,6 +2604,62 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1957,270 +2723,71 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "peer": true }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT", - "peer": true - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true, - "license": "MIT" - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" + "node": ">=8" } }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { @@ -2317,38 +2884,6 @@ "dev": true, "license": "MIT" }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", @@ -2381,2330 +2916,876 @@ "license": "MIT", "peer": true, "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT", - "peer": true - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "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", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001669", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", - "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true, - "license": "MIT" - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", - "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true, - "license": "ISC" - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-parser": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz", - "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cookie": "0.7.2", - "cookie-signature": "1.0.6" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true, - "license": "MIT" - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cp-sugar": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cp-sugar/-/cp-sugar-1.0.0.tgz", - "integrity": "sha512-s5Vc9FRSxFTuweU5Yjb33Dx2jTDNm1MrEEA5mQpyxc4l/C2cFJlYJlxwH5wj+hEMleUutitrDGVUv51zxqZtdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn-async": "^2.1.6", - "pinkie-promise": "^2.0.0", - "promisify-event": "^1.0.0", - "shell-quote": "^1.4.3" - } - }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn-async": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", - "integrity": "sha512-snteb3aVrxYYOX9e8BabYFK9WhCDhTlw1YQktfTthBogxri4/2r9U2nQc0ffY73ZAxezDc+U8gvHAeU1wy1ubQ==", - "deprecated": "cross-spawn no longer requires a build toolchain, use it instead", - "dev": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.0", - "which": "^1.2.8" - } - }, - "node_modules/cross-spawn-async/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/cross-spawn-async/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/cross-spawn-async/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true, - "license": "ISC" - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "license": "MIT", - "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/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/dezalgo": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", - "dev": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT", - "peer": true - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.46", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.46.tgz", - "integrity": "sha512-1XDk0Z8/YRgB2t5GeEg8DPK592DLjVmd/5uwAu6c/S4Z0CUwV/RwYqe5GWxQqcoN3bJ5U7hYMiMRPZzpCzSBhQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/elegant-status": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/elegant-status/-/elegant-status-1.1.0.tgz", - "integrity": "sha512-3bZztYKgnSt5V8yLtf77e36jwVHU6gq9gzkSBL0s4kqfemd63HnfsAS5haQxK3ix9VEomCCW87aJn3/9KmrdBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^1.1.1", - "elegant-spinner": "^1.0.1", - "log-update": "^1.0.2", - "os-family": "^1.0.0" - } - }, - "node_modules/elegant-status/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/elegant-status/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/elegant-status/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/elegant-status/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/elegant-status/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/elegant-status/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT", - "peer": true - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", - "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.12.0", - "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", - "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" + "ms": "2.0.0" } }, - "node_modules/exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT", + "peer": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "fill-range": "^7.1.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", "dependencies": { - "ms": "2.0.0" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "license": "MIT", "dependencies": { - "is-descriptor": "^0.1.0" + "fast-json-stable-stringify": "2.x" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "node-int64": "^0.4.0" } }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "license": "MIT", "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "node_modules/caniuse-lite": { + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", + "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/express/node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, "license": "MIT", "peer": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=6.0" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "license": "MIT", - "peer": true + "engines": { + "node": ">=8" + } }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "node_modules/cjs-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/extglob/node_modules/extend-shallow": { + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { - "is-extendable": "^0.1.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=7.0.0" } }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "license": "ISC", + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "peer": true, "dependencies": { - "is-glob": "^4.0.1" + "safe-buffer": "5.2.1" }, "engines": { - "node": ">= 6" + "node": ">= 0.6" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "node_modules/cookie-parser": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz", + "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "reusify": "^1.0.4" + "cookie": "0.7.2", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } + "license": "MIT" }, - "node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, "license": "MIT", "dependencies": { - "escape-string-regexp": "^1.0.5" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" }, "engines": { - "node": ">=4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, "engines": { - "node": ">=0.8.0" + "node": ">= 8" } }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^4.0.0" + "ms": "^2.1.3" }, "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" }, - "engines": { - "node": ">=10" + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "license": "MIT", - "peer": true, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=0.4.0" } }, - "node_modules/finalhandler/node_modules/ms": { + "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", - "peer": true + "peer": true, + "engines": { + "node": ">= 0.8" + } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, + "peer": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, "engines": { - "node": ">=16" + "node": ">=8" } }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "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==", + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "is-callable": "^1.1.3" + "asap": "^2.0.0", + "wrappy": "1" } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT", + "peer": true + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" }, "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/formidable": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", - "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", + "node_modules/electron-to-chromium": { + "version": "1.5.46", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.46.tgz", + "integrity": "sha512-1XDk0Z8/YRgB2t5GeEg8DPK592DLjVmd/5uwAu6c/S4Z0CUwV/RwYqe5GWxQqcoN3bJ5U7hYMiMRPZzpCzSBhQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "license": "MIT", - "dependencies": { - "dezalgo": "^1.0.4", - "hexoid": "^1.0.0", - "once": "^1.4.0", - "qs": "^6.11.0" + "engines": { + "node": ">=12" }, "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "peer": true, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", "dev": true, "license": "MIT", "dependencies": { - "map-cache": "^0.2.2" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.6" + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "node_modules/fs.realpath": { + "node_modules/es-define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "get-intrinsic": "^1.2.4" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.4" } }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "peer": true }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=6" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT", + "peer": true }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "node_modules/eslint": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", "dev": true, "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, "engines": { - "node": ">=8.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/eslint-config-prettier": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz", + "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" + "bin": { + "eslint-config-prettier": "build/bin/cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "node_modules/eslint-plugin-prettier": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.2.tgz", + "integrity": "sha512-1yI3/hf35wmlq66C8yOyrujQnel+v5l1Vop5Cl2I6ylyNTT1JbuUUnV3/41PzwTzcyDp/oF0jWE3HXvcH5AQOQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" }, "engines": { - "node": ">= 0.4" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "node_modules/eslint-plugin-simple-import-sort": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz", + "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "eslint": ">=5.0.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, + "license": "Apache-2.0", "engines": { - "node": ">=10.13.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/glob/node_modules/brace-expansion": { + "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -4715,7 +3796,20 @@ "concat-map": "0.0.1" } }, - "node_modules/glob/node_modules/minimatch": { + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", @@ -4728,691 +3822,782 @@ "node": "*" } }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "license": "MIT", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "get-intrinsic": "^1.1.3" + "estraverse": "^5.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=0.10" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "ISC" + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true, "license": "MIT" }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.x" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "license": "MIT", + "peer": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, "engines": { - "node": ">= 0.4" + "node": ">= 0.10.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "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==", + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", + "peer": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", + "peer": true, "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "ms": "2.0.0" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT", + "peer": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.6.0" } }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", + "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/fastq": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", + "dev": true, + "license": "ISC", "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "reusify": "^1.0.4" } }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "bser": "2.1.1" } }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=16.0.0" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", "dependencies": { - "function-bind": "^1.1.2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/hexoid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", - "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { "node": ">=8" } }, - "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, - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "peer": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", "statuses": "2.0.1", - "toidentifier": "1.0.1" + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, - "node_modules/http-status-codes": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", - "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", - "license": "MIT" - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", + "peer": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" + "ms": "2.0.0" } }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT", - "engines": { - "node": ">= 4" - } + "peer": true }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=0.8.19" + "node": ">=16" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "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.", + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/inquirer": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", - "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.0", - "figures": "^2.0.0", - "lodash": "^4.17.10", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.1.0", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=6.0.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/inquirer/node_modules/ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dev": true, "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/formidable": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "dezalgo": "^1.0.4", + "hexoid": "^1.0.0", + "once": "^1.4.0", + "qs": "^6.11.0" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" } }, - "node_modules/inquirer/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, + "peer": true, "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", - "dependencies": { - "color-name": "1.1.3" + "peer": true, + "engines": { + "node": ">= 0.6" } }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/inquirer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.8.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "license": "MIT", - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, + "license": "ISC", "engines": { - "node": ">=4" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/inversify": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.1.0.tgz", - "integrity": "sha512-x7gKeJTfLKpx/6jRVxOA2miT91G1snx3haEUKsZcQSX+wQRJPbURNosrx8hHGf5TXSRQ+aE074U/gc7+IZUqzQ==", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "@inversifyjs/common": "1.3.0", - "@inversifyjs/core": "1.3.0" + "engines": { + "node": ">=8.0.0" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "hasown": "^2.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 0.10" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10.13.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true, - "license": "MIT" + "license": "BSD-2-Clause", + "peer": true }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "*" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "license": "MIT" - }, - "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==", + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "license": "MIT", "dependencies": { - "ci-info": "^1.5.0" + "get-intrinsic": "^1.1.3" }, - "bin": { - "is-ci": "bin.js" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-ci/node_modules/ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, "license": "MIT" }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "dev": true, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "es-define-property": "^1.0.0" }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, "engines": { "node": ">= 0.4" }, @@ -5420,15 +4605,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, + "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==", "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, "engines": { "node": ">= 0.4" }, @@ -5436,182 +4617,192 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "node_modules/hexoid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", "dev": true, "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "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, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/is-fullwidth-code-point": { + "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "license": "MIT", + "peer": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/is-generator-fn": { + "node_modules/http-status-codes": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", + "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==", + "license": "MIT" + }, + "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">=6" + "node": ">=10.17.0" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", + "peer": true, "dependencies": { - "is-extglob": "^2.1.1" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 4" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, "engines": { - "node": ">=0.12.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8.19" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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.", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inversify": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.1.0.tgz", + "integrity": "sha512-x7gKeJTfLKpx/6jRVxOA2miT91G1snx3haEUKsZcQSX+wQRJPbURNosrx8hHGf5TXSRQ+aE074U/gc7+IZUqzQ==", "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@inversifyjs/common": "1.3.0", + "@inversifyjs/core": "1.3.0" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", + "peer": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.10" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5620,67 +4811,61 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "is-extglob": "^2.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=0.12.0" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/isexe": { "version": "2.0.0", @@ -5689,16 +4874,6 @@ "dev": true, "license": "ISC" }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -5770,6 +4945,22 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jake": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", @@ -6480,16 +5671,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -6529,113 +5710,49 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.toarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", - "integrity": "sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-update": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", - "integrity": "sha512-4vSow8gbiGnwdDNrpy1dyNaXWKSCIPop0EHdE8GrnngHoJujM3QhvHUN/igsYCgPoHo7pFOezlJ61Hlln0KHyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^1.0.0", - "cli-cursor": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/log-update/node_modules/cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "node_modules/log-update/node_modules/onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=6.11.5" } }, - "node_modules/log-update/node_modules/restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -6646,6 +5763,16 @@ "yallist": "^3.0.2" } }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -6679,29 +5806,6 @@ "tmpl": "1.0.5" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -6822,28 +5926,14 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": ">=16 || 14 >=14.17" } }, "node_modules/ms": { @@ -6852,36 +5942,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6899,15 +5959,13 @@ "node": ">= 0.6" } }, - "node_modules/node-emoji": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz", - "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==", + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true, "license": "MIT", - "dependencies": { - "lodash.toarray": "^4.4.0" - } + "peer": true }, "node_modules/node-int64": { "version": "0.4.0", @@ -6946,61 +6004,6 @@ "node": ">=8" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -7013,113 +6016,6 @@ "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, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "license": "MIT", - "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/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -7177,45 +6073,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-family": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/os-family/-/os-family-1.1.0.tgz", - "integrity": "sha512-E3Orl5pvDJXnVmpaAA2TeNNpNhTMl4o5HghuWhOivBjEiTnJSrMYSa5uZMek1lBEvu8kKEsa2YgVcGFVDqX/9w==", - "dev": true, - "license": "MIT" - }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7258,6 +6115,13 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7300,16 +6164,6 @@ "node": ">= 0.8" } }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7347,6 +6201,33 @@ "dev": true, "license": "MIT" }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", @@ -7361,40 +6242,17 @@ "dev": true, "license": "ISC" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", - "dependencies": { - "pinkie": "^2.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pirates": { @@ -7476,34 +6334,43 @@ "node": ">=8" } }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "node_modules/prettier": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, "engines": { - "node": ">= 0.4" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, "engines": { - "node": ">= 0.8.0" + "node": ">=6.0.0" } }, "node_modules/pretty-format": { @@ -7534,16 +6401,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/promisify-event": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/promisify-event/-/promisify-event-1.0.0.tgz", - "integrity": "sha512-mshw5LiFmdtphcuUGKyd3t6zmmgIVxrdZ8v4R1INAXHvMemUsDCqIUeq5QUIqqDfed8ZZ6uhov1PqhrdBvHOIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pinkie-promise": "^2.0.0" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -7572,266 +6429,6 @@ "node": ">= 0.10" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/publish-please": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/publish-please/-/publish-please-5.5.2.tgz", - "integrity": "sha512-jSoWJj6sXHixoRPxBNv0hURDXw1OqTb8kypobzyBSvGxEVwbGN1BLrpMbDf24g4On7X0zLQDV7+9zwXAwDJ2Og==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "chalk": "2.4.1", - "cp-sugar": "1.0.0", - "elegant-status": "1.1.0", - "inquirer": "6.2.0", - "is-ci": "1.2.1", - "lodash": "4.17.20", - "micromatch": "3.1.10", - "node-emoji": "1.8.1", - "osenv": "0.1.5", - "semver": "5.6.0" - }, - "bin": { - "publish-please": "bin/publish-please.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/publish-please/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/publish-please/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/publish-please/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/publish-please/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/publish-please/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/publish-please/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/publish-please/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/publish-please/node_modules/semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/publish-please/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/publish-please/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7895,6 +6492,16 @@ ], "license": "MIT" }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -7934,65 +6541,23 @@ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", "license": "Apache-2.0" }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -8048,14 +6613,6 @@ "node": ">=4" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true, - "license": "MIT" - }, "node_modules/resolve.exports": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", @@ -8066,72 +6623,138 @@ "node": ">=10" } }, - "node_modules/restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "license": "MIT", - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, "engines": { - "node": ">=4" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, "engines": { - "node": ">=4" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", + "node_modules/rimraf/node_modules/glob": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", + "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "mimic-fn": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=4" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">=0.12" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "node_modules/rollup": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.31.0.tgz", + "integrity": "sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw==", "dev": true, "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.31.0", + "@rollup/rollup-android-arm64": "4.31.0", + "@rollup/rollup-darwin-arm64": "4.31.0", + "@rollup/rollup-darwin-x64": "4.31.0", + "@rollup/rollup-freebsd-arm64": "4.31.0", + "@rollup/rollup-freebsd-x64": "4.31.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.31.0", + "@rollup/rollup-linux-arm-musleabihf": "4.31.0", + "@rollup/rollup-linux-arm64-gnu": "4.31.0", + "@rollup/rollup-linux-arm64-musl": "4.31.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.31.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.31.0", + "@rollup/rollup-linux-riscv64-gnu": "4.31.0", + "@rollup/rollup-linux-s390x-gnu": "4.31.0", + "@rollup/rollup-linux-x64-gnu": "4.31.0", + "@rollup/rollup-linux-x64-musl": "4.31.0", + "@rollup/rollup-win32-arm64-msvc": "4.31.0", + "@rollup/rollup-win32-ia32-msvc": "4.31.0", + "@rollup/rollup-win32-x64-msvc": "4.31.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-dts": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.1.tgz", + "integrity": "sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==", "dev": true, - "license": "MIT", + "license": "LGPL-3.0-only", + "dependencies": { + "magic-string": "^0.30.10" + }, "engines": { - "node": ">=0.12.0" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.24.2" + }, + "peerDependencies": { + "rollup": "^3.29.4 || ^4", + "typescript": "^4.5 || ^5.0" } }, "node_modules/run-parallel": { @@ -8158,38 +6781,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8208,43 +6799,35 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } + "peer": true }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" }, "engines": { - "node": ">= 0.4" + "node": ">= 10.13.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", @@ -8310,6 +6893,16 @@ "node": ">= 0.8" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -8343,61 +6936,6 @@ "node": ">= 0.4" } }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -8428,16 +6966,6 @@ "node": ">=8" } }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -8480,157 +7008,13 @@ "node": ">=8" } }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", "dev": true, "license": "MIT" }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8641,51 +7025,15 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true, - "license": "MIT" - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "license": "MIT", "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, "node_modules/sprintf-js": { @@ -8718,47 +7066,6 @@ "node": ">=8" } }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -8783,96 +7090,47 @@ "node": ">=10" } }, - "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -8994,121 +7252,246 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" } }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/synckit/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" } }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/terser-webpack-plugin": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", "dev": true, - "license": "ISC", + "license": "MIT", + "peer": true, "dependencies": { - "brace-expansion": "^1.1.7" + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { - "node": "*" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "os-tmpdir": "~1.0.2" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=0.6.0" + "node": ">= 10.13.0" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, - "license": "BSD-3-Clause" + "license": "MIT", + "peer": true }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "kind-of": "^3.0.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9133,16 +7516,16 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", + "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-jest": { @@ -9194,40 +7577,35 @@ } } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "node_modules/ts-loader": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz", + "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==", "dev": true, "license": "MIT", "dependencies": { - "minimist": "^1.2.0" + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" }, - "bin": { - "json5": "lib/cli.js" + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" } }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "engines": { - "node": ">=4" + "node": ">= 8" } }, "node_modules/tslib": { @@ -9235,7 +7613,9 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "optional": true, + "peer": true }, "node_modules/type-check": { "version": "0.4.0", @@ -9287,83 +7667,6 @@ "node": ">= 0.6" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", @@ -9378,55 +7681,36 @@ "node": ">=14.17" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "node_modules/typescript-eslint": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.20.0.tgz", + "integrity": "sha512-Kxz2QRFsgbWj6Xcftlw3Dd154b3cEPFqQC+qMZrMypSijPd4UanKKvoKDrJ4o8AIfZFKAF+7sMaEIR8mTElozA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "@typescript-eslint/eslint-plugin": "8.20.0", + "@typescript-eslint/parser": "8.20.0", + "@typescript-eslint/utils": "8.20.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true, "license": "MIT" }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -9437,65 +7721,6 @@ "node": ">= 0.8" } }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", @@ -9527,19 +7752,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/updates": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/updates/-/updates-15.3.1.tgz", - "integrity": "sha512-DqHT1aJ6p6jVLWRiAeuVx/TQotvEwUjgrY1Mlc0a2qYk+eKEQVXugQ4M+6QoVMA3X1NFAVsb02d93pmWam4bBA==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "updates": "bin/updates.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -9550,24 +7762,6 @@ "punycode": "^2.1.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true, - "license": "MIT" - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -9613,57 +7807,120 @@ "makeerror": "1.0.12" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, - "license": "ISC", + "license": "MIT", + "peer": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, "engines": { - "node": ">= 8" + "node": ">=10.13.0" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "node_modules/webpack": { + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/word-wrap": { @@ -9694,6 +7951,50 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", diff --git a/package.json b/package.json index 19794274..e6e43f38 100644 --- a/package.json +++ b/package.json @@ -4,27 +4,30 @@ "author": "Cody Simms", "description": "Some utilities for the development of express applications with Inversify", "license": "MIT", - "main": "lib/index.js", - "module": "es/index.js", + "main": "lib/cjs/index.js", + "module": "lib/esm/index.js", + "exports": { + ".": { + "import": "./lib/esm/index.js", + "require": "./lib/cjs/index.js" + } + }, "repository": { "type": "git", "url": "git+https://github.com/inversify/inversify-express-utils.git" }, "scripts": { - "build": "npm run build:lib && npm run build:es && npm run build:es6", - "build:lib": "tsc -p src/tsconfig.json", - "build:es": "tsc -p src/tsconfig-es.json", - "build:es6": "tsc -p src/tsconfig-es6.json", - "clean": "rm -r es es6 lib", - "eslint:fix": "eslint --fix ./", + "build": "npm run build:cjs && npm run build:esm", + "build:cjs": "tsc --build tsconfig.cjs.json && node ./scripts/writeCommonJsPackageJson.mjs ./lib/cjs", + "build:esm": "rollup -c ./rollup.config.mjs && node ./scripts/writeEsmPackageJson.mjs ./lib/esm", + "build:clean": "rimraf lib", + "format": "prettier --write ./src/**/*.ts", + "lint": "eslint ./src", + "prebuild": "npm run build:clean", + "prepublish": "npm run build", "test": "jest", "test:coverage": "jest --coverage", - "test:watch": "jest --watch", - "pretest": "eslint ./", - "publish-please": "publish-please", - "prepublish": "npm run build && publish-please guard", - "update": "updates --update --minor && (git diff-files --quiet package.json || (rimraf package-lock.json node_modules && npm install))", - "postupdate": "git diff-files --quiet package-lock.json || npm test" + "test:watch": "jest --watch" }, "bugs": { "url": "https://github.com/inversify/inversify-express-utils/issues" @@ -39,28 +42,35 @@ "http-status-codes": "2.3.0" }, "devDependencies": { - "@types/async": "3.2.24", + "@eslint/js": "9.18.0", + "@jest/globals": "29.7.0", + "@rollup/plugin-terser": "0.4.4", + "@rollup/plugin-typescript": "12.1.2", "@types/cookie-parser": "1.4.7", "@types/express": "^4.17.21", - "@types/jest": "29.5.14", - "@types/node": "20.17.1", + "@types/node": "22.10.7", "@types/supertest": "6.0.2", - "@typescript-eslint/eslint-plugin": "8.11.0", - "@typescript-eslint/parser": "8.11.0", - "async": "3.2.6", + "@typescript-eslint/eslint-plugin": "8.20.0", + "@typescript-eslint/parser": "8.20.0", "cookie-parser": "1.4.7", - "eslint": "9.12.0", - "eslint-plugin-import": "2.31.0", + "eslint": "9.18.0", + "eslint-config-prettier": "10.0.1", + "eslint-plugin-prettier": "5.2.2", + "eslint-plugin-simple-import-sort": "12.1.1", "jest": "29.7.0", - "publish-please": "5.5.2", + "prettier": "3.4.2", "reflect-metadata": "0.2.2", + "rimraf": "6.0.1", + "rollup-plugin-dts": "6.1.1", "supertest": "6.3.4", + "ts-loader": "9.5.2", "ts-jest": "29.2.5", "typescript": "5.6.3", - "updates": "15.3.1" + "typescript-eslint": "8.20.0" }, "peerDependencies": { "express": "^4.21.1", - "inversify": "^6.0.3" + "inversify": "^6.0.3", + "reflect-metadata": "~0.2.2" } } diff --git a/prettier.config.mjs b/prettier.config.mjs new file mode 100644 index 00000000..69c1a733 --- /dev/null +++ b/prettier.config.mjs @@ -0,0 +1,11 @@ +export default { + printWidth: 80, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + bracketSpacing: true, + arrowParens: 'always', + endOfLine: 'lf', + trailingComma: 'all', +}; diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..8c3ed931 --- /dev/null +++ b/renovate.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "automerge": false, + "extends": [ + "config:base", + ":disableRateLimiting", + ":semanticCommitScopeDisabled" + ], + "ignoreDeps": [], + "packageRules": [ + { + "groupName": "auto merge on patch or minor", + "automerge": true, + "matchUpdateTypes": ["patch", "minor"], + "excludePackageNames": ["turbo", "typescript"] + } + ], + "rangeStrategy": "bump", + "rebaseWhen": "conflicted", + "semanticCommits": "enabled", + "schedule": ["at any time"] +} diff --git a/rollup.config.mjs b/rollup.config.mjs new file mode 100644 index 00000000..317eb54a --- /dev/null +++ b/rollup.config.mjs @@ -0,0 +1,71 @@ +import fs from 'node:fs/promises'; + +import terser from '@rollup/plugin-terser'; +import typescript from '@rollup/plugin-typescript'; +import { dts } from 'rollup-plugin-dts'; + +const NODE_REGEX = /^node:/; + +/** + * @param {string} path + * @returns {Promise} + */ +async function pathExists(path) { + try { + await fs.access(path); + return true; + } catch (_err) { + return false; + } +} + +const PACKAGE_JSON_PATH = './package.json'; + +if (!pathExists(PACKAGE_JSON_PATH)) { + throw new Error(`Expected "${PACKAGE_JSON_PATH}" path to exist`); +} + +const packageJsonObject = JSON.parse(await fs.readFile(PACKAGE_JSON_PATH)); +const packageDependencies = Object.keys(packageJsonObject.dependencies ?? {}); +const packagePeerDependencies = Object.keys( + packageJsonObject.peerDependencies ?? {}, +); + +/** @type {!import("rollup").MergedRollupOptions[]} */ +export default [ + { + input: './src/index.ts', + external: [NODE_REGEX, ...packageDependencies, ...packagePeerDependencies], + output: [ + { + dir: './lib/esm', + format: 'esm', + sourcemap: true, + sourcemapPathTransform: (relativeSourcePath) => { + // Rollup seems to generate source maps pointing to the wrong directory. Ugly patch to fix it + if (relativeSourcePath.startsWith('../')) { + return relativeSourcePath.slice(3); + } else { + return relativeSourcePath; + } + }, + }, + ], + plugins: [ + typescript({ + tsconfig: './tsconfig.esm.json', + }), + terser(), + ], + }, + { + input: 'lib/esm/index.d.ts', + external: [NODE_REGEX, ...packageDependencies, ...packagePeerDependencies], + output: [{ file: 'lib/esm/index.d.ts', format: 'es' }], + plugins: [ + dts({ + tsconfig: './tsconfig.esm.json', + }), + ], + }, +]; diff --git a/scripts/writeCommonJsPackageJson.mjs b/scripts/writeCommonJsPackageJson.mjs new file mode 100644 index 00000000..c0414f38 --- /dev/null +++ b/scripts/writeCommonJsPackageJson.mjs @@ -0,0 +1,43 @@ +#!/usr/bin/env node + +import fs from 'node:fs/promises'; +import { argv } from 'node:process'; +import path from 'node:path'; +import { writeFile } from 'node:fs/promises'; + +/** + * @param {string} path + * @returns {Promise} + */ +async function pathExists(path) { + try { + await fs.access(path); + return true; + } catch (_err) { + return false; + } +} + +const directory = argv[2]; + +if (directory === undefined) { + throw new Error('Expected a path'); +} + +const directoryExists = await pathExists(directory); + +if (!directoryExists) { + throw new Error(`Path ${directory} not found`); +} + +const filePath = path.join(directory, 'package.json'); + +const packageJsonFileContent = JSON.stringify( + { + type: 'commonjs', + }, + undefined, + 2, +); + +await writeFile(filePath, packageJsonFileContent); diff --git a/scripts/writeEsmPackageJson.mjs b/scripts/writeEsmPackageJson.mjs new file mode 100755 index 00000000..2941aab5 --- /dev/null +++ b/scripts/writeEsmPackageJson.mjs @@ -0,0 +1,43 @@ +#!/usr/bin/env node + +import fs from 'node:fs/promises'; +import { argv } from 'node:process'; +import path from 'node:path'; +import { writeFile } from 'node:fs/promises'; + +/** + * @param {string} path + * @returns {Promise} + */ +async function pathExists(path) { + try { + await fs.access(path); + return true; + } catch (_err) { + return false; + } +} + +const directory = argv[2]; + +if (directory === undefined) { + throw new Error('Expected a path'); +} + +const directoryExists = await pathExists(directory); + +if (!directoryExists) { + throw new Error(`Path ${directory} not found`); +} + +const filePath = path.join(directory, 'package.json'); + +const packageJsonFileContent = JSON.stringify( + { + type: 'module', + }, + undefined, + 2, +); + +await writeFile(filePath, packageJsonFileContent); diff --git a/src/base_http_controller.ts b/src/base_http_controller.ts index f3f36acd..75e35c18 100644 --- a/src/base_http_controller.ts +++ b/src/base_http_controller.ts @@ -1,11 +1,28 @@ -import { injectable } from 'inversify'; +import { Readable } from 'node:stream'; import { URL } from 'node:url'; -import { Readable } from 'stream'; + import { StatusCodes } from 'http-status-codes'; +import { injectable } from 'inversify'; + import { injectHttpContext } from './decorators'; import { HttpResponseMessage } from './httpResponseMessage'; -import { CreatedNegotiatedContentResult, ConflictResult, OkNegotiatedContentResult, OkResult, BadRequestErrorMessageResult, BadRequestResult, ExceptionResult, InternalServerErrorResult, NotFoundResult, RedirectResult, ResponseMessageResult, StatusCodeResult, JsonResult, StreamResult } from './results'; import type { HttpContext } from './interfaces'; +import { + BadRequestErrorMessageResult, + BadRequestResult, + ConflictResult, + CreatedNegotiatedContentResult, + ExceptionResult, + InternalServerErrorResult, + JsonResult, + NotFoundResult, + OkNegotiatedContentResult, + OkResult, + RedirectResult, + ResponseMessageResult, + StatusCodeResult, + StreamResult, +} from './results'; @injectable() export class BaseHttpController { @@ -13,7 +30,7 @@ export class BaseHttpController { protected created( location: string | URL, - content: T + content: T, ): CreatedNegotiatedContentResult { return new CreatedNegotiatedContentResult(location, content); } @@ -53,7 +70,7 @@ export class BaseHttpController { } protected responseMessage( - message: HttpResponseMessage + message: HttpResponseMessage, ): ResponseMessageResult { return new ResponseMessageResult(message); } @@ -64,7 +81,7 @@ export class BaseHttpController { protected json>( content: T | T[], - statusCode: number = StatusCodes.OK + statusCode: number = StatusCodes.OK, ): JsonResult { return new JsonResult(content, statusCode); } @@ -72,7 +89,7 @@ export class BaseHttpController { protected stream( readableStream: Readable, contentType: string, - statusCode: number = StatusCodes.OK + statusCode: number = StatusCodes.OK, ): StreamResult { return new StreamResult(readableStream, contentType, statusCode); } diff --git a/src/base_middleware.ts b/src/base_middleware.ts index d1932f73..dbc054de 100644 --- a/src/base_middleware.ts +++ b/src/base_middleware.ts @@ -1,5 +1,6 @@ import type { NextFunction, Request, Response } from 'express'; import { injectable, interfaces as inversifyInterfaces } from 'inversify'; + import type { HttpContext } from './interfaces'; @injectable() diff --git a/src/constants.ts b/src/constants.ts index 80095bc4..eee62093 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/typedef */ +/* eslint-disable @typescript-eslint/naming-convention */ export const TYPE = { AuthProvider: Symbol.for('AuthProvider'), Controller: Symbol.for('Controller'), @@ -21,27 +23,28 @@ export enum PARAMETER_TYPE { HEADERS, COOKIES, NEXT, - PRINCIPAL + PRINCIPAL, } export enum HTTP_VERBS_ENUM { - all = 'ALL', - connect = 'CONNECT', - delete = 'DELETE', - get = 'GET', - head = 'HEAD', - options = 'OPTIONS', - patch = 'PATCH', - post = 'POST', - propfind = 'PROPFIND', - put = 'PUT', - trace = 'TRACE', + all = 'all', + connect = 'connect', + delete = 'delete', + get = 'get', + head = 'head', + options = 'options', + patch = 'patch', + post = 'post', + propfind = 'propfind', + put = 'put', + trace = 'trace', } -export const DUPLICATED_CONTROLLER_NAME = (name: string): string => `Two controllers cannot have the same name: ${name}`; +export const DUPLICATED_CONTROLLER_NAME: (name: string) => string = ( + name: string, +): string => `Two controllers cannot have the same name: ${name}`; -export const NO_CONTROLLERS_FOUND = 'No controllers' + - 'have been found! Please ensure that you have register' + - 'at least one Controller.'; +export const NO_CONTROLLERS_FOUND: string = + 'No controllers have been found! Please ensure that you have register at least one Controller.'; -export const DEFAULT_ROUTING_ROOT_PATH = '/'; +export const DEFAULT_ROUTING_ROOT_PATH: string = '/'; diff --git a/src/content/httpContent.ts b/src/content/httpContent.ts index 9b2b5b78..53c150a0 100644 --- a/src/content/httpContent.ts +++ b/src/content/httpContent.ts @@ -1,8 +1,8 @@ import type { OutgoingHttpHeaders } from 'node:http'; -import type { Readable } from 'stream'; +import type { Readable } from 'node:stream'; export abstract class HttpContent { - private _headers: OutgoingHttpHeaders = {}; + private readonly _headers: OutgoingHttpHeaders = {}; public get headers(): OutgoingHttpHeaders { return this._headers; diff --git a/src/content/jsonContent.ts b/src/content/jsonContent.ts index 7376b6fe..6c6cf36a 100644 --- a/src/content/jsonContent.ts +++ b/src/content/jsonContent.ts @@ -1,17 +1,17 @@ import { HttpContent } from './httpContent'; -const DEFAULT_MEDIA_TYPE = 'application/json'; +const DEFAULT_MEDIA_TYPE: string = 'application/json'; export class JsonContent< - T extends Record + T extends Record, > extends HttpContent { - constructor(private content: T | T[]) { + constructor(private readonly content: T | T[]) { super(); this.headers['content-type'] = DEFAULT_MEDIA_TYPE; } - public readAsync(): Promise { - return Promise.resolve(this.content); + public async readAsync(): Promise { + return this.content; } } diff --git a/src/content/streamContent.ts b/src/content/streamContent.ts index 476ab139..b114ebd4 100644 --- a/src/content/streamContent.ts +++ b/src/content/streamContent.ts @@ -1,13 +1,17 @@ -import { Readable } from 'stream'; +import { Readable } from 'node:stream'; + import { HttpContent } from './httpContent'; export class StreamContent extends HttpContent { - constructor(private readonly content: Readable, private mediaType: string) { - super(); + constructor( + private readonly content: Readable, + mediaType: string, + ) { + super(); - this.headers['content-type'] = mediaType; - } - readAsync(): Promise { - return Promise.resolve(this.content); - } + this.headers['content-type'] = mediaType; + } + public async readAsync(): Promise { + return this.content; + } } diff --git a/src/content/stringContent.ts b/src/content/stringContent.ts index c724515d..b2b396cf 100644 --- a/src/content/stringContent.ts +++ b/src/content/stringContent.ts @@ -1,15 +1,15 @@ import { HttpContent } from './httpContent'; -const DEFAULT_MEDIA_TYPE = 'text/plain'; +const DEFAULT_MEDIA_TYPE: string = 'text/plain'; export class StringContent extends HttpContent { - constructor(private content: string) { + constructor(private readonly content: string) { super(); this.headers['content-type'] = DEFAULT_MEDIA_TYPE; } - public readAsync(): Promise { - return Promise.resolve(this.content); + public async readAsync(): Promise { + return this.content; } } diff --git a/src/debug.ts b/src/debug.ts index 9f68e66b..4240ce22 100644 --- a/src/debug.ts +++ b/src/debug.ts @@ -1,76 +1,97 @@ import { interfaces as inversifyInterfaces } from 'inversify'; -import { PARAMETER_TYPE } from './constants'; -import { getControllersFromContainer, getControllerMetadata, getControllerMethodMetadata, getControllerParameterMetadata, } from './utils'; -import type { RouteDetails, RouteInfo, RawMetadata } from './interfaces'; +import { PARAMETER_TYPE } from './constants'; +import type { + Controller, + ControllerMethodMetadata, + ControllerParameterMetadata, + ParameterMetadata, + RawMetadata, + RouteDetails, + RouteInfo, +} from './interfaces'; +import { + getControllerMetadata, + getControllerMethodMetadata, + getControllerParameterMetadata, + getControllersFromContainer, +} from './utils'; export function getRouteInfo( container: inversifyInterfaces.Container, ): RouteInfo[] { - const raw = getRawMetadata(container); + const raw: RawMetadata[] = getRawMetadata(container); - return raw.map(r => { - const controllerId = (r.controllerMetadata.target as { name: string }).name; + return raw.map((r: RawMetadata) => { + const controllerId: string = ( + r.controllerMetadata.target as { name: string } + ).name; - const endpoints = r.methodMetadata.map(m => { - const method = m.method.toUpperCase(); - const controllerPath = r.controllerMetadata.path; - const actionPath = m.path; - const paramMetadata = r.parameterMetadata; - let args: (string | undefined)[] | undefined = undefined; + const endpoints: RouteDetails[] = r.methodMetadata.map( + (m: ControllerMethodMetadata) => { + const method: string = m.method.toUpperCase(); + const controllerPath: string = r.controllerMetadata.path; + const actionPath: string = m.path; + const paramMetadata: ControllerParameterMetadata = r.parameterMetadata; + let args: (string | undefined)[] | undefined = undefined; - if (paramMetadata !== undefined) { - const paramMetadataForKey = paramMetadata[m.key] || undefined; - if (paramMetadataForKey) { - args = (r.parameterMetadata[m.key] || []).map(a => { - let type = ''; - switch (a.type) { - case PARAMETER_TYPE.RESPONSE: - type = '@response'; - break; - case PARAMETER_TYPE.REQUEST: - type = '@request'; - break; - case PARAMETER_TYPE.NEXT: - type = '@next'; - break; - case PARAMETER_TYPE.PARAMS: - type = '@requestParam'; - break; - case PARAMETER_TYPE.QUERY: - type = 'queryParam'; - break; - case PARAMETER_TYPE.BODY: - type = '@requestBody'; - break; - case PARAMETER_TYPE.HEADERS: - type = '@requestHeaders'; - break; - case PARAMETER_TYPE.COOKIES: - type = '@cookies'; - break; - case PARAMETER_TYPE.PRINCIPAL: - type = '@principal'; - break; - default: - break; - } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (paramMetadata !== undefined) { + const paramMetadataForKey: ParameterMetadata[] | undefined = + paramMetadata[m.key] || undefined; + if (paramMetadataForKey) { + args = (r.parameterMetadata[m.key] || []).map( + (a: ParameterMetadata) => { + let type: string = ''; + switch (a.type) { + case PARAMETER_TYPE.RESPONSE: + type = '@response'; + break; + case PARAMETER_TYPE.REQUEST: + type = '@request'; + break; + case PARAMETER_TYPE.NEXT: + type = '@next'; + break; + case PARAMETER_TYPE.PARAMS: + type = '@requestParam'; + break; + case PARAMETER_TYPE.QUERY: + type = 'queryParam'; + break; + case PARAMETER_TYPE.BODY: + type = '@requestBody'; + break; + case PARAMETER_TYPE.HEADERS: + type = '@requestHeaders'; + break; + case PARAMETER_TYPE.COOKIES: + type = '@cookies'; + break; + case PARAMETER_TYPE.PRINCIPAL: + type = '@principal'; + break; + default: + break; + } - return `${type} ${a.parameterName as string}`; - }); + return `${type} ${a.parameterName as string}`; + }, + ); + } } - } - const details: RouteDetails = { - route: `${method} ${controllerPath}${actionPath}`, - }; + const details: RouteDetails = { + route: `${method} ${controllerPath}${actionPath}`, + }; - if (args) { - details.args = args as string[]; - } + if (args) { + details.args = args as string[]; + } - return details; - }); + return details; + }, + ); return { controller: controllerId, @@ -80,12 +101,15 @@ export function getRouteInfo( } export function getRawMetadata( - container: inversifyInterfaces.Container + container: inversifyInterfaces.Container, ): RawMetadata[] { - const controllers = getControllersFromContainer(container, true); + const controllers: Controller[] = getControllersFromContainer( + container, + true, + ); - return controllers.map(controller => { - const { constructor } = controller; + return controllers.map((controller: Controller) => { + const { constructor }: Controller = controller; return { controllerMetadata: getControllerMetadata(constructor), diff --git a/src/decorators.ts b/src/decorators.ts index 352356f4..5d185ad4 100644 --- a/src/decorators.ts +++ b/src/decorators.ts @@ -1,12 +1,27 @@ -import { inject, injectable, decorate } from 'inversify'; -import { TYPE, METADATA_KEY, PARAMETER_TYPE, HTTP_VERBS_ENUM, } from './constants'; -import type { DecoratorTarget, Middleware, ControllerMetadata, HandlerDecorator, ControllerMethodMetadata, ControllerParameterMetadata, ParameterMetadata, MiddlewareMetaData } from './interfaces'; +import { decorate, inject, injectable } from 'inversify'; + +import { + HTTP_VERBS_ENUM, + METADATA_KEY, + PARAMETER_TYPE, + TYPE, +} from './constants'; +import type { + ControllerMetadata, + ControllerMethodMetadata, + ControllerParameterMetadata, + DecoratorTarget, + HandlerDecorator, + Middleware, + MiddlewareMetaData, + ParameterMetadata, +} from './interfaces'; import { getMiddlewareMetadata, getOrCreateMetadata } from './utils'; export const injectHttpContext: ( target: DecoratorTarget, targetKey?: string | symbol, - indexOrPropertyDescriptor?: number | TypedPropertyDescriptor + indexOrPropertyDescriptor?: number | TypedPropertyDescriptor, ) => void = inject(TYPE.HttpContext); function defineMiddlewareMetadata( @@ -16,7 +31,8 @@ function defineMiddlewareMetadata( ): void { // We register decorated middleware meteadata in a map, e.g. { "controller": [ middleware ] } const middlewareMap: MiddlewareMetaData = getOrCreateMetadata( - METADATA_KEY.middleware, target, + METADATA_KEY.middleware, + target, {}, ); @@ -31,16 +47,12 @@ function defineMiddlewareMetadata( export function withMiddleware(...middleware: Middleware[]) { return function ( target: DecoratorTarget | NewableFunction, - methodName?: string + methodName?: string, ): void { - if (methodName) { + if (methodName !== undefined) { defineMiddlewareMetadata(target, methodName, ...middleware); } else if (isNewableFunction(target)) { - defineMiddlewareMetadata( - target.constructor, - target.name, - ...middleware - ); + defineMiddlewareMetadata(target.constructor, target.name, ...middleware); } }; } @@ -52,9 +64,9 @@ function isNewableFunction(target: unknown): target is NewableFunction { export function controller(path: string, ...middleware: Middleware[]) { return (target: NewableFunction): void => { // Get the list of middleware registered with @middleware() decorators - const decoratedMiddleware = getMiddlewareMetadata( + const decoratedMiddleware: Middleware[] = getMiddlewareMetadata( target.constructor, - target.name + target.name, ); const currentMetadata: ControllerMetadata = { @@ -72,18 +84,17 @@ export function controller(path: string, ...middleware: Middleware[]) { // We attach metadata to the Reflect object itself to avoid // declaring additional globals. Also, the Reflect is available // in both node and web browsers. - const previousMetadata: ControllerMetadata[] = Reflect.getMetadata( - METADATA_KEY.controller, - Reflect, - ) as ControllerMetadata[] || []; + const previousMetadata: ControllerMetadata[] = + (Reflect.getMetadata(METADATA_KEY.controller, Reflect) as + | ControllerMetadata[] + | undefined) ?? []; - const newMetadata = [currentMetadata, ...previousMetadata]; + const newMetadata: ControllerMetadata[] = [ + currentMetadata, + ...previousMetadata, + ]; - Reflect.defineMetadata( - METADATA_KEY.controller, - newMetadata, - Reflect, - ); + Reflect.defineMetadata(METADATA_KEY.controller, newMetadata, Reflect); }; } @@ -91,65 +102,68 @@ export function all( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('all', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.all, path, ...middleware); } export function httpGet( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('get', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.get, path, ...middleware); } export function httpPost( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('post', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.post, path, ...middleware); } export function httpPut( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('put', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.put, path, ...middleware); } export function httpPatch( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('patch', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.patch, path, ...middleware); } export function httpHead( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('head', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.head, path, ...middleware); } export function httpDelete( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('delete', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.delete, path, ...middleware); } export function httpOptions( path: string, ...middleware: Middleware[] ): HandlerDecorator { - return httpMethod('options', path, ...middleware); + return httpMethod(HTTP_VERBS_ENUM.options, path, ...middleware); } export function httpMethod( - method: keyof typeof HTTP_VERBS_ENUM, + method: HTTP_VERBS_ENUM, path: string, ...middleware: Middleware[] ): HandlerDecorator { return (target: DecoratorTarget, key: string): void => { - const decoratedMiddleware = getMiddlewareMetadata(target, key); + const decoratedMiddleware: Middleware[] = getMiddlewareMetadata( + target, + key, + ); const metadata: ControllerMethodMetadata = { key, @@ -162,15 +176,12 @@ export function httpMethod( let metadataList: ControllerMethodMetadata[] = []; if ( - !Reflect.hasOwnMetadata( - METADATA_KEY.controllerMethod, - target.constructor - ) + !Reflect.hasOwnMetadata(METADATA_KEY.controllerMethod, target.constructor) ) { Reflect.defineMetadata( METADATA_KEY.controllerMethod, metadataList, - target.constructor + target.constructor, ); } else { metadataList = Reflect.getOwnMetadata( @@ -183,40 +194,37 @@ export function httpMethod( }; } -export const request: () => ParameterDecorator = - paramDecoratorFactory(PARAMETER_TYPE.REQUEST); +export const request: () => ParameterDecorator = paramDecoratorFactory( + PARAMETER_TYPE.REQUEST, +); -export const response: () => ParameterDecorator = - paramDecoratorFactory(PARAMETER_TYPE.RESPONSE); +export const response: () => ParameterDecorator = paramDecoratorFactory( + PARAMETER_TYPE.RESPONSE, +); export const requestParam: (paramName?: string) => ParameterDecorator = - paramDecoratorFactory( - PARAMETER_TYPE.PARAMS - ); + paramDecoratorFactory(PARAMETER_TYPE.PARAMS); export const queryParam: (queryParamName?: string) => ParameterDecorator = - paramDecoratorFactory( - PARAMETER_TYPE.QUERY - ); + paramDecoratorFactory(PARAMETER_TYPE.QUERY); -export const requestBody: () => ParameterDecorator = - paramDecoratorFactory(PARAMETER_TYPE.BODY); +export const requestBody: () => ParameterDecorator = paramDecoratorFactory( + PARAMETER_TYPE.BODY, +); export const requestHeaders: (headerName?: string) => ParameterDecorator = - paramDecoratorFactory( - PARAMETER_TYPE.HEADERS - ); + paramDecoratorFactory(PARAMETER_TYPE.HEADERS); export const cookies: (cookieName?: string) => ParameterDecorator = - paramDecoratorFactory( - PARAMETER_TYPE.COOKIES - ); + paramDecoratorFactory(PARAMETER_TYPE.COOKIES); -export const next: () => ParameterDecorator = - paramDecoratorFactory(PARAMETER_TYPE.NEXT); +export const next: () => ParameterDecorator = paramDecoratorFactory( + PARAMETER_TYPE.NEXT, +); -export const principal: () => ParameterDecorator = - paramDecoratorFactory(PARAMETER_TYPE.PRINCIPAL); +export const principal: () => ParameterDecorator = paramDecoratorFactory( + PARAMETER_TYPE.PRINCIPAL, +); function paramDecoratorFactory( parameterType: PARAMETER_TYPE, @@ -225,14 +233,11 @@ function paramDecoratorFactory( params(parameterType, name); } -export function params( - type: PARAMETER_TYPE, - parameterName?: string | symbol -) { +export function params(type: PARAMETER_TYPE, parameterName?: string | symbol) { return ( target: object, methodName: string | symbol | undefined, - index: number + index: number, ): void => { let metadataList: ControllerParameterMetadata = {}; let parameterMetadataList: ParameterMetadata[] = []; @@ -245,7 +250,7 @@ export function params( if ( !Reflect.hasOwnMetadata( METADATA_KEY.controllerParameter, - target.constructor + target.constructor, ) ) { parameterMetadataList.unshift(parameterMetadata); @@ -263,7 +268,7 @@ export function params( Reflect.defineMetadata( METADATA_KEY.controllerParameter, metadataList, - target.constructor + target.constructor, ); }; } diff --git a/src/httpResponseMessage.ts b/src/httpResponseMessage.ts index 2b11cff9..fe2b62aa 100644 --- a/src/httpResponseMessage.ts +++ b/src/httpResponseMessage.ts @@ -1,42 +1,47 @@ import type { OutgoingHttpHeaders } from 'node:http'; + +import { StatusCodes } from 'http-status-codes'; + import { HttpContent } from './content/httpContent'; +const MAX_STATUS_CODE: number = 999; + export class HttpResponseMessage { private _content!: HttpContent; private _headers: OutgoingHttpHeaders = {}; - public get headers(): OutgoingHttpHeaders { - return this._headers; - } + private _statusCode!: number; - public set headers(headers: OutgoingHttpHeaders) { - this._headers = headers; + constructor(statusCode: number = StatusCodes.OK) { + this.statusCode = statusCode; } public get content(): HttpContent { return this._content; } - public set content(value: HttpContent) { - this._content = value; + public get headers(): OutgoingHttpHeaders { + return this._headers; } - private _statusCode!: number; - public get statusCode(): number { return this._statusCode; } + public set content(value: HttpContent) { + this._content = value; + } + + public set headers(headers: OutgoingHttpHeaders) { + this._headers = headers; + } + public set statusCode(code: number) { - if (code < 0 || code > 999) { - throw new Error(`${code} is not a valid status code`); + if (code < 0 || code > MAX_STATUS_CODE) { + throw new Error(`${code.toString()} is not a valid status code`); } this._statusCode = code; } - - constructor(statusCode = 200) { - this.statusCode = statusCode; - } } diff --git a/src/interfaces.ts b/src/interfaces.ts index afb89ee1..442a0524 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,5 +1,12 @@ -import type { Application, NextFunction, Request, RequestHandler, Response } from 'express'; +import type { + Application, + NextFunction, + Request, + RequestHandler, + Response, +} from 'express'; import { interfaces as inversifyInterfaces } from 'inversify'; + import { HTTP_VERBS_ENUM, PARAMETER_TYPE } from './constants'; import { HttpResponseMessage } from './httpResponseMessage'; @@ -10,20 +17,22 @@ type Prototype = { }; interface ConstructorFunction> { - new(...args: unknown[]): T; prototype: Prototype; + new (...args: unknown[]): T; } export type DecoratorTarget = - ConstructorFunction | Prototype; + | ConstructorFunction + | Prototype; -export type Middleware = (string | symbol | RequestHandler); +export type Middleware = string | symbol | RequestHandler; export interface MiddlewareMetaData { [identifier: string]: Middleware[]; } export type ControllerHandler = (...params: unknown[]) => unknown; +// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-empty-interface export interface Controller {} export interface ControllerMetadata { @@ -34,7 +43,7 @@ export interface ControllerMetadata { export interface ControllerMethodMetadata extends ControllerMetadata { key: string; - method: keyof typeof HTTP_VERBS_ENUM; + method: HTTP_VERBS_ENUM; } export interface ControllerParameterMetadata { @@ -51,12 +60,12 @@ export interface ParameterMetadata { export type ExtractedParameters = | ParameterMetadata[] | [Request, Response, NextFunction] - | unknown[] + | unknown[]; export type HandlerDecorator = ( target: DecoratorTarget, key: string, - value: unknown + value: unknown, ) => void; export type ConfigFunction = (app: Application) => void; @@ -75,11 +84,7 @@ export interface Principal { } export interface AuthProvider { - getUser( - req: Request, - res: Response, - next: NextFunction - ): Promise; + getUser(req: Request, res: Response, next: NextFunction): Promise; } export interface HttpContext { @@ -89,6 +94,7 @@ export interface HttpContext { user: Principal; } +// eslint-disable-next-line @typescript-eslint/naming-convention export interface IHttpActionResult { executeAsync(): Promise; } @@ -104,7 +110,7 @@ export interface RouteInfo { } export interface RawMetadata { - controllerMetadata: ControllerMetadata, - methodMetadata: ControllerMethodMetadata[], - parameterMetadata: ControllerParameterMetadata, -} \ No newline at end of file + controllerMetadata: ControllerMetadata; + methodMetadata: ControllerMethodMetadata[]; + parameterMetadata: ControllerParameterMetadata; +} diff --git a/src/results/BadRequestErrorMessageResult.ts b/src/results/BadRequestErrorMessageResult.ts index c703e95e..5fdc13fb 100644 --- a/src/results/BadRequestErrorMessageResult.ts +++ b/src/results/BadRequestErrorMessageResult.ts @@ -1,14 +1,18 @@ import { StatusCodes } from 'http-status-codes'; -import { HttpResponseMessage } from '../httpResponseMessage'; + import { StringContent } from '../content/stringContent'; +import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class BadRequestErrorMessageResult implements IHttpActionResult { - constructor(private message: string) { } + constructor(private readonly message: string) {} public async executeAsync(): Promise { - const response = new HttpResponseMessage(StatusCodes.BAD_REQUEST); + const response: HttpResponseMessage = new HttpResponseMessage( + StatusCodes.BAD_REQUEST, + ); response.content = new StringContent(this.message); - return Promise.resolve(response); + + return response; } } diff --git a/src/results/BadRequestResult.ts b/src/results/BadRequestResult.ts index 43203a9d..326c2a8a 100644 --- a/src/results/BadRequestResult.ts +++ b/src/results/BadRequestResult.ts @@ -1,9 +1,10 @@ import { StatusCodes } from 'http-status-codes'; + import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class BadRequestResult implements IHttpActionResult { public async executeAsync(): Promise { - return Promise.resolve(new HttpResponseMessage(StatusCodes.BAD_REQUEST)); + return new HttpResponseMessage(StatusCodes.BAD_REQUEST); } } diff --git a/src/results/ConflictResult.ts b/src/results/ConflictResult.ts index c88c27f1..9c75838e 100644 --- a/src/results/ConflictResult.ts +++ b/src/results/ConflictResult.ts @@ -1,9 +1,10 @@ import { StatusCodes } from 'http-status-codes'; + import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class ConflictResult implements IHttpActionResult { public async executeAsync(): Promise { - return Promise.resolve(new HttpResponseMessage(StatusCodes.CONFLICT)); + return new HttpResponseMessage(StatusCodes.CONFLICT); } } diff --git a/src/results/CreatedNegotiatedContentResult.ts b/src/results/CreatedNegotiatedContentResult.ts index aa162fac..759fe5d3 100644 --- a/src/results/CreatedNegotiatedContentResult.ts +++ b/src/results/CreatedNegotiatedContentResult.ts @@ -1,16 +1,24 @@ -import { StatusCodes } from 'http-status-codes'; import { URL } from 'node:url'; -import { HttpResponseMessage } from '../httpResponseMessage'; + +import { StatusCodes } from 'http-status-codes'; + import { StringContent } from '../content/stringContent'; +import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class CreatedNegotiatedContentResult implements IHttpActionResult { - constructor(private location: string | URL, private content: T) { } + constructor( + private readonly location: string | URL, + private readonly content: T, + ) {} public async executeAsync(): Promise { - const response = new HttpResponseMessage(StatusCodes.CREATED); + const response: HttpResponseMessage = new HttpResponseMessage( + StatusCodes.CREATED, + ); response.content = new StringContent(JSON.stringify(this.content)); response.headers['location'] = this.location.toString(); - return Promise.resolve(response); + + return response; } } diff --git a/src/results/ExceptionResult.ts b/src/results/ExceptionResult.ts index 87b94540..f2fd148b 100644 --- a/src/results/ExceptionResult.ts +++ b/src/results/ExceptionResult.ts @@ -1,14 +1,18 @@ import { StatusCodes } from 'http-status-codes'; -import { HttpResponseMessage } from '../httpResponseMessage'; + import { StringContent } from '../content/stringContent'; +import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class ExceptionResult implements IHttpActionResult { - constructor(private error: Error) { } + constructor(private readonly error: Error) {} public async executeAsync(): Promise { - const response = new HttpResponseMessage(StatusCodes.INTERNAL_SERVER_ERROR); + const response: HttpResponseMessage = new HttpResponseMessage( + StatusCodes.INTERNAL_SERVER_ERROR, + ); response.content = new StringContent(this.error.toString()); - return Promise.resolve(response); + + return response; } } diff --git a/src/results/InternalServerError.ts b/src/results/InternalServerError.ts index d5b504aa..8a5ac58c 100644 --- a/src/results/InternalServerError.ts +++ b/src/results/InternalServerError.ts @@ -1,11 +1,10 @@ import { StatusCodes } from 'http-status-codes'; + import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class InternalServerErrorResult implements IHttpActionResult { public async executeAsync(): Promise { - return Promise.resolve( - new HttpResponseMessage(StatusCodes.INTERNAL_SERVER_ERROR) - ); + return new HttpResponseMessage(StatusCodes.INTERNAL_SERVER_ERROR); } } diff --git a/src/results/JsonResult.ts b/src/results/JsonResult.ts index 79639252..3e77c6cc 100644 --- a/src/results/JsonResult.ts +++ b/src/results/JsonResult.ts @@ -2,17 +2,20 @@ import { JsonContent } from '../content/jsonContent'; import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; -export class JsonResult< - T extends Record -> implements IHttpActionResult { +export class JsonResult> + implements IHttpActionResult +{ constructor( public readonly json: T | T[], - public readonly statusCode: number - ) { } + public readonly statusCode: number, + ) {} public async executeAsync(): Promise { - const response = new HttpResponseMessage(this.statusCode); + const response: HttpResponseMessage = new HttpResponseMessage( + this.statusCode, + ); response.content = new JsonContent(this.json); - return Promise.resolve(response); + + return response; } } diff --git a/src/results/NotFoundResult.ts b/src/results/NotFoundResult.ts index bb9a4ba0..3324c99a 100644 --- a/src/results/NotFoundResult.ts +++ b/src/results/NotFoundResult.ts @@ -1,11 +1,10 @@ import { StatusCodes } from 'http-status-codes'; + import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class NotFoundResult implements IHttpActionResult { public async executeAsync(): Promise { - return Promise.resolve( - new HttpResponseMessage(StatusCodes.NOT_FOUND) - ); + return new HttpResponseMessage(StatusCodes.NOT_FOUND); } } diff --git a/src/results/OkNegotiatedContentResult.ts b/src/results/OkNegotiatedContentResult.ts index fef5de5e..cff9e057 100644 --- a/src/results/OkNegotiatedContentResult.ts +++ b/src/results/OkNegotiatedContentResult.ts @@ -1,14 +1,18 @@ import { StatusCodes } from 'http-status-codes'; -import { HttpResponseMessage } from '../httpResponseMessage'; + import { StringContent } from '../content/stringContent'; +import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class OkNegotiatedContentResult implements IHttpActionResult { - constructor(private content: T) { } + constructor(private readonly content: T) {} public async executeAsync(): Promise { - const response = new HttpResponseMessage(StatusCodes.OK); + const response: HttpResponseMessage = new HttpResponseMessage( + StatusCodes.OK, + ); response.content = new StringContent(JSON.stringify(this.content)); - return Promise.resolve(response); + + return response; } } diff --git a/src/results/OkResult.ts b/src/results/OkResult.ts index 5ec0e4e3..8b07b54e 100644 --- a/src/results/OkResult.ts +++ b/src/results/OkResult.ts @@ -1,11 +1,10 @@ import { StatusCodes } from 'http-status-codes'; + import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class OkResult implements IHttpActionResult { public async executeAsync(): Promise { - return Promise.resolve( - new HttpResponseMessage(StatusCodes.OK) - ); + return new HttpResponseMessage(StatusCodes.OK); } } diff --git a/src/results/RedirectResult.ts b/src/results/RedirectResult.ts index cef8d04e..5956f764 100644 --- a/src/results/RedirectResult.ts +++ b/src/results/RedirectResult.ts @@ -1,14 +1,19 @@ -import { StatusCodes } from 'http-status-codes'; import { URL } from 'node:url'; + +import { StatusCodes } from 'http-status-codes'; + import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class RedirectResult implements IHttpActionResult { - constructor(private location: string | URL) { } + constructor(private readonly location: string | URL) {} public async executeAsync(): Promise { - const response = new HttpResponseMessage(StatusCodes.MOVED_TEMPORARILY); + const response: HttpResponseMessage = new HttpResponseMessage( + StatusCodes.MOVED_TEMPORARILY, + ); response.headers['location'] = this.location.toString(); - return Promise.resolve(response); + + return response; } } diff --git a/src/results/ResponseMessageResult.ts b/src/results/ResponseMessageResult.ts index e3db4aeb..c5ece202 100644 --- a/src/results/ResponseMessageResult.ts +++ b/src/results/ResponseMessageResult.ts @@ -2,9 +2,9 @@ import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class ResponseMessageResult implements IHttpActionResult { - constructor(private message: HttpResponseMessage) { } + constructor(private readonly message: HttpResponseMessage) {} public async executeAsync(): Promise { - return Promise.resolve(this.message); + return this.message; } } diff --git a/src/results/StatusCodeResult.ts b/src/results/StatusCodeResult.ts index 95c3c227..dd69d538 100644 --- a/src/results/StatusCodeResult.ts +++ b/src/results/StatusCodeResult.ts @@ -2,11 +2,9 @@ import { HttpResponseMessage } from '../httpResponseMessage'; import type { IHttpActionResult } from '../interfaces'; export class StatusCodeResult implements IHttpActionResult { - constructor(private statusCode: number) { } + constructor(private readonly statusCode: number) {} public async executeAsync(): Promise { - return Promise.resolve( - new HttpResponseMessage(this.statusCode) - ); + return new HttpResponseMessage(this.statusCode); } } diff --git a/src/results/StreamResult.ts b/src/results/StreamResult.ts index c89566e0..2e574e1f 100644 --- a/src/results/StreamResult.ts +++ b/src/results/StreamResult.ts @@ -1,22 +1,23 @@ -import { Readable } from 'stream'; -import { IHttpActionResult } from '../interfaces'; -import { HttpResponseMessage } from '../httpResponseMessage'; -import { StreamContent } from '../content/streamContent'; +import { Readable } from 'node:stream'; +import { StreamContent } from '../content/streamContent'; +import { HttpResponseMessage } from '../httpResponseMessage'; +import { IHttpActionResult } from '../interfaces'; export class StreamResult implements IHttpActionResult { constructor( public readableStream: Readable, public contentType: string, - public readonly statusCode: number - ) { } + public readonly statusCode: number, + ) {} public async executeAsync(): Promise { - const response = new HttpResponseMessage(this.statusCode); - response.content = new StreamContent( - this.readableStream, - this.contentType, + const response: HttpResponseMessage = new HttpResponseMessage( + this.statusCode, ); - return Promise.resolve(response); + + response.content = new StreamContent(this.readableStream, this.contentType); + + return response; } } diff --git a/src/results/index.ts b/src/results/index.ts index 6577d292..090a0854 100644 --- a/src/results/index.ts +++ b/src/results/index.ts @@ -1,14 +1,14 @@ -export * from './ExceptionResult'; -export * from './BadRequestResult'; export * from './BadRequestErrorMessageResult'; +export * from './BadRequestResult'; +export * from './ConflictResult'; export * from './CreatedNegotiatedContentResult'; +export * from './ExceptionResult'; export * from './InternalServerError'; +export * from './JsonResult'; export * from './NotFoundResult'; export * from './OkNegotiatedContentResult'; export * from './OkResult'; export * from './RedirectResult'; export * from './ResponseMessageResult'; -export * from './ConflictResult'; export * from './StatusCodeResult'; -export * from './JsonResult'; export * from './StreamResult'; diff --git a/src/server.ts b/src/server.ts index b06956f3..8fa8dc6e 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,395 +1,501 @@ -import "reflect-metadata"; +import 'reflect-metadata'; + +import type { OutgoingHttpHeader, OutgoingHttpHeaders } from 'node:http'; import express, { - Application, - NextFunction, - Request, - RequestHandler, - Response, - Router, -} from "express"; -import { interfaces } from "inversify"; -import { BaseMiddleware, Controller } from "./index"; -import { - getControllersFromMetadata, - getControllersFromContainer, - getControllerMetadata, - getControllerMethodMetadata, - getControllerParameterMetadata, - instanceOfIHttpActionResult, -} from "./utils"; + Application, + NextFunction, + Request, + RequestHandler, + Response, + Router, +} from 'express'; +import { interfaces } from 'inversify'; + +import { BaseMiddleware } from './base_middleware'; import { - TYPE, - METADATA_KEY, - DEFAULT_ROUTING_ROOT_PATH, - PARAMETER_TYPE, - DUPLICATED_CONTROLLER_NAME, -} from "./constants"; -import { HttpResponseMessage } from "./httpResponseMessage"; - + DEFAULT_ROUTING_ROOT_PATH, + DUPLICATED_CONTROLLER_NAME, + HTTP_VERBS_ENUM, + METADATA_KEY, + PARAMETER_TYPE, + TYPE, +} from './constants'; +import { HttpResponseMessage } from './httpResponseMessage'; import type { - AuthProvider, - ConfigFunction, - ControllerHandler, - ControllerMethodMetadata, - ExtractedParameters, - HttpContext, - Middleware, - ParameterMetadata, - Principal, - RoutingConfig, -} from "./interfaces"; -import type { OutgoingHttpHeaders } from "node:http"; + AuthProvider, + ConfigFunction, + Controller, + ControllerHandler, + ControllerMetadata, + ControllerMethodMetadata, + ControllerParameterMetadata, + DecoratorTarget, + ExtractedParameters, + HttpContext, + Middleware, + ParameterMetadata, + Principal, + RoutingConfig, +} from './interfaces'; +import { + getControllerMetadata, + getControllerMethodMetadata, + getControllerParameterMetadata, + getControllersFromContainer, + getControllersFromMetadata, + instanceOfIhttpActionResult, +} from './utils'; export class InversifyExpressServer { - private _router: Router; - private _container: interfaces.Container; - private _app: Application; - private _configFn!: ConfigFunction; - private _errorConfigFn!: ConfigFunction; - private _routingConfig: RoutingConfig; - private _AuthProvider!: new () => AuthProvider; - private _forceControllers: boolean; - - /** - * Wrapper for the express server. - * - * @param container Container loaded with all controllers and their dependencies. - * @param customRouter optional express.Router custom router - * @param routingConfig optional interfaces.RoutingConfig routing config - * @param customApp optional express.Application custom app - * @param authProvider optional interfaces.AuthProvider auth provider - * @param forceControllers optional boolean setting to force controllers (defaults do true) - */ - constructor( - container: interfaces.Container, - customRouter?: Router | null, - routingConfig?: RoutingConfig | null, - customApp?: Application | null, - authProvider?: (new () => AuthProvider) | null, - forceControllers = true - ) { - this._container = container; - this._forceControllers = forceControllers; - this._router = customRouter || Router(); - this._routingConfig = routingConfig || { - rootPath: DEFAULT_ROUTING_ROOT_PATH, - }; - this._app = customApp || express(); - if (authProvider) { - this._AuthProvider = authProvider; - container.bind(TYPE.AuthProvider).to(this._AuthProvider); - } + private readonly _router: Router; + private readonly _container: interfaces.Container; + private readonly _app: Application; + private _configFn!: ConfigFunction; + private _errorConfigFn!: ConfigFunction; + private readonly _routingConfig: RoutingConfig; + private readonly _authProvider!: new () => AuthProvider; + private readonly _forceControllers: boolean; + + /** + * Wrapper for the express server. + * + * @param container Container loaded with all controllers and their dependencies. + * @param customRouter optional express.Router custom router + * @param routingConfig optional interfaces.RoutingConfig routing config + * @param customApp optional express.Application custom app + * @param authProvider optional interfaces.AuthProvider auth provider + * @param forceControllers optional boolean setting to force controllers (defaults do true) + */ + constructor( + container: interfaces.Container, + customRouter?: Router | null, + routingConfig?: RoutingConfig | null, + customApp?: Application | null, + authProvider?: (new () => AuthProvider) | null, + forceControllers: boolean = true, + ) { + this._container = container; + this._forceControllers = forceControllers; + this._router = customRouter || Router(); + this._routingConfig = routingConfig || { + rootPath: DEFAULT_ROUTING_ROOT_PATH, + }; + this._app = customApp || express(); + if (authProvider) { + this._authProvider = authProvider; + container.bind(TYPE.AuthProvider).to(this._authProvider); } - - /** - * Sets the configuration function to be applied to the application. - * Note that the config function is not actually executed until a call to - * InversifyExpresServer.build(). - * - * This method is chainable. - * - * @param fn Function in which app-level middleware can be registered. - */ - public setConfig(fn: ConfigFunction): InversifyExpressServer { - this._configFn = fn; - return this; - } - - /** - * Sets the error handler configuration function to be applied to the application. - * Note that the error config function is not actually executed until a call to - * InversifyExpresServer.build(). - * - * This method is chainable. - * - * @param fn Function in which app-level error handlers can be registered. - */ - public setErrorConfig(fn: ConfigFunction): InversifyExpressServer { - this._errorConfigFn = fn; - return this; - } - - /** - * Applies all routes and configuration to the server, returning the express application. - */ - public build(): express.Application { - // The very first middleware to be invoked - // it creates a new httpContext and attaches it to the - // current request as metadata using Reflect - this._app.all("*", (req: Request, res: Response, next: NextFunction) => { - void (async (): Promise => { - const httpContext = await this._createHttpContext(req, res, next); - Reflect.defineMetadata(METADATA_KEY.httpContext, httpContext, req); - next(); - })(); - }); - - // register server-level middleware before anything else - if (this._configFn) { - this._configFn.apply(undefined, [this._app]); - } - - this.registerControllers(); - - // register error handlers after controllers - if (this._errorConfigFn) { - this._errorConfigFn.apply(undefined, [this._app]); - } - - return this._app; + } + + /** + * Sets the configuration function to be applied to the application. + * Note that the config function is not actually executed until a call to + * InversifyExpresServer.build(). + * + * This method is chainable. + * + * @param fn Function in which app-level middleware can be registered. + */ + public setConfig(fn: ConfigFunction): this { + this._configFn = fn; + return this; + } + + /** + * Sets the error handler configuration function to be applied to the application. + * Note that the error config function is not actually executed until a call to + * InversifyExpresServer.build(). + * + * This method is chainable. + * + * @param fn Function in which app-level error handlers can be registered. + */ + public setErrorConfig(fn: ConfigFunction): this { + this._errorConfigFn = fn; + return this; + } + + /** + * Applies all routes and configuration to the server, returning the express application. + */ + public build(): express.Application { + // The very first middleware to be invoked + // it creates a new httpContext and attaches it to the + // current request as metadata using Reflect + this._app.all('*', (req: Request, res: Response, next: NextFunction) => { + void (async (): Promise => { + const httpContext: HttpContext = await this._createHttpContext( + req, + res, + next, + ); + Reflect.defineMetadata(METADATA_KEY.httpContext, httpContext, req); + next(); + })(); + }); + + // register server-level middleware before anything else + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/strict-boolean-expressions + if (this._configFn) { + this._configFn.apply(undefined, [this._app]); } - private registerControllers(): void { - // Fake HttpContext is needed during registration - this._container.bind(TYPE.HttpContext).toConstantValue({} as HttpContext); - - const constructors = getControllersFromMetadata(); - - constructors.forEach((constructor) => { - const { name } = constructor as { name: string }; + this.registerControllers(); - if (this._container.isBoundNamed(TYPE.Controller, name)) { - throw new Error(DUPLICATED_CONTROLLER_NAME(name)); - } - - this._container - .bind(TYPE.Controller) - .to(constructor as new (...args: never[]) => unknown) - .whenTargetNamed(name); - }); - - const controllers = getControllersFromContainer(this._container, this._forceControllers); - - controllers.forEach((controller: Controller) => { - const controllerMetadata = getControllerMetadata(controller.constructor); - const methodMetadata = getControllerMethodMetadata(controller.constructor); - const parameterMetadata = getControllerParameterMetadata(controller.constructor); - - if (controllerMetadata && methodMetadata) { - const controllerMiddleware = this.resolveMiddlewere( - ...controllerMetadata.middleware - ); - - methodMetadata.forEach((metadata: ControllerMethodMetadata) => { - let paramList: ParameterMetadata[] = []; - if (parameterMetadata) { - paramList = parameterMetadata[metadata.key] || []; - } - const handler: RequestHandler = this.handlerFactory( - (controllerMetadata.target as { name: string }).name, - metadata.key, - paramList - ); - - const routeMiddleware = this.resolveMiddlewere(...metadata.middleware); - this._router[metadata.method]( - `${controllerMetadata.path}${metadata.path}`, - ...controllerMiddleware, - ...routeMiddleware, - handler - ); - }); - } - }); - - this._app.use(this._routingConfig.rootPath, this._router); + // register error handlers after controllers + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/strict-boolean-expressions + if (this._errorConfigFn) { + this._errorConfigFn.apply(undefined, [this._app]); } - private resolveMiddlewere(...middleware: Middleware[]): RequestHandler[] { - return middleware.map((middlewareItem) => { - if (!this._container.isBound(middlewareItem)) { - return middlewareItem as express.RequestHandler; - } - - type MiddlewareInstance = RequestHandler | BaseMiddleware; - const middlewareInstance = this._container.get(middlewareItem); - - if (middlewareInstance instanceof BaseMiddleware) { - return (req: Request, res: Response, next: NextFunction): void | Promise => { - const mReq = this._container.get(middlewareItem); - mReq.httpContext = this._getHttpContext(req); - return mReq.handler(req, res, next); - }; - } + return this._app; + } + + private registerControllers(): void { + // Fake HttpContext is needed during registration + this._container + .bind(TYPE.HttpContext) + .toConstantValue({} as HttpContext); + + const constructors: DecoratorTarget[] = getControllersFromMetadata(); + + constructors.forEach((constructor: DecoratorTarget) => { + const { name }: { name: string } = constructor as { name: string }; + + if (this._container.isBoundNamed(TYPE.Controller, name)) { + throw new Error(DUPLICATED_CONTROLLER_NAME(name)); + } + + this._container + .bind(TYPE.Controller) + .to(constructor as new (...args: never[]) => unknown) + .whenTargetNamed(name); + }); + + const controllers: Controller[] = getControllersFromContainer( + this._container, + this._forceControllers, + ); + + controllers.forEach((controller: Controller) => { + const controllerMetadata: ControllerMetadata = getControllerMetadata( + controller.constructor, + ); + const methodMetadata: ControllerMethodMetadata[] = + getControllerMethodMetadata(controller.constructor); + const parameterMetadata: ControllerParameterMetadata = + getControllerParameterMetadata(controller.constructor); + + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unnecessary-condition + if (controllerMetadata && methodMetadata) { + const controllerMiddleware: RequestHandler[] = this.resolveMiddlewere( + ...controllerMetadata.middleware, + ); + + // Priorirties for HTTP methods. Lower value means higher priority. Default is 0. + const methodToPriorityMap: Record = { + [HTTP_VERBS_ENUM.head]: -1, + }; - return middlewareInstance; + const sortedMethodMetadata: ControllerMethodMetadata[] = + methodMetadata.sort((a, b) => { + const aPriority: number = methodToPriorityMap[a.method] ?? 0; + const bPriority: number = methodToPriorityMap[b.method] ?? 0; + return aPriority - bPriority; + }); + + sortedMethodMetadata.forEach((metadata: ControllerMethodMetadata) => { + let paramList: ParameterMetadata[] = []; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/strict-boolean-expressions + if (parameterMetadata) { + paramList = parameterMetadata[metadata.key] || []; + } + const handler: RequestHandler = this.handlerFactory( + (controllerMetadata.target as { name: string }).name, + metadata.key, + paramList, + ); + + const routeMiddleware: RequestHandler[] = this.resolveMiddlewere( + ...metadata.middleware, + ); + + const path: string = this.mergePaths( + controllerMetadata.path, + metadata.path, + ); + + this._router[metadata.method]( + path, + ...controllerMiddleware, + ...routeMiddleware, + handler, + ); }); - } + } + }); - private copyHeadersTo(headers: OutgoingHttpHeaders, target: Response): void { - for (const name of Object.keys(headers)) { - const headerValue = headers[name]; + this._app.use(this._routingConfig.rootPath, this._router); + } - target.append( - name, - typeof headerValue === "number" ? headerValue.toString() : headerValue - ); - } - } + private mergePaths(...paths: string[]) { + return paths + .map((path: string) => { + let finalPath: string = + path.startsWith('/') || path.startsWith('.') ? path : `/${path}`; - private async handleHttpResponseMessage( - message: HttpResponseMessage, - res: express.Response - ): Promise { - this.copyHeadersTo(message.headers, res); - - if (message.content !== undefined) { - this.copyHeadersTo(message.content.headers, res); - - res.status(message.statusCode) - // If the content is a number, ensure we change it to a string, else our content is - // treated as a statusCode rather than as the content of the Response - .send(await message.content.readAsync()); - } else { - res.sendStatus(message.statusCode); + if (path.endsWith('/')) { + finalPath = finalPath.substring(0, finalPath.length - 1); } - } - private handlerFactory( - controllerName: string, - key: string, - parameterMetadata: ParameterMetadata[] - ): RequestHandler { - return async (req: Request, res: Response, next: NextFunction): Promise => { - try { - const args = this.extractParameters(req, res, next, parameterMetadata); - const httpContext = this._getHttpContext(req); - httpContext.container - .bind(TYPE.HttpContext) - .toConstantValue(httpContext); - - // invoke controller's action - const value = await ( - httpContext.container.getNamed>(TYPE.Controller, controllerName)[ - key - ] as ControllerHandler - )(...args); - - if (value instanceof HttpResponseMessage) { - await this.handleHttpResponseMessage(value, res); - } else if (instanceOfIHttpActionResult(value)) { - const httpResponseMessage = await value.executeAsync(); - await this.handleHttpResponseMessage(httpResponseMessage, res); - } else if (value instanceof Function) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - value(); - } else if (!res.headersSent) { - if (value !== undefined) { - res.send(value); - } - } - } catch (err) { - next(err); - } + return finalPath; + }) + .join(''); + } + + private resolveMiddlewere(...middleware: Middleware[]): RequestHandler[] { + return middleware.map((middlewareItem: Middleware) => { + if (!this._container.isBound(middlewareItem)) { + return middlewareItem as express.RequestHandler; + } + + type MiddlewareInstance = RequestHandler | BaseMiddleware; + const middlewareInstance: MiddlewareInstance = + this._container.get(middlewareItem); + + if (middlewareInstance instanceof BaseMiddleware) { + return (req: Request, res: Response, next: NextFunction): void => { + const mReq: BaseMiddleware = + this._container.get(middlewareItem); + mReq.httpContext = this._getHttpContext(req); + mReq.handler(req, res, next); }; - } + } - private _getHttpContext(req: express.Request): HttpContext { - return Reflect.getMetadata(METADATA_KEY.httpContext, req) as HttpContext; - } + return middlewareInstance; + }); + } - private async _createHttpContext( - req: Request, - res: Response, - next: NextFunction - ): Promise { - const principal = await this._getCurrentUser(req, res, next); - return { - // We use a childContainer for each request so we can be - // sure that the binding is unique for each HTTP request - container: this._container.createChild(), - request: req, - response: res, - user: principal, - }; - } + private copyHeadersTo(headers: OutgoingHttpHeaders, target: Response): void { + for (const name of Object.keys(headers)) { + const headerValue: OutgoingHttpHeader | undefined = headers[name]; - private async _getCurrentUser( - req: Request, - res: Response, - next: NextFunction - ): Promise { - if (this._AuthProvider !== undefined) { - const authProvider = this._container.get(TYPE.AuthProvider); - return authProvider.getUser(req, res, next); - } - return Promise.resolve({ - details: null, - isAuthenticated: () => Promise.resolve(false), - isInRole: (_role: string) => Promise.resolve(false), - isResourceOwner: (_resourceId: unknown) => Promise.resolve(false), - }); + target.append( + name, + typeof headerValue === 'number' ? headerValue.toString() : headerValue, + ); } - - private extractParameters( - req: Request, - res: Response, - next: NextFunction, - params: ParameterMetadata[] - ): ExtractedParameters { - const args: unknown[] = []; - if (!params || !params.length) { - return [req, res, next]; + } + + private async handleHttpResponseMessage( + message: HttpResponseMessage, + res: express.Response, + ): Promise { + this.copyHeadersTo(message.headers, res); + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (message.content !== undefined) { + this.copyHeadersTo(message.content.headers, res); + + res + .status(message.statusCode) + // If the content is a number, ensure we change it to a string, else our content is + // treated as a statusCode rather than as the content of the Response + .send(await message.content.readAsync()); + } else { + res.sendStatus(message.statusCode); + } + } + + private handlerFactory( + controllerName: string, + key: string, + parameterMetadata: ParameterMetadata[], + ): RequestHandler { + return (async ( + req: Request, + res: Response, + next: NextFunction, + ): Promise => { + try { + const args: ExtractedParameters = this.extractParameters( + req, + res, + next, + parameterMetadata, + ); + const httpContext: HttpContext = this._getHttpContext(req); + httpContext.container + .bind(TYPE.HttpContext) + .toConstantValue(httpContext); + + // invoke controller's action + const value: unknown = await ( + httpContext.container.getNamed>( + TYPE.Controller, + controllerName, + )[key] as ControllerHandler + )(...args); + + if (value instanceof HttpResponseMessage) { + await this.handleHttpResponseMessage(value, res); + } else if (instanceOfIhttpActionResult(value)) { + const httpResponseMessage: HttpResponseMessage = + await value.executeAsync(); + await this.handleHttpResponseMessage(httpResponseMessage, res); + } else if (value instanceof Function) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + value(); + } else if (!res.headersSent) { + if (value !== undefined) { + res.send(value); + } } - - params.forEach(({ type, index, parameterName, injectRoot }) => { - switch (type) { - case PARAMETER_TYPE.REQUEST: - args[index] = req; - break; - case PARAMETER_TYPE.NEXT: - args[index] = next; - break; - case PARAMETER_TYPE.PARAMS: - args[index] = this.getParam(req, "params", injectRoot, parameterName); - break; - case PARAMETER_TYPE.QUERY: - args[index] = this.getParam(req, "query", injectRoot, parameterName); - break; - case PARAMETER_TYPE.BODY: - args[index] = req.body; - break; - case PARAMETER_TYPE.HEADERS: - args[index] = this.getParam(req, "headers", injectRoot, parameterName); - break; - case PARAMETER_TYPE.COOKIES: - args[index] = this.getParam(req, "cookies", injectRoot, parameterName); - break; - case PARAMETER_TYPE.PRINCIPAL: - args[index] = this._getPrincipal(req); - break; - default: - args[index] = res; - break; // response - } - }); - - args.push(req, res, next); - return args; + } catch (err) { + next(err); + } + }) as RequestHandler; + } + + private _getHttpContext(req: express.Request): HttpContext { + return Reflect.getMetadata(METADATA_KEY.httpContext, req) as HttpContext; + } + + private async _createHttpContext( + req: Request, + res: Response, + next: NextFunction, + ): Promise { + const principal: Principal = await this._getCurrentUser(req, res, next); + + return { + // We use a childContainer for each request so we can be + // sure that the binding is unique for each HTTP request + container: this._container.createChild(), + request: req, + response: res, + user: principal, + }; + } + + private async _getCurrentUser( + req: Request, + res: Response, + next: NextFunction, + ): Promise { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (this._authProvider !== undefined) { + const authProvider: AuthProvider = this._container.get( + TYPE.AuthProvider, + ); + return authProvider.getUser(req, res, next); + } + return Promise.resolve({ + details: null, + isAuthenticated: async (): Promise => false, + isInRole: async (_role: string): Promise => false, + isResourceOwner: async (_resourceId: unknown): Promise => false, + }); + } + + private extractParameters( + req: Request, + res: Response, + next: NextFunction, + params: ParameterMetadata[], + ): ExtractedParameters { + const args: unknown[] = []; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/strict-boolean-expressions + if (!params || !params.length) { + return [req, res, next]; } - private getParam( - source: Request, - paramType: "params" | "query" | "headers" | "cookies", - injectRoot: boolean, - name?: string | symbol - ): unknown { - const key = - paramType === "headers" - ? typeof name === "symbol" - ? name.toString() - : name?.toLowerCase() - : (name as string); - const param = source[paramType] as Record; - - if (injectRoot) { - return param; + params.forEach( + ({ type, index, parameterName, injectRoot }: ParameterMetadata) => { + switch (type) { + case PARAMETER_TYPE.REQUEST: + args[index] = req; + break; + case PARAMETER_TYPE.NEXT: + args[index] = next; + break; + case PARAMETER_TYPE.PARAMS: + args[index] = this.getParam( + req, + 'params', + injectRoot, + parameterName, + ); + break; + case PARAMETER_TYPE.QUERY: + args[index] = this.getParam( + req, + 'query', + injectRoot, + parameterName, + ); + break; + case PARAMETER_TYPE.BODY: + args[index] = req.body; + break; + case PARAMETER_TYPE.HEADERS: + args[index] = this.getParam( + req, + 'headers', + injectRoot, + parameterName, + ); + break; + case PARAMETER_TYPE.COOKIES: + args[index] = this.getParam( + req, + 'cookies', + injectRoot, + parameterName, + ); + break; + case PARAMETER_TYPE.PRINCIPAL: + args[index] = this._getPrincipal(req); + break; + default: + args[index] = res; + break; // response } - return param && key ? param[key] : undefined; + }, + ); + + args.push(req, res, next); + return args; + } + + private getParam( + source: Request, + paramType: 'params' | 'query' | 'headers' | 'cookies', + injectRoot: boolean, + name?: string | symbol, + ): unknown { + const key: string | undefined = + paramType === 'headers' + ? typeof name === 'symbol' + ? name.toString() + : name?.toLowerCase() + : (name as string); + + const param: Record = source[paramType] as Record< + string, + unknown + >; + + if (injectRoot) { + return param; } - private _getPrincipal(req: express.Request): Principal | null { - return this._getHttpContext(req).user; - } + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unnecessary-condition + return param && key ? param[key] : undefined; + } + + private _getPrincipal(req: express.Request): Principal | null { + return this._getHttpContext(req).user; + } } diff --git a/src/test/action_result.test.ts b/src/test/action_result.test.ts new file mode 100644 index 00000000..115e6b5a --- /dev/null +++ b/src/test/action_result.test.ts @@ -0,0 +1,175 @@ +import { describe, expect, it } from '@jest/globals'; +import { StatusCodes } from 'http-status-codes'; + +import { HttpResponseMessage } from '../httpResponseMessage'; +import { + BadRequestErrorMessageResult, + BadRequestResult, + ConflictResult, + CreatedNegotiatedContentResult, + ExceptionResult, + InternalServerErrorResult, + NotFoundResult, + OkNegotiatedContentResult, + OkResult, + RedirectResult, + ResponseMessageResult, + StatusCodeResult, +} from '../results'; + +describe('ActionResults', () => { + describe('OkResult', () => { + it('should respond with an HTTP 200', async () => { + const actionResult: OkResult = new OkResult(); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.OK); + }); + }); + + describe('OkNegotiatedContentResult', () => { + it('should respond with an HTTP 200 with content', async () => { + const content: { foo: string } = { + foo: 'bar', + }; + + const actionResult: OkNegotiatedContentResult<{ foo: string }> = + new OkNegotiatedContentResult(content); + + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.OK); + expect(await responseMessage.content.readAsync()).toBe( + JSON.stringify(content), + ); + }); + }); + + describe('BadRequestResult', () => { + it('should respond with an HTTP 400', async () => { + const actionResult: BadRequestResult = new BadRequestResult(); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.BAD_REQUEST); + }); + }); + + describe('BadRequestErrorMessageResult', () => { + it('should respond with an HTTP 400 and an error message', async () => { + const message: string = 'uh oh!'; + const actionResult: BadRequestErrorMessageResult = + new BadRequestErrorMessageResult(message); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.BAD_REQUEST); + expect(await responseMessage.content.readAsync()).toBe(message); + }); + }); + + describe('ConflictResult', () => { + it('should respond with an HTTP 409', async () => { + const actionResult: ConflictResult = new ConflictResult(); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.CONFLICT); + }); + }); + + describe('CreatedNegotiatedContentResult', () => { + it('should respond with an HTTP 302 and appropriate headers', async () => { + const uri: string = 'http://foo/bar'; + const content: { foo: string } = { + foo: 'bar', + }; + + const actionResult: CreatedNegotiatedContentResult<{ foo: string }> = + new CreatedNegotiatedContentResult(uri, content); + + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.CREATED); + expect(await responseMessage.content.readAsync()).toBe( + JSON.stringify(content), + ); + expect(responseMessage.headers['location']).toBe(uri); + }); + }); + + describe('ExceptionResult', () => { + it('should respond with an HTTP 500 and the error message', async () => { + const error: Error = new Error('foo'); + + const actionResult: ExceptionResult = new ExceptionResult(error); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe( + StatusCodes.INTERNAL_SERVER_ERROR, + ); + + expect(await responseMessage.content.readAsync()).toBe('Error: foo'); + }); + }); + + describe('InternalServerErrorResult', () => { + it('should respond with an HTTP 500', async () => { + const actionResult: InternalServerErrorResult = + new InternalServerErrorResult(); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe( + StatusCodes.INTERNAL_SERVER_ERROR, + ); + }); + }); + + describe('NotFoundResult', () => { + it('should respond with an HTTP 404', async () => { + const actionResult: NotFoundResult = new NotFoundResult(); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.NOT_FOUND); + }); + }); + + describe('RedirectResult', () => { + it('should respond with an HTTP 302', async () => { + const uri: string = 'http://foo/bar'; + const actionResult: RedirectResult = new RedirectResult(uri); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(StatusCodes.MOVED_TEMPORARILY); + expect(responseMessage.headers['location']).toBe(uri); + }); + }); + + describe('ResponseMessageResult', () => { + it('should respond with an HTTP 302', async () => { + const responseMessage: HttpResponseMessage = new HttpResponseMessage(200); + const actionResult: ResponseMessageResult = new ResponseMessageResult( + responseMessage, + ); + + expect(await actionResult.executeAsync()).toBe(responseMessage); + }); + }); + + describe('StatusCodeResult', () => { + it('should respond with the specified status code', async () => { + const actionResult: StatusCodeResult = new StatusCodeResult(417); + const responseMessage: HttpResponseMessage = + await actionResult.executeAsync(); + + expect(responseMessage.statusCode).toBe(417); + }); + }); +}); diff --git a/test/auth_provider.test.ts b/src/test/auth_provider.test.ts similarity index 51% rename from test/auth_provider.test.ts rename to src/test/auth_provider.test.ts index 1c471985..8cf318f2 100644 --- a/test/auth_provider.test.ts +++ b/src/test/auth_provider.test.ts @@ -1,15 +1,24 @@ -import { Container, injectable, inject } from 'inversify'; +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { beforeEach, describe, expect, it } from '@jest/globals'; +import { Container, inject, injectable } from 'inversify'; import supertest from 'supertest'; -import { InversifyExpressServer, controller, httpGet, BaseHttpController, Principal, AuthProvider, } from '../src/index'; -import { cleanUpMetadata } from '../src/utils'; + +import { + AuthProvider, + BaseHttpController, + controller, + httpGet, + InversifyExpressServer, + Principal, +} from '../index'; +import { cleanUpMetadata } from '../utils'; describe('AuthProvider', () => { - beforeEach(done => { + beforeEach(() => { cleanUpMetadata(); - done(); }); - it('Should be able to access current user via HttpContext', done => { + it('Should be able to access current user via HttpContext', async () => { interface SomeDependency { name: string; } @@ -20,15 +29,15 @@ describe('AuthProvider', () => { this.details = details; } - public isAuthenticated() { + public async isAuthenticated() { return Promise.resolve(true); } - public isResourceOwner(resourceId: unknown) { + public async isResourceOwner(resourceId: unknown) { return Promise.resolve(resourceId === 1111); } - public isInRole(role: string) { + public async isInRole(role: string) { return Promise.resolve(role === 'admin'); } } @@ -38,8 +47,8 @@ describe('AuthProvider', () => { @inject('SomeDependency') private readonly _someDependency!: SomeDependency; - public getUser() { - const principal = new PrincipalClass({ + public async getUser() { + const principal: PrincipalClass = new PrincipalClass({ email: `${this._someDependency.name}@test.com`, }); return Promise.resolve(principal); @@ -57,23 +66,29 @@ describe('AuthProvider', () => { @httpGet('/') public async getTest() { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (this.httpContext.user !== null) { - const { email } = this.httpContext.user.details as { email: string }; - const { name } = this._someDependency; - const isAuthenticated = await this.httpContext.user.isAuthenticated(); + const { email }: { email: string } = this.httpContext.user + .details as { email: string }; + const { name }: SomeDependency = this._someDependency; + const isAuthenticated: boolean = + await this.httpContext.user.isAuthenticated(); + expect(isAuthenticated).toEqual(true); + return `${email} & ${name}`; } return null; } } - const container = new Container(); + const container: Container = new Container(); - container.bind('SomeDependency') + container + .bind('SomeDependency') .toConstantValue({ name: 'SomeDependency!' }); - const server = new InversifyExpressServer( + const server: InversifyExpressServer = new InversifyExpressServer( container, null, null, @@ -81,8 +96,8 @@ describe('AuthProvider', () => { CustomAuthProvider, ); - void supertest(server.build()) + await supertest(server.build()) .get('/') - .expect(200, 'SomeDependency!@test.com & SomeDependency!', done); + .expect(200, 'SomeDependency!@test.com & SomeDependency!'); }); }); diff --git a/src/test/base_http_controller.test.ts b/src/test/base_http_controller.test.ts new file mode 100644 index 00000000..ee9e6e96 --- /dev/null +++ b/src/test/base_http_controller.test.ts @@ -0,0 +1,109 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { beforeEach, describe, expect, it } from '@jest/globals'; +import { Container, inject } from 'inversify'; +import supertest from 'supertest'; + +import { BaseHttpController } from '../base_http_controller'; +import { StringContent } from '../content/stringContent'; +import { controller, httpGet } from '../decorators'; +import { HttpResponseMessage } from '../httpResponseMessage'; +import { IHttpActionResult } from '../interfaces'; +import { InversifyExpressServer } from '../server'; +import { cleanUpMetadata } from '../utils'; + +describe('BaseHttpController', () => { + beforeEach(() => { + cleanUpMetadata(); + }); + + it('Should contain httpContext instance', async () => { + interface SomeDependency { + name: string; + } + + @controller('/') + class TestController extends BaseHttpController { + private readonly _someDependency: SomeDependency; + constructor(@inject('SomeDependency') someDependency: SomeDependency) { + super(); + this._someDependency = someDependency; + } + + @httpGet('/') + public async getTest() { + const headerVal: string | string[] | undefined = + this.httpContext.request.headers['x-custom']; + const { name }: SomeDependency = this._someDependency; + const isAuthenticated: boolean = + await this.httpContext.user.isAuthenticated(); + + expect(isAuthenticated).toBe(false); + + return `${headerVal as string} & ${name}`; + } + } + + const container: Container = new Container(); + + container + .bind('SomeDependency') + .toConstantValue({ name: 'SomeDependency!' }); + + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + await supertest(server.build()) + .get('/') + .set('x-custom', 'test-header!') + .expect(200, 'test-header! & SomeDependency!'); + }); + + it('should support returning an HttpResponseMessage from a method', async () => { + @controller('/') + class TestController extends BaseHttpController { + @httpGet('/') + public async getTest() { + const response: HttpResponseMessage = new HttpResponseMessage(200); + response.headers['x-custom'] = 'test-header'; + response.content = new StringContent('12345'); + return Promise.resolve(response); + } + } + + const server: InversifyExpressServer = new InversifyExpressServer( + new Container(), + ); + + await supertest(server.build()) + .get('/') + .expect(200, '12345') + .expect('x-custom', 'test-header') + .expect('content-type', 'text/plain; charset=utf-8'); + }); + + it('should support returning an IHttpActionResult from a method', async () => { + @controller('/') + class TestController extends BaseHttpController { + @httpGet('/') + public getTest() { + return new (class TestActionResult implements IHttpActionResult { + public async executeAsync() { + const response: HttpResponseMessage = new HttpResponseMessage(400); + response.content = new StringContent('You done did that wrong'); + + return response; + } + })(); + } + } + + const server: InversifyExpressServer = new InversifyExpressServer( + new Container(), + ); + + await supertest(server.build()) + .get('/') + .expect(400, 'You done did that wrong'); + }); +}); diff --git a/src/test/base_middleware.test.ts b/src/test/base_middleware.test.ts new file mode 100644 index 00000000..8c7a71e7 --- /dev/null +++ b/src/test/base_middleware.test.ts @@ -0,0 +1,283 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { beforeEach, describe, expect, it } from '@jest/globals'; +import { Application, NextFunction, Request, Response } from 'express'; +import { Container, inject, injectable, optional } from 'inversify'; +import supertest from 'supertest'; + +import { + AuthProvider, + BaseHttpController, + BaseMiddleware, + controller, + httpGet, + InversifyExpressServer, + Principal, +} from '../index'; +import { cleanUpMetadata } from '../utils'; + +describe('BaseMiddleware', () => { + beforeEach(() => { + cleanUpMetadata(); + }); + + it('Should be able to inject BaseMiddleware implementations', async () => { + // eslint-disable-next-line @typescript-eslint/typedef + const TYPES = { + LoggerMiddleware: Symbol.for('LoggerMiddleware'), + SomeDependency: Symbol.for('SomeDependency'), + }; + + let principalInstanceCount: number = 0; + + class PrincipalClass implements Principal { + public details: unknown; + constructor(details: unknown) { + this.details = details; + } + + public async isAuthenticated() { + return Promise.resolve(true); + } + + public async isResourceOwner(resourceId: unknown) { + return Promise.resolve(resourceId === 1111); + } + + public async isInRole(role: string) { + return Promise.resolve(role === 'admin'); + } + } + + @injectable() + class CustomAuthProvider implements AuthProvider { + public async getUser(_req: Request, _res: Response, _next: NextFunction) { + principalInstanceCount += 1; + + const principal: PrincipalClass = new PrincipalClass({ + email: 'test@test.com', + }); + + return principal; + } + } + + interface SomeDependency { + name: string; + } + + const logEntries: string[] = []; + + @injectable() + class LoggerMiddleware extends BaseMiddleware { + @inject(TYPES.SomeDependency) + private readonly _someDependency!: SomeDependency; + public handler(req: Request, _res: Response, next: NextFunction) { + const { email }: { email: string } = this.httpContext.user.details as { + email: string; + }; + logEntries.push(`${email} => ${req.url} ${this._someDependency.name}`); + next(); + } + } + + @controller('/', (_req: unknown, _res: unknown, next: NextFunction) => { + logEntries.push('Hello from controller middleware!'); + next(); + }) + class TestController extends BaseHttpController { + @httpGet('/', TYPES.LoggerMiddleware) + public async getTest() { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (this.httpContext.user !== null) { + const { email }: { email: string } = this.httpContext.user + .details as { email: string }; + + const isAuthenticated: boolean = + await this.httpContext.user.isAuthenticated(); + logEntries.push( + `${email} => isAuthenticated() => ${String(isAuthenticated)}`, + ); + return email; + } + return null; + } + } + + const container: Container = new Container(); + + container + .bind(TYPES.SomeDependency) + .toConstantValue({ name: 'SomeDependency!' }); + + container + .bind(TYPES.LoggerMiddleware) + .to(LoggerMiddleware); + + const server: InversifyExpressServer = new InversifyExpressServer( + container, + null, + null, + null, + CustomAuthProvider, + ); + + await supertest(server.build()).get('/').expect(200, 'test@test.com'); + + expect(principalInstanceCount).toBe(1); + expect(logEntries.length).toBe(3); + expect(logEntries[0]).toBe('Hello from controller middleware!'); + expect(logEntries[1]).toBe('test@test.com => / SomeDependency!'); + expect(logEntries[2]).toBe('test@test.com => isAuthenticated() => true'); + }); + + it('Should allow the middleware to inject services in a HTTP request scope', async () => { + const TRACE_HEADER: string = 'X-Trace-Id'; + + // eslint-disable-next-line @typescript-eslint/typedef + const TYPES = { + Service: Symbol.for('Service'), + TraceIdValue: Symbol.for('TraceIdValue'), + TracingMiddleware: Symbol.for('TracingMiddleware'), + }; + + @injectable() + class TracingMiddleware extends BaseMiddleware { + public handler(req: Request, res: Response, next: NextFunction) { + setTimeout( + () => { + this.bind(TYPES.TraceIdValue).toConstantValue( + req.header(TRACE_HEADER) as string, + ); + next(); + }, + someTimeBetween(0, 500), + ); + } + } + + @injectable() + class Service { + constructor( + @inject(TYPES.TraceIdValue) + private readonly traceID: string, + ) {} + + public async doSomethingThatRequiresTraceId() { + return new Promise((resolve: (value: unknown) => void) => { + setTimeout( + () => { + resolve(this.traceID); + }, + someTimeBetween(0, 500), + ); + }); + } + } + + @controller('/') + class TracingTestController extends BaseHttpController { + constructor(@inject(TYPES.Service) private readonly service: Service) { + super(); + } + + @httpGet('/', TYPES.TracingMiddleware) + public async getTest() { + return this.service.doSomethingThatRequiresTraceId(); + } + } + + const container: Container = new Container(); + + container + .bind(TYPES.TracingMiddleware) + .to(TracingMiddleware); + container.bind(TYPES.Service).to(Service); + container.bind(TYPES.TraceIdValue).toConstantValue('undefined'); + + const api: Application = new InversifyExpressServer(container).build(); + + const expectedRequests: number = 100; + + await run(expectedRequests, async (executionId: number) => { + await supertest(api) + .get('/') + .set(TRACE_HEADER, `trace-id-${executionId.toString()}`) + .expect(200, `trace-id-${executionId.toString()}`); + }); + }); + + it('Should not allow services injected into a HTTP request scope to be accessible outside the request scope', async () => { + // eslint-disable-next-line @typescript-eslint/typedef + const TYPES = { + Transaction: Symbol.for('Transaction'), + TransactionMiddleware: Symbol.for('TransactionMiddleware'), + }; + + class TransactionMiddleware extends BaseMiddleware { + private count: number = 0; + + public handler(req: Request, res: Response, next: NextFunction) { + this.bind(TYPES.Transaction).toConstantValue( + `I am transaction #${(this.count += 1).toString()}\n`, + ); + next(); + } + } + + @controller('/') + class TransactionTestController extends BaseHttpController { + constructor( + @inject(TYPES.Transaction) + @optional() + private readonly transaction: string, + ) { + super(); + } + + @httpGet('/1', TYPES.TransactionMiddleware) + public getTest1() { + return this.transaction; + } + + @httpGet('/2' /*<= No middleware!*/) + public getTest2() { + return 'No middleware!'; + } + } + + const container: Container = new Container(); + + container + .bind(TYPES.TransactionMiddleware) + .to(TransactionMiddleware) + .inSingletonScope(); + + const app: Application = new InversifyExpressServer(container).build(); + + await supertest(app).get('/1').expect(200, 'I am transaction #1\n'); + await supertest(app).get('/1').expect(200, 'I am transaction #2\n'); + await supertest(app).get('/2').expect(200, 'No middleware!'); + }); +}); + +async function run( + parallelRuns: number, + test: (executionId: number) => PromiseLike, +) { + const tasks: PromiseLike[] = new Array>( + parallelRuns, + ); + + for (let i: number = 0; i < parallelRuns; ++i) { + tasks[i] = test(i); + } + + await Promise.all(tasks); +} + +function someTimeBetween(minimum: number, maximum: number) { + const min: number = Math.ceil(minimum); + const max: number = Math.floor(maximum); + + return Math.floor(Math.random() * (max - min + 1)) + min; +} diff --git a/src/test/constants.test.ts b/src/test/constants.test.ts new file mode 100644 index 00000000..e28c8891 --- /dev/null +++ b/src/test/constants.test.ts @@ -0,0 +1,11 @@ +import { describe, expect, it } from '@jest/globals'; + +import { DUPLICATED_CONTROLLER_NAME } from '../constants'; + +describe('Constants test', () => { + it('should return correct message', () => { + expect(DUPLICATED_CONTROLLER_NAME('test')).toBe( + 'Two controllers cannot have the same name: test', + ); + }); +}); diff --git a/src/test/content/jsonContent.test.ts b/src/test/content/jsonContent.test.ts new file mode 100644 index 00000000..308fe8df --- /dev/null +++ b/src/test/content/jsonContent.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it } from '@jest/globals'; + +import { JsonContent } from '../../content/jsonContent'; + +describe('JsonContent', () => { + it('should have application/json as the default media type', () => { + const content: JsonContent> = new JsonContent({}); + expect(content.headers['content-type']).toBe('application/json'); + }); + + it('should respond with the original object', async () => { + const mockObject: Record = { + count: 6, + success: true, + type: 'fake', + }; + + const content: unknown = await new JsonContent(mockObject).readAsync(); + + expect(content).toBe(mockObject); + }); +}); diff --git a/src/test/content/streamContent.test.ts b/src/test/content/streamContent.test.ts new file mode 100644 index 00000000..7d924c8a --- /dev/null +++ b/src/test/content/streamContent.test.ts @@ -0,0 +1,51 @@ +import { Readable, Writable } from 'node:stream'; + +import { describe, expect, it } from '@jest/globals'; + +import { StreamContent } from '../../content/streamContent'; + +describe('StreamContent', () => { + it('should have text/plain as the set media type', () => { + const stream: Readable = new Readable(); + + const content: StreamContent = new StreamContent(stream, 'text/plain'); + + expect(content.headers['content-type']).toEqual('text/plain'); + }); + + it('should be able to pipe stream which was given to it', async () => { + const stream: Readable = new Readable({ + read() { + this.push(Buffer.from('test')); + this.push(null); + }, + }); + + const readable: Readable = await new StreamContent( + stream, + 'text/plain', + ).readAsync(); + + const chunks: Array = []; + + let buffer: Buffer | null = null; + + return new Promise((resolve: () => void) => { + readable.on('end', () => { + buffer = Buffer.concat(chunks); + + expect(buffer.toString()).toEqual('test'); + + resolve(); + }); + + const writableStream: Writable = new Writable({ + write(chunk: unknown) { + chunks.push(chunk as Buffer); + }, + }); + + readable.pipe(writableStream); + }); + }); +}); diff --git a/test/debug.test.ts b/src/test/debug.test.ts similarity index 68% rename from test/debug.test.ts rename to src/test/debug.test.ts index e30ac5f3..e8b44853 100644 --- a/test/debug.test.ts +++ b/src/test/debug.test.ts @@ -1,15 +1,26 @@ +import { beforeEach, describe, expect, it } from '@jest/globals'; import { Container } from 'inversify'; -import { cleanUpMetadata } from '../src/utils'; -import { InversifyExpressServer, controller, httpGet, requestParam, httpPost, httpDelete, getRouteInfo, BaseHttpController } from '../src/index'; + +import { BaseHttpController } from '../base_http_controller'; +import { getRouteInfo } from '../debug'; +import { + controller, + httpDelete, + httpGet, + httpPost, + requestParam, +} from '../decorators'; +import { RouteInfo } from '../interfaces'; +import { InversifyExpressServer } from '../server'; +import { cleanUpMetadata } from '../utils'; describe('Debug utils', () => { - beforeEach(done => { + beforeEach(() => { cleanUpMetadata(); - done(); }); it('should be able to get router info', () => { - const container = new Container(); + const container: Container = new Container(); @controller('/api/user') class UserController extends BaseHttpController { @@ -24,7 +35,7 @@ describe('Debug utils', () => { } @httpDelete('/:id') - public delete(@requestParam('id') id: string) { + public delete(@requestParam('id') _id: string) { return {}; } } @@ -42,20 +53,23 @@ describe('Debug utils', () => { } @httpDelete('/:id') - public delete(@requestParam('id') id: string) { + public delete(@requestParam('id') _id: string) { return {}; } } + // eslint-disable-next-line @typescript-eslint/typedef const TYPES = { OrderController: OrderController.name, UserController: UserController.name, }; - const server = new InversifyExpressServer(container); + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); server.build(); - const routeInfo = getRouteInfo(container); + const routeInfo: RouteInfo[] = getRouteInfo(container); expect(routeInfo[0]?.controller).toBe(TYPES.OrderController); expect(routeInfo[0]?.endpoints[0]?.route).toBe('GET /api/order/'); @@ -64,7 +78,7 @@ describe('Debug utils', () => { expect(routeInfo[0]?.endpoints[1]?.args).toBeUndefined(); expect(routeInfo[0]?.endpoints[2]?.route).toBe('DELETE /api/order/:id'); - const arg1 = routeInfo[0]?.endpoints[2]?.args; + const arg1: string[] | undefined = routeInfo[0]?.endpoints[2]?.args; if (arg1 !== undefined) { expect(arg1[0]).toBe('@requestParam id'); } else { @@ -78,7 +92,7 @@ describe('Debug utils', () => { expect(routeInfo[1]?.endpoints[1]?.args).toBeUndefined(); expect(routeInfo[1]?.endpoints[2]?.route).toBe('DELETE /api/user/:id'); - const arg2 = routeInfo[1]?.endpoints[2]?.args; + const arg2: string[] | undefined = routeInfo[1]?.endpoints[2]?.args; if (arg2 !== undefined) { expect(arg2[0]).toBe('@requestParam id'); } else { @@ -87,7 +101,7 @@ describe('Debug utils', () => { }); it('should be able to handle missig parameter metadata', () => { - const container = new Container(); + const container: Container = new Container(); @controller('/api/order') class OrderController extends BaseHttpController { @@ -102,14 +116,17 @@ describe('Debug utils', () => { } } + // eslint-disable-next-line @typescript-eslint/typedef const TYPES = { OrderController: OrderController.name, }; - const server = new InversifyExpressServer(container); + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); server.build(); - const routeInfo = getRouteInfo(container); + const routeInfo: RouteInfo[] = getRouteInfo(container); expect(routeInfo[0]?.controller).toBe(TYPES.OrderController); expect(routeInfo[0]?.endpoints[0]?.route).toBe('GET /api/order/'); diff --git a/test/decorators.test.ts b/src/test/decorators.test.ts similarity index 51% rename from test/decorators.test.ts rename to src/test/decorators.test.ts index 0f653baf..380ef08b 100644 --- a/test/decorators.test.ts +++ b/src/test/decorators.test.ts @@ -1,19 +1,28 @@ -import { controller, httpMethod, params } from '../src/decorators'; -import { HTTP_VERBS_ENUM, METADATA_KEY, PARAMETER_TYPE } from '../src/constants'; -import { ControllerMetadata, ControllerMethodMetadata, ControllerParameterMetadata, ParameterMetadata } from '../src'; +import { describe, expect, it } from '@jest/globals'; + +import { HTTP_VERBS_ENUM, METADATA_KEY, PARAMETER_TYPE } from '../constants'; +import { controller, httpMethod, params } from '../decorators'; +import { + ControllerMetadata, + ControllerMethodMetadata, + ControllerParameterMetadata, + Middleware, + ParameterMetadata, +} from '../interfaces'; describe('Unit Test: Controller Decorators', () => { - - it('should add controller metadata to a class when decorated with @controller', done => { - const middleware = [() => { - // - }, 'foo', Symbol.for('bar')]; - const path = 'foo'; + it('should add controller metadata to a class when decorated with @controller', () => { + const middleware: Middleware[] = [ + () => undefined, + 'foo', + Symbol.for('bar'), + ]; + const path: string = 'foo'; @controller(path, ...middleware) - class TestController { } + class TestController {} - const controllerMetadata = Reflect.getMetadata( + const controllerMetadata: ControllerMetadata = Reflect.getMetadata( METADATA_KEY.controller, TestController, ) as ControllerMetadata; @@ -21,34 +30,35 @@ describe('Unit Test: Controller Decorators', () => { expect(controllerMetadata.middleware).toEqual(middleware); expect(controllerMetadata.path).toEqual(path); expect(controllerMetadata.target).toEqual(TestController); - done(); }); - it('should add method metadata to a class when decorated with @httpMethod', done => { - const middleware = [() => { - // - }, 'bar', Symbol.for('baz')]; - const path = 'foo'; - const method: keyof typeof HTTP_VERBS_ENUM = 'get'; + it('should add method metadata to a class when decorated with @httpMethod', () => { + const middleware: Middleware[] = [ + () => undefined, + 'bar', + Symbol.for('baz'), + ]; + const path: string = 'foo'; + const method: HTTP_VERBS_ENUM = HTTP_VERBS_ENUM.get; class TestController { @httpMethod(method, path, ...middleware) public test() { - // + return undefined; } - @httpMethod('foo' as unknown as keyof typeof HTTP_VERBS_ENUM, 'bar') + @httpMethod('foo' as unknown as HTTP_VERBS_ENUM, 'bar') public test2() { - // + return undefined; } - @httpMethod('bar' as unknown as keyof typeof HTTP_VERBS_ENUM, 'foo') + @httpMethod('bar' as unknown as HTTP_VERBS_ENUM, 'foo') public test3() { - // + return undefined; } } - const methodMetadata = Reflect.getMetadata( + const methodMetadata: ControllerMethodMetadata[] = Reflect.getMetadata( METADATA_KEY.controllerMethod, TestController, ) as ControllerMethodMetadata[]; @@ -62,52 +72,55 @@ describe('Unit Test: Controller Decorators', () => { expect(metadata?.target.constructor).toEqual(TestController); expect(metadata?.key).toEqual('test'); expect(metadata?.method).toEqual(method); - done(); }); - it('should add parameter metadata to a class when decorated with @params', done => { - const middleware = [() => { - // - }, 'bar', Symbol.for('baz')]; - const path = 'foo'; - const method: keyof typeof HTTP_VERBS_ENUM = 'get'; - const methodName = 'test'; + it('should add parameter metadata to a class when decorated with @params', () => { + const middleware: Middleware[] = [ + () => { + // + }, + 'bar', + Symbol.for('baz'), + ]; + const path: string = 'foo'; + const method: HTTP_VERBS_ENUM = HTTP_VERBS_ENUM.get; + const methodName: string = 'test'; class TestController { @httpMethod(method, path, ...middleware) public test( - @params(PARAMETER_TYPE.PARAMS, 'id') id: unknown, - @params(PARAMETER_TYPE.PARAMS, 'cat') cat: Record + @params(PARAMETER_TYPE.PARAMS, 'id') _id: unknown, + @params(PARAMETER_TYPE.PARAMS, 'cat') _cat: Record, ) { // } - @httpMethod('foo' as unknown as keyof typeof HTTP_VERBS_ENUM, 'bar') + @httpMethod('foo' as unknown as HTTP_VERBS_ENUM, 'bar') public test2( - @params(PARAMETER_TYPE.PARAMS, 'dog') dog: Record) { + @params(PARAMETER_TYPE.PARAMS, 'dog') _dog: Record, + ) { // } - @httpMethod('bar' as unknown as keyof typeof HTTP_VERBS_ENUM, 'foo') + @httpMethod('bar' as unknown as HTTP_VERBS_ENUM, 'foo') public test3() { // } } - const methodMetadataList = Reflect.getMetadata( + const methodMetadataList: ControllerParameterMetadata = Reflect.getMetadata( METADATA_KEY.controllerParameter, TestController, ) as ControllerParameterMetadata; expect(methodMetadataList['test'] && true).toEqual(true); - const paramaterMetadataList: - ParameterMetadata[] | undefined = methodMetadataList[methodName]; + const paramaterMetadataList: ParameterMetadata[] | undefined = + methodMetadataList[methodName]; expect(paramaterMetadataList?.length).toEqual(2); const paramaterMetadata: ParameterMetadata | undefined = paramaterMetadataList?.[0]; expect(paramaterMetadata?.index).toEqual(0); expect(paramaterMetadata?.parameterName).toEqual('id'); - done(); }); }); diff --git a/src/test/features/controller_inheritance.test.ts b/src/test/features/controller_inheritance.test.ts new file mode 100644 index 00000000..4577d435 --- /dev/null +++ b/src/test/features/controller_inheritance.test.ts @@ -0,0 +1,262 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { beforeEach, describe, expect, it } from '@jest/globals'; +import { Application, json, urlencoded } from 'express'; +import { Container, injectable } from 'inversify'; +import { Response } from 'superagent'; +import supertest from 'supertest'; + +import { + controller, + httpDelete, + httpGet, + httpOptions, + httpPost, + httpPut, + requestBody, + requestParam, +} from '../../decorators'; +import { InversifyExpressServer } from '../../server'; +import { cleanUpMetadata } from '../../utils'; + +interface ResponseBody { + args: string; + status: number; +} + +function getDemoServer() { + interface Movie { + name: string; + } + + const container: Container = new Container(); + + @injectable() + class GenericController { + @httpGet('/') + public get() { + return { status: 'BASE GET!' }; + } + + @httpGet('/:id') + public getById(@requestParam('id') id: string) { + return { status: `BASE GET BY ID! ${id}` }; + } + + @httpPost('/') + public post(@requestBody() body: T) { + return { + args: body, + status: 'BASE POST!', + }; + } + + @httpPut('/:id') + public put(@requestBody() body: T, @requestParam('id') id: string) { + return { + args: body, + status: `BASE PUT! ${id}`, + }; + } + + @httpDelete('/:id') + public delete(@requestParam('id') id: string) { + return { status: `BASE DELETE! ${id}` }; + } + + @httpOptions('/:id') + public options(@requestParam('id') id: string) { + return { status: `BASE OPTIONS! ${id}` }; + } + } + + @controller('/api/v1/movies') + class MoviesController extends GenericController { + @httpDelete('/:movieId/actors/:actorId') + public deleteActor( + @requestParam('movieId') movieId: string, + @requestParam('actorId') actorId: string, + ) { + return { + status: `DERIVED DELETE ACTOR! MOVIECONTROLLER1 ${movieId} ${actorId}`, + }; + } + } + + @controller('/api/v1/movies2') + class MoviesController2 extends GenericController { + @httpDelete('/:movieId2/actors/:actorId2') + public deleteActor( + @requestParam('movieId2') movieId: string, + @requestParam('actorId2') actorId: string, + ) { + return { + status: `DERIVED DELETE ACTOR! MOVIECONTROLLER2 ${movieId} ${actorId}`, + }; + } + } + + @controller('/api/v1/movies3') + class MoviesController3 extends GenericController { + @httpDelete('/:movieId3/actors/:actorId3') + public deleteActor( + @requestParam('movieId3') movieId: string, + @requestParam('actorId3') actorId: string, + ) { + return { + status: `DERIVED DELETE ACTOR! MOVIECONTROLLER3 ${movieId} ${actorId}`, + }; + } + } + + const app: InversifyExpressServer = new InversifyExpressServer(container); + + app.setConfig((a: Application) => { + a.use(json()); + a.use(urlencoded({ extended: true })); + }); + + const server: Application = app.build(); + + return server; +} + +describe('Derived controller', () => { + beforeEach(() => { + cleanUpMetadata(); + }); + + it('Can access methods decorated with @httpGet from parent', async () => { + const server: Application = getDemoServer(); + + const response: Response = await supertest(server) + .get('/api/v1/movies') + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + + expect(body.status).toEqual('BASE GET!'); + }); + + it('Can access methods decorated with @httpGet from parent', async () => { + const server: Application = getDemoServer(); + const id: number = 5; + + const response: Response = await supertest(server) + .get(`/api/v1/movies/${id.toString()}`) + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + + expect(body.status).toEqual(`BASE GET BY ID! ${id.toString()}`); + }); + + it('Can access methods decorated with @httpPost from parent', async () => { + const server: Application = getDemoServer(); + const movie: object = { name: 'The Shining' }; + const status: string = 'BASE POST!'; + + const response: Response = await supertest(server) + .post('/api/v1/movies') + .send(movie) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json') + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + expect(body.status).toEqual(status); + expect(body.args).toEqual(movie); + }); + + it('Can access methods decorated with @httpPut from parent', async () => { + const server: Application = getDemoServer(); + const id: number = 5; + const movie: object = { name: 'The Shining' }; + + const response: Response = await supertest(server) + .put(`/api/v1/movies/${id.toString()}`) + .send(movie) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json') + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + expect(body.status).toEqual(`BASE PUT! ${id.toString()}`); + expect(body.args).toEqual(movie); + }); + + it('Can access methods decorated with @httpDelete from parent', async () => { + const server: Application = getDemoServer(); + const id: number = 5; + + const response: Response = await supertest(server) + .delete(`/api/v1/movies/${id.toString()}`) + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + expect(body.status).toEqual(`BASE DELETE! ${id.toString()}`); + }); + + it('Can access methods decorated with @httpOptions from parent', async () => { + const server: Application = getDemoServer(); + const id: number = 5; + + const response: Response = await supertest(server) + .options(`/api/v1/movies/${id.toString()}`) + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + expect(body.status).toEqual(`BASE OPTIONS! ${id.toString()}`); + }); + + it('Derived controller can have its own methods', async () => { + const server: Application = getDemoServer(); + const movieId: number = 5; + const actorId: number = 3; + + const response: Response = await supertest(server) + .delete( + `/api/v1/movies/${movieId.toString()}/actors/${actorId.toString()}`, + ) + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + expect(body.status).toEqual( + `DERIVED DELETE ACTOR! MOVIECONTROLLER1 ${movieId.toString()} ${actorId.toString()}`, + ); + }); + + it('Derived controller 2 can have its own methods', async () => { + const server: Application = getDemoServer(); + const movieId: number = 5; + const actorId: number = 3; + + const response: Response = await supertest(server) + .delete( + `/api/v1/movies2/${movieId.toString()}/actors/${actorId.toString()}`, + ) + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + expect(body.status).toEqual( + `DERIVED DELETE ACTOR! MOVIECONTROLLER2 ${movieId.toString()} ${actorId.toString()}`, + ); + }); + + it('Derived controller 3 can have its own methods', async () => { + const server: Application = getDemoServer(); + const movieId: number = 5; + const actorId: number = 3; + + const response: Response = await supertest(server) + .delete( + `/api/v1/movies3/${movieId.toString()}/actors/${actorId.toString()}`, + ) + .expect(200); + + const body: ResponseBody = response.body as ResponseBody; + + expect(body.status).toEqual( + `DERIVED DELETE ACTOR! MOVIECONTROLLER3 ${movieId.toString()} ${actorId.toString()}`, + ); + }); +}); diff --git a/src/test/features/decorator_middleware.test.ts b/src/test/features/decorator_middleware.test.ts new file mode 100644 index 00000000..b69bf4c8 --- /dev/null +++ b/src/test/features/decorator_middleware.test.ts @@ -0,0 +1,322 @@ +import { beforeEach, describe, it } from '@jest/globals'; +import assert from 'assert'; +import * as express from 'express'; +import { Container } from 'inversify'; +import { Response } from 'superagent'; +import supertest from 'supertest'; + +import { BaseMiddleware } from '../../base_middleware'; +import { HTTP_VERBS_ENUM, METADATA_KEY } from '../../constants'; +import { + controller, + httpGet, + httpMethod, + httpPut, + withMiddleware, +} from '../../decorators'; +import { + ControllerMetadata, + ControllerMethodMetadata, + DecoratorTarget, +} from '../../interfaces'; +import { InversifyExpressServer } from '../../server'; +import { cleanUpMetadata } from '../../utils'; + +function cleanUpMidDecTestControllerMetadata() { + class MidDecTestController {} + Reflect.defineMetadata( + METADATA_KEY.middleware, + {}, + MidDecTestController.constructor, + ); +} + +describe('Unit Test: @middleware decorator', () => { + beforeEach(() => { + cleanUpMetadata(); + cleanUpMidDecTestControllerMetadata(); + }); + + it('should add method metadata to a class when a handler is decorated with @withMiddleware', () => { + const functionMiddleware: () => void = () => undefined; + const identifierMiddleware: symbol = Symbol.for('foo'); + const path: string = 'foo'; + const method: HTTP_VERBS_ENUM = HTTP_VERBS_ENUM.get; + + class MidDecTestController { + @httpMethod(method, path) + @withMiddleware(functionMiddleware) + public test() { + // do nothing + } + + @httpMethod(method, path) + @withMiddleware(functionMiddleware, identifierMiddleware) + public test2() { + // do nothing + } + } + + const methodMetadata: ControllerMethodMetadata[] = Reflect.getMetadata( + METADATA_KEY.controllerMethod, + MidDecTestController, + ) as ControllerMethodMetadata[]; + + const [testMetaData, test2MetaData]: ControllerMethodMetadata[] = + methodMetadata; + assert.strictEqual(testMetaData?.middleware.length, 1); + assert.strictEqual(test2MetaData?.middleware.length, 2); + assert.deepStrictEqual(testMetaData.middleware, [functionMiddleware]); + assert.deepStrictEqual(test2MetaData.middleware, [ + functionMiddleware, + identifierMiddleware, + ]); + }); + + it('should add class metadata to a controller class when decorated with @withMiddleware', () => { + const identifierMiddleware: symbol = Symbol.for('foo'); + const functionMiddleware: () => void = () => undefined; + + @controller('/foo') + @withMiddleware(identifierMiddleware, functionMiddleware) + class MidDecTestController {} + + const controllerMetaData: ControllerMetadata = Reflect.getMetadata( + METADATA_KEY.controller, + MidDecTestController, + ) as ControllerMetadata; + + assert.strictEqual(controllerMetaData.middleware.length, 2); + assert.deepStrictEqual(controllerMetaData.middleware, [ + identifierMiddleware, + functionMiddleware, + ]); + }); + + it('should be able to add middleware from multiple decorations', () => { + const identifierMiddleware: symbol = Symbol.for('foo'); + const functionMiddleware: () => void = () => undefined; + + const first: ( + target: DecoratorTarget | NewableFunction, + methodName?: string, + ) => void = withMiddleware(identifierMiddleware); + const second: ( + target: DecoratorTarget | NewableFunction, + methodName?: string, + ) => void = withMiddleware(functionMiddleware); + + @controller('/foo') + @first + @second + class MidDecTestController {} + + const controllerMetaData: ControllerMetadata = Reflect.getMetadata( + METADATA_KEY.controller, + MidDecTestController, + ) as ControllerMetadata; + + assert.strictEqual(controllerMetaData.middleware.length, 2); + assert.deepStrictEqual(controllerMetaData.middleware, [ + functionMiddleware, + identifierMiddleware, + ]); + }); + + it('should process all requests when decorating a controller', async () => { + const addTestHeader: ( + target: DecoratorTarget | NewableFunction, + methodName?: string, + ) => void = withMiddleware( + ( + _req: express.Request, + res: express.Response, + next: express.NextFunction, + ) => { + res.set('test-header', 'foo'); + next(); + }, + ); + + @controller('/foo') + @addTestHeader + class MidDecTestController { + @httpGet('/bar') + public get() { + return { data: 'hello' }; + } + + @httpPut('/baz') + public put() { + return { data: 'there' }; + } + } + + const container: Container = new Container(); + container + .bind('MidDecTestController') + .to(MidDecTestController); + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + const app: express.Application = server.build(); + + const barResponse: Response = await supertest(app).get('/foo/bar'); + const bazResponse: Response = await supertest(app).put('/foo/baz'); + + assert.strictEqual(barResponse.header['test-header'], 'foo'); + assert.strictEqual(bazResponse.header['test-header'], 'foo'); + }); + + it('should process only specific requests when decorating a handler', async () => { + const addTestHeader: ( + target: DecoratorTarget | NewableFunction, + methodName?: string, + ) => void = withMiddleware( + ( + _req: express.Request, + res: express.Response, + next: express.NextFunction, + ) => { + res.set('test-header', 'foo'); + next(); + }, + ); + + @controller('/foo') + class MidDecTestController { + @httpGet('/bar') + public get() { + return { data: 'hello' }; + } + + @httpPut('/baz') + @addTestHeader + public put() { + return { data: 'there' }; + } + } + + const container: Container = new Container(); + container + .bind('MidDecTestController') + .to(MidDecTestController); + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + const app: express.Application = server.build(); + + const barResponse: Response = await supertest(app).get('/foo/bar'); + const bazResponse: Response = await supertest(app).put('/foo/baz'); + + assert.strictEqual(barResponse.header['test-header'], undefined); + assert.strictEqual(bazResponse.header['test-header'], 'foo'); + }); + + it('should process requests with both controller- and handler middleware', async () => { + const addHandlerHeader: ( + target: DecoratorTarget | NewableFunction, + methodName?: string, + ) => void = withMiddleware( + ( + _req: express.Request, + res: express.Response, + next: express.NextFunction, + ) => { + res.set('test-handler', 'hello there!'); + next(); + }, + ); + + const addControllerHeader: ( + target: DecoratorTarget | NewableFunction, + methodName?: string, + ) => void = withMiddleware( + ( + _req: express.Request, + res: express.Response, + next: express.NextFunction, + ) => { + res.set('test-controller', 'general kenobi'); + next(); + }, + ); + + @controller('/foo') + @addControllerHeader + class MidDecTestController { + @httpGet('/bar') + public get() { + return { data: 'hello' }; + } + + @httpPut('/baz') + @addHandlerHeader + public put() { + return { data: 'there' }; + } + } + + const container: Container = new Container(); + container + .bind('MidDecTestController') + .to(MidDecTestController); + + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + const app: express.Application = server.build(); + + const barResponse: Response = await supertest(app).get('/foo/bar'); + + assert.strictEqual(barResponse.header['test-controller'], 'general kenobi'); + assert.strictEqual(barResponse.header['test-handler'], undefined); + + const bazResponse: Response = await supertest(app).put('/foo/baz'); + + assert.strictEqual(bazResponse.header['test-controller'], 'general kenobi'); + assert.strictEqual(bazResponse.header['test-handler'], 'hello there!'); + }); + + it('should be able to inject BaseMiddleware services by identifier', async () => { + const container: Container = new Container(); + class MidDecTestMiddleware extends BaseMiddleware { + public handler( + _req: express.Request, + res: express.Response, + next: express.NextFunction, + ) { + res.set('test-base-middleware', 'working'); + next(); + } + } + container + .bind('TestMiddleware') + .to(MidDecTestMiddleware); + + @controller('/foo') + @withMiddleware('TestMiddleware') + class MidDecTestController { + @httpGet('/bar') + public get() { + return { data: 'hello' }; + } + } + container + .bind('MidDecTestController') + .to(MidDecTestController); + + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + const app: express.Application = server.build(); + + const response: Response = await supertest(app).get('/foo/bar'); + + assert.strictEqual(response.header['test-base-middleware'], 'working'); + }); +}); diff --git a/src/test/framework.test.ts b/src/test/framework.test.ts new file mode 100644 index 00000000..959c9387 --- /dev/null +++ b/src/test/framework.test.ts @@ -0,0 +1,152 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { beforeEach, describe, expect, it, jest } from '@jest/globals'; +import express, { + Application, + NextFunction, + Request, + Response, + Router, +} from 'express'; +import { Container } from 'inversify'; + +import { controller } from '../decorators'; +import { HttpResponseMessage } from '../httpResponseMessage'; +import { ConfigFunction, Middleware, RoutingConfig } from '../interfaces'; +import { InversifyExpressServer } from '../server'; +import { cleanUpMetadata } from '../utils'; + +interface ServerWithTypes { + _app: Application; + _router: Router; + _routingConfig: RoutingConfig; + handleHttpResponseMessage: ( + message: HttpResponseMessage, + res: Response, + ) => void; +} + +describe('Unit Test: InversifyExpressServer', () => { + beforeEach(() => { + cleanUpMetadata(); + }); + + it('should call the configFn before the errorConfigFn', () => { + const middleware: Middleware = ( + _req: Request, + _res: Response, + _next: NextFunction, + ) => undefined; + + const configFn: jest.Mock = jest.fn((app: Application) => { + app.use(middleware); + }); + + const errorConfigFn: jest.Mock = jest.fn( + (app: Application) => { + app.use(middleware); + }, + ); + + const container: Container = new Container(); + + @controller('/') + class TestController {} + + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + server.setConfig(configFn).setErrorConfig(errorConfigFn); + + expect(configFn).not.toHaveBeenCalled(); + expect(errorConfigFn).not.toHaveBeenCalled(); + + server.build(); + + expect(configFn).toHaveBeenCalledTimes(1); + expect(errorConfigFn).toHaveBeenCalledTimes(1); + }); + + it('Should allow to pass a custom Router instance as config', () => { + const container: Container = new Container(); + + const customRouter: Router = Router({ + caseSensitive: false, + mergeParams: false, + strict: false, + }); + + const serverWithDefaultRouter: InversifyExpressServer = + new InversifyExpressServer(container); + const serverWithCustomRouter: InversifyExpressServer = + new InversifyExpressServer(container, customRouter); + + expect( + (serverWithDefaultRouter as unknown as ServerWithTypes)._router === + customRouter, + ).toBe(false); + expect( + (serverWithCustomRouter as unknown as ServerWithTypes)._router === + customRouter, + ).toBe(true); + }); + + it('Should allow to provide custom routing configuration', () => { + const container: Container = new Container(); + + // eslint-disable-next-line @typescript-eslint/typedef + const routingConfig = { + rootPath: '/such/root/path', + }; + + const serverWithDefaultConfig: InversifyExpressServer = + new InversifyExpressServer(container); + const serverWithCustomConfig: InversifyExpressServer = + new InversifyExpressServer(container, null, routingConfig); + + expect( + (serverWithCustomConfig as unknown as ServerWithTypes)._routingConfig, + ).toBe(routingConfig); + + expect( + (serverWithDefaultConfig as unknown as ServerWithTypes)._routingConfig, + ).not.toEqual( + (serverWithCustomConfig as unknown as ServerWithTypes)._routingConfig, + ); + }); + + it('Should allow to provide a custom express application', () => { + const container: Container = new Container(); + const app: Application = express(); + const serverWithDefaultApp: InversifyExpressServer = + new InversifyExpressServer(container); + const serverWithCustomApp: InversifyExpressServer = + new InversifyExpressServer(container, null, null, app); + + expect((serverWithCustomApp as unknown as ServerWithTypes)._app).toBe(app); + expect( + (serverWithDefaultApp as unknown as ServerWithTypes)._app, + ).not.toEqual((serverWithCustomApp as unknown as ServerWithTypes)._app); + }); + + it('Should handle a HttpResponseMessage that has no content', () => { + const container: Container = new Container(); + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + const httpResponseMessageWithoutContent: HttpResponseMessage = + new HttpResponseMessage(404); + + const mockResponse: Partial> = { + sendStatus: jest.fn() as unknown, + } as Partial>; + + (server as unknown as ServerWithTypes).handleHttpResponseMessage( + httpResponseMessageWithoutContent, + mockResponse as unknown as Response, + ); + + expect(mockResponse.sendStatus).toHaveBeenCalledWith(404); + }); +}); diff --git a/test/helpers/jest.setup.ts b/src/test/helpers/jest.setup.ts similarity index 100% rename from test/helpers/jest.setup.ts rename to src/test/helpers/jest.setup.ts diff --git a/src/test/http_context.test.ts b/src/test/http_context.test.ts new file mode 100644 index 00000000..6187a210 --- /dev/null +++ b/src/test/http_context.test.ts @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { beforeEach, describe, expect, it } from '@jest/globals'; +import { Container, inject } from 'inversify'; +import supertest from 'supertest'; + +import { controller, httpGet, injectHttpContext } from '../decorators'; +import { HttpContext } from '../interfaces'; +import { InversifyExpressServer } from '../server'; +import { cleanUpMetadata } from '../utils'; + +describe('HttpContex', () => { + beforeEach(() => { + cleanUpMetadata(); + }); + + it('Should be able to httpContext manually with the @injectHttpContext decorator', async () => { + interface SomeDependency { + name: string; + } + + @controller('/') + class TestController { + @injectHttpContext private readonly _httpContext!: HttpContext; + @inject('SomeDependency') + private readonly _someDependency!: SomeDependency; + + @httpGet('/') + public async getTest() { + const headerVal: string | string[] | undefined = + this._httpContext.request.headers['x-custom']; + const { name }: SomeDependency = this._someDependency; + const isAuthenticated: boolean = + await this._httpContext.user.isAuthenticated(); + expect(isAuthenticated).toBe(false); + return `${headerVal as string} & ${name}`; + } + } + + const container: Container = new Container(); + + container + .bind('SomeDependency') + .toConstantValue({ name: 'SomeDependency!' }); + + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + + await supertest(server.build()) + .get('/') + .set('x-custom', 'test-header!') + .expect(200, 'test-header! & SomeDependency!'); + }); +}); diff --git a/src/test/issue_590.test.ts b/src/test/issue_590.test.ts new file mode 100644 index 00000000..6545dca8 --- /dev/null +++ b/src/test/issue_590.test.ts @@ -0,0 +1,36 @@ +import { beforeEach, describe, expect, it } from '@jest/globals'; +import { Application } from 'express'; +import { Container } from 'inversify'; + +import { NO_CONTROLLERS_FOUND } from '../constants'; +import { InversifyExpressServer } from '../server'; +import { cleanUpMetadata } from '../utils'; + +describe('Issue 590', () => { + beforeEach(() => { + cleanUpMetadata(); + }); + + it('should throw if no bindings for controllers are declared', () => { + const container: Container = new Container(); + const server: InversifyExpressServer = new InversifyExpressServer( + container, + ); + const throws: () => Application = (): Application => server.build(); + expect(throws).toThrowError(NO_CONTROLLERS_FOUND); + }); + + it('should not throw if forceControllers is false and no bindings for controllers are declared', () => { + const container: Container = new Container(); + const server: InversifyExpressServer = new InversifyExpressServer( + container, + null, + null, + null, + null, + false, + ); + const throws: () => Application = (): Application => server.build(); + expect(throws).not.toThrowError(); + }); +}); diff --git a/src/test/server.test.ts b/src/test/server.test.ts new file mode 100644 index 00000000..b652f581 --- /dev/null +++ b/src/test/server.test.ts @@ -0,0 +1,838 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { beforeEach, describe, expect, it, jest } from '@jest/globals'; +import cookieParser from 'cookie-parser'; +import { + Application, + CookieOptions, + json, + NextFunction, + Request, + RequestHandler, + Response, + Router, +} from 'express'; +import { interfaces } from 'inversify'; +import { Container, injectable } from 'inversify'; +import supertest from 'supertest'; +import TestAgent from 'supertest/lib/agent'; + +import { HTTP_VERBS_ENUM } from '../constants'; +import { + all, + controller, + cookies, + httpDelete, + httpGet, + httpHead, + httpMethod, + httpPatch, + httpPost, + httpPut, + next, + principal, + queryParam, + request, + requestBody, + requestHeaders, + requestParam, + response, +} from '../decorators'; +import { AuthProvider, Principal } from '../interfaces'; +import { InversifyExpressServer } from '../server'; +import { cleanUpMetadata } from '../utils'; + +describe('Integration Tests:', () => { + let server: InversifyExpressServer; + let container: interfaces.Container; + + beforeEach(() => { + cleanUpMetadata(); + container = new Container(); + }); + + describe('Routing & Request Handling:', () => { + it('should work for async controller methods', async () => { + @controller('/') + class TestController { + @httpGet('/') public async getTest(req: Request, res: Response) { + return new Promise((resolve: (value: string) => void) => { + setTimeout(() => { + resolve('GET'); + }, 10); + }); + } + } + + server = new InversifyExpressServer(container); + + await supertest(server.build()).get('/').expect(200, 'GET'); + }); + + it('should work for async controller methods that fails', async () => { + @controller('/') + class TestController { + @httpGet('/') public async getTest(req: Request, res: Response) { + return new Promise( + ( + _resolve: (value: unknown) => void, + reject: (reason: unknown) => void, + ) => { + setTimeout(() => { + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors + reject('GET'); + }, 10); + }, + ); + } + } + + server = new InversifyExpressServer(container); + + await supertest(server.build()).get('/').expect(500); + }); + + it('should work for methods which call nextFunc()', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest(req: Request, res: Response, nextFunc: NextFunction) { + nextFunc(); + } + + @httpGet('/') public getTest2(req: Request, res: Response) { + return 'GET'; + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).get('/').expect(200, 'GET'); + }); + + it('should work for async methods which call nextFunc()', async () => { + @controller('/') + class TestController { + @httpGet('/') + public async getTest( + _req: Request, + _res: Response, + nextFunc: NextFunction, + ) { + return new Promise((resolve: (value: unknown) => void) => { + setTimeout(() => { + nextFunc(); + resolve(null); + }, 10); + }); + } + + @httpGet('/') public getTest2(req: Request, res: Response) { + return 'GET'; + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).get('/').expect(200, 'GET'); + }); + + it('should work for async methods called by nextFunc()', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest(req: Request, res: Response, nextFunc: NextFunction) { + return nextFunc; + } + + @httpGet('/') public async getTest2(req: Request, res: Response) { + return new Promise((resolve: (value: string) => void) => { + setTimeout(() => { + resolve('GET'); + }, 10); + }); + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).get('/').expect(200, 'GET'); + }); + + it('should work for each shortcut decorator', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest(_req: Request, res: Response) { + res.send('GET'); + } + + @httpPost('/') + public postTest(_req: Request, res: Response) { + res.send('POST'); + } + + @httpPut('/') + public putTest(_req: Request, res: Response) { + res.send('PUT'); + } + + @httpPatch('/') + public patchTest(_req: Request, res: Response) { + res.send('PATCH'); + } + + @httpHead('/') + public headTest(_req: Request, res: Response) { + res.send('HEAD'); + } + + @httpDelete('/') + public deleteTest(_req: Request, res: Response) { + res.send('DELETE'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.get('/').expect(200, 'GET'); + await agent.post('/').expect(200, 'POST'); + await agent.put('/').expect(200, 'PUT'); + await agent.patch('/').expect(200, 'PATCH'); + await agent.head('/').expect(200, undefined); // HEAD requests have no body + await agent.delete('/').expect(200, 'DELETE'); + }); + + it('should work for more obscure HTTP methods using the httpMethod decorator', async () => { + @controller('/') + class TestController { + @httpMethod('propfind' as HTTP_VERBS_ENUM, '/') + public getTest(req: Request, res: Response) { + res.send('PROPFIND'); + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).propfind('/').expect(200, 'PROPFIND'); + }); + + it('should use returned values as response', async () => { + const result: unknown = { hello: 'world' }; + + @controller('/') + class TestController { + @httpGet('/') + public getTest(req: Request, res: Response) { + return result; + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()) + .get('/') + .expect(200, JSON.stringify(result)); + }); + + it('should use custom router passed from configuration', async () => { + @controller('/CaseSensitive') + class TestController { + @httpGet('/Endpoint') public get() { + return 'Such Text'; + } + } + + const customRouter: Router = Router({ + caseSensitive: true, + }); + + server = new InversifyExpressServer(container, customRouter); + const app: Application = server.build(); + + const expectedSuccess: supertest.Test = supertest(app) + .get('/CaseSensitive/Endpoint') + .expect(200, 'Such Text'); + + const expectedNotFound1: supertest.Test = supertest(app) + .get('/casesensitive/endpoint') + .expect(404); + + const expectedNotFound2: supertest.Test = supertest(app) + .get('/CaseSensitive/endpoint') + .expect(404); + + return Promise.all([ + expectedSuccess, + expectedNotFound1, + expectedNotFound2, + ]); + }); + + it('should use custom routing configuration', () => { + @controller('/ping') + class TestController { + @httpGet('/endpoint') public get() { + return 'pong'; + } + } + + server = new InversifyExpressServer(container, null, { + rootPath: '/api/v1', + }); + + return supertest(server.build()) + .get('/api/v1/ping/endpoint') + .expect(200, 'pong'); + }); + + it("should work for controller methods who's return value is falsey", async () => { + @controller('/user') + class TestController { + @httpDelete('/') public async delete(): Promise { + return undefined; + } + } + + server = new InversifyExpressServer(container); + + try { + await supertest(server.build()) + .delete('/user') + .timeout({ deadline: 200, response: 100 }); + + throw new Error( + 'Expected request to hang, but a response was received', + ); + } catch (error: unknown) { + if (!('timeout' in (error as object))) { + throw error; + } + } + }); + }); + + describe('Middleware:', () => { + let result: string; + interface Middleware { + a: (req: Request, res: Response, nextFunc: NextFunction) => void; + b: (req: Request, res: Response, nextFunc: NextFunction) => void; + c: (req: Request, res: Response, nextFunc: NextFunction) => void; + } + const middleware: Middleware = { + a(req: Request, res: Response, nextFunc: NextFunction) { + result += 'a'; + nextFunc(); + }, + b(req: Request, res: Response, nextFunc: NextFunction) { + result += 'b'; + nextFunc(); + }, + c(req: Request, res: Response, nextFunc: NextFunction) { + result += 'c'; + nextFunc(); + }, + }; + + const spyA: jest.Mock = jest + .fn() + .mockImplementation(middleware.a.bind(middleware)); + const spyB: jest.Mock = jest + .fn() + .mockImplementation(middleware.b.bind(middleware)); + const spyC: jest.Mock = jest + .fn() + .mockImplementation(middleware.c.bind(middleware)); + + beforeEach(() => { + spyA.mockClear(); + spyB.mockClear(); + spyC.mockClear(); + result = ''; + }); + + it('should call method-level middleware correctly (GET)', async () => { + @controller('/') + class TestController { + @httpGet('/', spyA, spyB, spyC) + public getTest(req: Request, res: Response) { + res.send('GET'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.get('/').expect(200, 'GET'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call method-level middleware correctly (POST)', async () => { + @controller('/') + class TestController { + @httpPost('/', spyA, spyB, spyC) + public postTest(req: Request, res: Response) { + res.send('POST'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.post('/').expect(200, 'POST'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call method-level middleware correctly (PUT)', async () => { + @controller('/') + class TestController { + @httpPut('/', spyA, spyB, spyC) + public postTest(req: Request, res: Response) { + res.send('PUT'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.put('/').expect(200, 'PUT'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call method-level middleware correctly (PATCH)', async () => { + @controller('/') + class TestController { + @httpPatch('/', spyA, spyB, spyC) + public postTest(req: Request, res: Response) { + res.send('PATCH'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.patch('/').expect(200, 'PATCH'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call method-level middleware correctly (HEAD)', async () => { + @controller('/') + class TestController { + @httpHead('/', spyA, spyB, spyC) + public postTest(req: Request, res: Response) { + res.send('HEAD'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.head('/').expect(200, undefined); // HEAD requests have no body + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call method-level middleware correctly (DELETE)', async () => { + @controller('/') + class TestController { + @httpDelete('/', spyA, spyB, spyC) + public postTest(req: Request, res: Response) { + res.send('DELETE'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.delete('/').expect(200, 'DELETE'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call method-level middleware correctly (ALL)', async () => { + @controller('/') + class TestController { + @all('/', spyA, spyB, spyC) + public postTest(req: Request, res: Response) { + res.send('ALL'); + } + } + + server = new InversifyExpressServer(container); + const agent: TestAgent = supertest(server.build()); + + await agent.get('/').expect(200, 'ALL'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call controller-level middleware correctly', async () => { + @controller('/', spyA, spyB, spyC) + class TestController { + @httpGet('/') + public getTest(req: Request, res: Response) { + res.send('GET'); + } + } + + server = new InversifyExpressServer(container); + + await supertest(server.build()).get('/').expect(200, 'GET'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call server-level middleware correctly', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest(req: Request, res: Response) { + res.send('GET'); + } + } + + server = new InversifyExpressServer(container); + + server.setConfig((app: Application) => { + app.use(spyA); + app.use(spyB); + app.use(spyC); + }); + + await supertest(server.build()).get('/').expect(200, 'GET'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should call all middleware in correct order', async () => { + @controller('/', spyB) + class TestController { + @httpGet('/', spyC) + public getTest(req: Request, res: Response) { + res.send('GET'); + } + } + + server = new InversifyExpressServer(container); + + server.setConfig((app: Application) => { + app.use(spyA); + }); + + await supertest(server.build()).get('/').expect(200, 'GET'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(spyC).toHaveBeenCalledTimes(1); + expect(result).toBe('abc'); + }); + + it('should resolve controller-level middleware', async () => { + const symbolId: symbol = Symbol.for('spyA'); + const strId: string = 'spyB'; + + @controller('/', symbolId, strId) + class TestController { + @httpGet('/') + public getTest(req: Request, res: Response) { + res.send('GET'); + } + } + + container.bind(symbolId).toConstantValue(spyA); + container.bind(strId).toConstantValue(spyB); + + server = new InversifyExpressServer(container); + + const agent: TestAgent = supertest(server.build()); + + await agent.get('/').expect(200, 'GET'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(result).toBe('ab'); + }); + + it('should resolve method-level middleware', async () => { + const symbolId: symbol = Symbol.for('spyA'); + const strId: string = 'spyB'; + + @controller('/') + class TestController { + @httpGet('/', symbolId, strId) + public getTest(req: Request, res: Response) { + res.send('GET'); + } + } + + container.bind(symbolId).toConstantValue(spyA); + container.bind(strId).toConstantValue(spyB); + + server = new InversifyExpressServer(container); + + const agent: TestAgent = supertest(server.build()); + + await agent.get('/').expect(200, 'GET'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(result).toBe('ab'); + }); + + it('should compose controller- and method-level middleware', async () => { + const symbolId: symbol = Symbol.for('spyA'); + const strId: string = 'spyB'; + + @controller('/', symbolId) + class TestController { + @httpGet('/', strId) + public getTest(req: Request, res: Response) { + res.send('GET'); + } + } + + container.bind(symbolId).toConstantValue(spyA); + container.bind(strId).toConstantValue(spyB); + + server = new InversifyExpressServer(container); + + const agent: TestAgent = supertest(server.build()); + + await agent.get('/').expect(200, 'GET'); + + expect(spyA).toHaveBeenCalledTimes(1); + expect(spyB).toHaveBeenCalledTimes(1); + expect(result).toBe('ab'); + }); + }); + + describe('Parameters:', () => { + it('should bind a method parameter to the url parameter of the web request', async () => { + @controller('/') + class TestController { + @httpGet(':id') + public getTest( + @requestParam('id') id: string, + req: Request, + res: Response, + ) { + return id; + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).get('/foo').expect(200, 'foo'); + }); + + it('should bind a method parameter to the request object', async () => { + @controller('/') + class TestController { + @httpGet(':id') + public getTest(@request() req: Request) { + return req.params['id']; + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).get('/GET').expect(200, 'GET'); + }); + + it('should bind a method parameter to the response object', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest(@response() res: Response) { + return res.send('foo'); + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).get('/').expect(200, 'foo'); + }); + + it('should bind a method parameter to a query parameter', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest(@queryParam('id') id: string) { + return id; + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()) + .get('/') + .query('id=foo') + .expect(200, 'foo'); + }); + + it('should bind a method parameter to the request body', async () => { + @controller('/') + class TestController { + @httpPost('/') public getTest(@requestBody() reqBody: string) { + return reqBody; + } + } + + server = new InversifyExpressServer(container); + const body: Record = { foo: 'bar' }; + server.setConfig((app: Application) => { + app.use(json()); + }); + + await supertest(server.build()).post('/').send(body).expect(200, body); + }); + + it('should bind a method parameter to the request headers', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest( + @requestHeaders('testhead') headers: Record, + ) { + return headers; + } + } + + server = new InversifyExpressServer(container); + + await supertest(server.build()) + .get('/') + .set('TestHead', 'foo') + .expect(200, 'foo'); + }); + + it('should be case insensitive to request headers', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getTest( + @requestHeaders('TestHead') headers: Record, + ) { + return headers; + } + } + + server = new InversifyExpressServer(container); + + await supertest(server.build()) + .get('/') + .set('TestHead', 'foo') + .expect(200, 'foo'); + }); + + it('should bind a method parameter to a cookie', async () => { + @controller('/') + class TestController { + @httpGet('/') public getCookie( + @cookies('Cookie') cookie: CookieOptions, + req: Request, + res: Response, + ) { + return cookie; + } + } + + server = new InversifyExpressServer(container); + server.setConfig((app: Application) => { + app.use(cookieParser()); + }); + + await supertest(server.build()) + .get('/') + .set('Cookie', 'Cookie=hey') + .expect(200, 'hey'); + }); + + it('should bind a method parameter to the next function', async () => { + @controller('/') + class TestController { + @httpGet('/') public getTest(@next() nextFunc: NextFunction) { + return nextFunc(); + } + + @httpGet('/') public getResult() { + return 'foo'; + } + } + + server = new InversifyExpressServer(container); + + await supertest(server.build()).get('/').expect(200, 'foo'); + }); + + it('should bind a method parameter to a principal with null (empty) details when no AuthProvider is set.', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getPrincipalTest(@principal() userPrincipal: Principal) { + return userPrincipal.details; + } + } + + server = new InversifyExpressServer(container); + await supertest(server.build()).get('/').expect(200, ''); + }); + + it('should bind a method parameter to a principal with valid details when an AuthProvider is set.', async () => { + @controller('/') + class TestController { + @httpGet('/') + public getPrincipalTest(@principal() userPrincipal: Principal) { + return userPrincipal.details; + } + } + + @injectable() + class CustomAuthProvider implements AuthProvider { + public async getUser( + req: Request, + res: Response, + nextFunc: NextFunction, + ): Promise { + return Promise.resolve({ + details: 'something', + isAuthenticated: async () => Promise.resolve(true), + isInRole: async () => Promise.resolve(true), + isResourceOwner: async () => Promise.resolve(true), + } as Principal); + } + } + + server = new InversifyExpressServer( + container, + null, + null, + null, + CustomAuthProvider, + ); + await supertest(server.build()).get('/').expect(200, 'something'); + }); + }); +}); diff --git a/src/tsconfig-es.json b/src/tsconfig-es.json deleted file mode 100644 index b2c3b398..00000000 --- a/src/tsconfig-es.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "compilerOptions": { - "outDir": "../es6", - "target": "ES6" - }, - "extends": "../tsconfig.json" -} \ No newline at end of file diff --git a/src/tsconfig-es6.json b/src/tsconfig-es6.json deleted file mode 100644 index fc6ba4e0..00000000 --- a/src/tsconfig-es6.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "compilerOptions": { - "outDir": "../es", - "target": "ES2015" - }, - "extends": "../tsconfig.json" -} \ No newline at end of file diff --git a/src/tsconfig.json b/src/tsconfig.json deleted file mode 100644 index 18db89c1..00000000 --- a/src/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "declaration": true, - "outDir": "../lib", - "rootDir": ".", - "target": "ES2015" - }, - "extends": "../tsconfig.json", - "include": [ - "./**/*.ts" - ] -} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 9baf1490..0635afa2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,16 @@ import { interfaces } from 'inversify'; + import { METADATA_KEY, NO_CONTROLLERS_FOUND, TYPE } from './constants'; -import type { Controller, ControllerMetadata, ControllerMethodMetadata, ControllerParameterMetadata, DecoratorTarget, IHttpActionResult, Middleware, MiddlewareMetaData } from './interfaces'; +import type { + Controller, + ControllerMetadata, + ControllerMethodMetadata, + ControllerParameterMetadata, + DecoratorTarget, + IHttpActionResult, + Middleware, + MiddlewareMetaData, +} from './interfaces'; export function getControllersFromContainer( container: interfaces.Container, @@ -8,7 +18,8 @@ export function getControllersFromContainer( ): Controller[] { if (container.isBound(TYPE.Controller)) { return container.getAll(TYPE.Controller); - } if (forceControllers) { + } + if (forceControllers) { throw new Error(NO_CONTROLLERS_FOUND); } else { return []; @@ -17,24 +28,28 @@ export function getControllersFromContainer( export function getControllersFromMetadata(): DecoratorTarget[] { const arrayOfControllerMetadata: ControllerMetadata[] = - Reflect.getMetadata( - METADATA_KEY.controller, - Reflect, - ) as ControllerMetadata[] || []; - return arrayOfControllerMetadata.map(metadata => metadata.target); + (Reflect.getMetadata(METADATA_KEY.controller, Reflect) as + | ControllerMetadata[] + | undefined) ?? []; + return arrayOfControllerMetadata.map( + (metadata: ControllerMetadata) => metadata.target, + ); } -export function getMiddlewareMetadata(constructor: DecoratorTarget, key: string) - : Middleware[] { - const middlewareMetadata = Reflect.getMetadata( - METADATA_KEY.middleware, - constructor - ) as MiddlewareMetaData || {}; - return middlewareMetadata[key] || []; +export function getMiddlewareMetadata( + constructor: DecoratorTarget, + key: string, +): Middleware[] { + const middlewareMetadata: MiddlewareMetaData = + (Reflect.getMetadata(METADATA_KEY.middleware, constructor) as + | MiddlewareMetaData + | undefined) ?? {}; + + return middlewareMetadata[key] ?? []; } export function getControllerMetadata( - constructor: NewableFunction + constructor: NewableFunction, ): ControllerMetadata { const controllerMetadata: ControllerMetadata = Reflect.getMetadata( METADATA_KEY.controller, @@ -46,19 +61,22 @@ export function getControllerMetadata( export function getControllerMethodMetadata( constructor: NewableFunction, ): ControllerMethodMetadata[] { - const methodMetadata = Reflect.getOwnMetadata( + const methodMetadata: ControllerMethodMetadata[] = Reflect.getOwnMetadata( METADATA_KEY.controllerMethod, constructor, ) as ControllerMethodMetadata[]; - const genericMetadata = Reflect.getMetadata( + const genericMetadata: ControllerMethodMetadata[] = Reflect.getMetadata( METADATA_KEY.controllerMethod, Reflect.getPrototypeOf(constructor) as NewableFunction, ) as ControllerMethodMetadata[]; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (genericMetadata !== undefined && methodMetadata !== undefined) { return methodMetadata.concat(genericMetadata); - } if (genericMetadata !== undefined) { + } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (genericMetadata !== undefined) { return genericMetadata; } return methodMetadata; @@ -77,33 +95,34 @@ export function getControllerParameterMetadata( Reflect.getPrototypeOf(constructor) as NewableFunction, ) as ControllerParameterMetadata; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (genericMetadata !== undefined && parameterMetadata !== undefined) { return { ...parameterMetadata, ...genericMetadata }; - } if (genericMetadata !== undefined) { + } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (genericMetadata !== undefined) { return genericMetadata; } return parameterMetadata; } export function cleanUpMetadata(): void { - Reflect.defineMetadata( - METADATA_KEY.controller, - [], - Reflect, - ); + Reflect.defineMetadata(METADATA_KEY.controller, [], Reflect); } -export function instanceOfIHttpActionResult( - value: unknown +export function instanceOfIhttpActionResult( + value: unknown, ): value is IHttpActionResult { - return value != null && - typeof (value as IHttpActionResult).executeAsync === 'function'; + return ( + value != null && + typeof (value as IHttpActionResult).executeAsync === 'function' + ); } export function getOrCreateMetadata( key: string, target: object, - defaultValue: T + defaultValue: T, ): T { if (!Reflect.hasMetadata(key, target)) { Reflect.defineMetadata(key, defaultValue, target); diff --git a/test/.eslintrc.js b/test/.eslintrc.js deleted file mode 100644 index 9296f6bc..00000000 --- a/test/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - rules: { - '@typescript-eslint/ban-ts-comment': 'off', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - 'max-classes-per-file': 'off', - }, -}; diff --git a/test/action_result.test.ts b/test/action_result.test.ts deleted file mode 100644 index 34d5e771..00000000 --- a/test/action_result.test.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { StatusCodes } from 'http-status-codes'; -import { BadRequestErrorMessageResult, BadRequestResult, ConflictResult, CreatedNegotiatedContentResult, ExceptionResult, InternalServerErrorResult, NotFoundResult, OkNegotiatedContentResult, OkResult, RedirectResult, ResponseMessageResult, StatusCodeResult } from '../src/results'; -import { HttpResponseMessage } from '../src/httpResponseMessage'; - -describe('ActionResults', () => { - describe('OkResult', () => { - it('should respond with an HTTP 200', async () => { - const actionResult = new OkResult(); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.OK); - }); - }); - - describe('OkNegotiatedContentResult', () => { - it('should respond with an HTTP 200 with content', async () => { - const content = { - foo: 'bar', - }; - const actionResult = new OkNegotiatedContentResult(content); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.OK); - expect( - await responseMessage.content.readAsync(), - ).toBe(JSON.stringify(content)); - }); - }); - - describe('BadRequestResult', () => { - it('should respond with an HTTP 400', async () => { - const actionResult = new BadRequestResult(); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.BAD_REQUEST); - }); - }); - - describe('BadRequestErrorMessageResult', () => { - it('should respond with an HTTP 400 and an error message', async () => { - const message = 'uh oh!'; - const actionResult = new BadRequestErrorMessageResult(message); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.BAD_REQUEST); - expect(await responseMessage.content.readAsync()).toBe(message); - }); - }); - - describe('ConflictResult', () => { - it('should respond with an HTTP 409', async () => { - const actionResult = new ConflictResult(); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.CONFLICT); - }); - }); - - describe('CreatedNegotiatedContentResult', () => { - it('should respond with an HTTP 302 and appropriate headers', async () => { - const uri = 'http://foo/bar'; - const content = { - foo: 'bar', - }; - - const actionResult = new CreatedNegotiatedContentResult(uri, content); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.CREATED); - expect( - await responseMessage.content.readAsync(), - ).toBe(JSON.stringify(content)); - expect(responseMessage.headers['location']).toBe(uri); - }); - }); - - describe('ExceptionResult', () => { - it('should respond with an HTTP 500 and the error message', async () => { - const error = new Error('foo'); - - const actionResult = new ExceptionResult(error); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode) - .toBe(StatusCodes.INTERNAL_SERVER_ERROR); - - expect(await responseMessage.content - .readAsync()) - .toBe('Error: foo'); - }); - }); - - describe('InternalServerErrorResult', () => { - it('should respond with an HTTP 500', async () => { - const actionResult = new InternalServerErrorResult(); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode) - .toBe(StatusCodes.INTERNAL_SERVER_ERROR); - }); - }); - - describe('NotFoundResult', () => { - it('should respond with an HTTP 404', async () => { - const actionResult = new NotFoundResult(); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.NOT_FOUND); - }); - }); - - describe('RedirectResult', () => { - it('should respond with an HTTP 302', async () => { - const uri = 'http://foo/bar'; - const actionResult = new RedirectResult(uri); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(StatusCodes.MOVED_TEMPORARILY); - expect(responseMessage.headers['location']).toBe(uri); - }); - }); - - describe('ResponseMessageResult', () => { - it('should respond with an HTTP 302', async () => { - const responseMessage = new HttpResponseMessage(200); - const actionResult = new ResponseMessageResult(responseMessage); - - expect(await actionResult.executeAsync()).toBe(responseMessage); - }); - }); - - describe('StatusCodeResult', () => { - it('should respond with the specified status code', async () => { - const actionResult = new StatusCodeResult(417); - const responseMessage = await actionResult.executeAsync(); - - expect(responseMessage.statusCode).toBe(417); - }); - }); -}); diff --git a/test/base_http_controller.test.ts b/test/base_http_controller.test.ts deleted file mode 100644 index 3ecd0be2..00000000 --- a/test/base_http_controller.test.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Container, inject } from 'inversify'; -import supertest from 'supertest'; -import { InversifyExpressServer, controller, httpGet, BaseHttpController, IHttpActionResult } from '../src/index'; -import { cleanUpMetadata } from '../src/utils'; -import { HttpResponseMessage } from '../src/httpResponseMessage'; -import { StringContent } from '../src/content/stringContent'; - -describe('BaseHttpController', () => { - beforeEach(done => { - cleanUpMetadata(); - done(); - }); - - it('Should contain httpContext instance', done => { - interface SomeDependency { - name: string; - } - - @controller('/') - class TestController extends BaseHttpController { - private readonly _someDependency: SomeDependency; - constructor( - @inject('SomeDependency') someDependency: SomeDependency, - ) { - super(); - this._someDependency = someDependency; - } - - @httpGet('/') - public async getTest() { - const headerVal = this.httpContext.request.headers['x-custom']; - const { name } = this._someDependency; - const isAuthenticated = await this.httpContext.user.isAuthenticated(); - expect(isAuthenticated).toBe(false); - return `${headerVal as string} & ${name}`; - } - } - - const container = new Container(); - - container.bind('SomeDependency') - .toConstantValue({ name: 'SomeDependency!' }); - - const server = new InversifyExpressServer(container); - - void supertest(server.build()) - .get('/') - .set('x-custom', 'test-header!') - .expect(200, 'test-header! & SomeDependency!', done); - }); - - it('should support returning an HttpResponseMessage from a method', - async () => { - @controller('/') - class TestController extends BaseHttpController { - @httpGet('/') - public async getTest() { - const response = new HttpResponseMessage(200); - response.headers['x-custom'] = 'test-header'; - response.content = new StringContent('12345'); - return Promise.resolve(response); - } - } - - const server = new InversifyExpressServer(new Container()); - - await supertest(server.build()) - .get('/') - .expect(200, '12345') - .expect('x-custom', 'test-header') - .expect('content-type', 'text/plain; charset=utf-8'); - }); - - it('should support returning an IHttpActionResult from a method', - async () => { - @controller('/') - class TestController extends BaseHttpController { - @httpGet('/') - public getTest() { - return new class TestActionResult implements IHttpActionResult { - public async executeAsync() { - const response = new HttpResponseMessage(400); - response.content = new StringContent('You done did that wrong'); - return Promise.resolve(response); - } - }(); - } - } - - const server = new InversifyExpressServer(new Container()); - - void await supertest(server.build()) - .get('/') - .expect(400, 'You done did that wrong'); - }); -}); diff --git a/test/base_middleware.test.ts b/test/base_middleware.test.ts deleted file mode 100644 index 9f4a89b6..00000000 --- a/test/base_middleware.test.ts +++ /dev/null @@ -1,293 +0,0 @@ -import { NextFunction, Request, Response } from 'express'; -import { parallel } from 'async'; -import { Container, injectable, inject, optional, } from 'inversify'; -import supertest from 'supertest'; -import { InversifyExpressServer, controller, httpGet, BaseMiddleware, BaseHttpController, Principal, AuthProvider, } from '../src/index'; -import { cleanUpMetadata } from '../src/utils'; - -describe('BaseMiddleware', () => { - beforeEach(done => { - cleanUpMetadata(); - done(); - }); - - it('Should be able to inject BaseMiddleware implementations', done => { - const TYPES = { - LoggerMiddleware: Symbol.for('LoggerMiddleware'), - SomeDependency: Symbol.for('SomeDependency'), - }; - - let principalInstanceCount = 0; - - class PrincipalClass implements Principal { - public details: unknown; - constructor(details: unknown) { - this.details = details; - } - - public isAuthenticated() { - return Promise.resolve(true); - } - - public isResourceOwner(resourceId: unknown) { - return Promise.resolve(resourceId === 1111); - } - - public isInRole(role: string) { - return Promise.resolve(role === 'admin'); - } - } - - @injectable() - class CustomAuthProvider implements AuthProvider { - public getUser( - req: Request, - res: Response, - next: NextFunction, - ) { - principalInstanceCount += 1; - const principal = new PrincipalClass({ - email: 'test@test.com', - }); - return Promise.resolve(principal); - } - } - - interface SomeDependency { - name: string; - } - - const logEntries: string[] = []; - - @injectable() - class LoggerMiddleware extends BaseMiddleware { - @inject(TYPES.SomeDependency) - private readonly _someDependency!: SomeDependency; - public handler( - req: Request, - res: Response, - next: NextFunction, - ) { - const { email } = this.httpContext.user.details as { email: string }; - logEntries.push(`${email} => ${req.url} ${this._someDependency.name}`); - next(); - } - } - - @controller( - '/', - (req, res, next) => { - logEntries.push('Hello from controller middleware!'); - next(); - }, - ) - class TestController extends BaseHttpController { - @httpGet( - '/', - TYPES.LoggerMiddleware, - ) - public async getTest() { - if (this.httpContext.user !== null) { - const { email } = this.httpContext.user.details as { email: string }; - const isAuthenticated = await this.httpContext.user.isAuthenticated(); - logEntries.push( - `${email} => isAuthenticated() => ${String(isAuthenticated)}` - ); - return `${email}`; - } - return null; - } - } - - const container = new Container(); - - container.bind(TYPES.SomeDependency) - .toConstantValue({ name: 'SomeDependency!' }); - - container.bind(TYPES.LoggerMiddleware) - .to(LoggerMiddleware); - - const server = new InversifyExpressServer( - container, - null, - null, - null, - CustomAuthProvider, - ); - - void supertest(server.build()) - .get('/') - .expect(200, 'test@test.com', () => { - expect(principalInstanceCount).toBe(1); - expect(logEntries.length).toBe(3); - expect(logEntries[0]).toBe('Hello from controller middleware!'); - expect(logEntries[1]).toBe('test@test.com => / SomeDependency!'); - expect(logEntries[2]) - .toBe('test@test.com => isAuthenticated() => true'); - done(); - }); - }); - - it('Should allow the middleware to inject services in a HTTP request scope', done => { - const TRACE_HEADER = 'X-Trace-Id'; - - const TYPES = { - Service: Symbol.for('Service'), - TraceIdValue: Symbol.for('TraceIdValue'), - TracingMiddleware: Symbol.for('TracingMiddleware') - }; - - @injectable() - class TracingMiddleware extends BaseMiddleware { - public handler( - req: Request, - res: Response, - next: NextFunction, - ) { - setTimeout(() => { - this.bind(TYPES.TraceIdValue) - .toConstantValue(`${req.header(TRACE_HEADER) as string}`); - next(); - }, someTimeBetween(0, 500)); - } - } - - @injectable() - class Service { - constructor( - @inject(TYPES.TraceIdValue) - private readonly traceID: string) { - } - - public doSomethingThatRequiresTheTraceID() { - return new Promise((resolve, reject) => { - setTimeout(() => { - resolve(this.traceID); - }, someTimeBetween(0, 500)); - }); - } - } - - @controller('/') - class TracingTestController extends BaseHttpController { - constructor(@inject(TYPES.Service) private readonly service: Service) { - super(); - } - - @httpGet( - '/', - TYPES.TracingMiddleware, - ) - public getTest() { - return this.service.doSomethingThatRequiresTheTraceID(); - } - } - - const container = new Container(); - - container.bind(TYPES.TracingMiddleware) - .to(TracingMiddleware); - container.bind(TYPES.Service).to(Service); - container.bind(TYPES.TraceIdValue).toConstantValue('undefined'); - - const api = new InversifyExpressServer(container).build(); - - const expectedRequests = 100; - let handledRequests = 0; - - run(expectedRequests, (executionId: number) => supertest(api) - .get('/') - .set(TRACE_HEADER, `trace-id-${executionId}`) - .expect(200, `trace-id-${executionId}`) - .then(res => { - handledRequests += 1; - }), (err: Error | null | undefined) => { - expect(handledRequests).toBe(expectedRequests); - done(err); - }); - }); - - it('Should not allow services injected into a HTTP request scope to be accessible outside the request scope', done => { - const TYPES = { - Transaction: Symbol.for('Transaction'), - TransactionMiddleware: Symbol.for('TransactionMiddleware'), - }; - - class TransactionMiddleware extends BaseMiddleware { - private count = 0; - - public handler( - req: Request, - res: Response, - next: NextFunction, - ) { - this.bind(TYPES.Transaction) - .toConstantValue(`I am transaction #${this.count += 1}\n`); - next(); - } - } - - @controller('/') - class TransactionTestController extends BaseHttpController { - constructor( - @inject(TYPES.Transaction) - @optional() private transaction: string - ) { - super(); - } - - @httpGet('/1', TYPES.TransactionMiddleware) - public getTest1() { - return this.transaction; - } - - @httpGet('/2' /*<= No middleware!*/) - public getTest2() { - return this.transaction; - } - } - - const container = new Container(); - - container.bind( - TYPES.TransactionMiddleware, - ).to(TransactionMiddleware); - const app = new InversifyExpressServer(container).build(); - - void supertest(app) - .get('/1') - .expect(200, 'I am transaction #1', () => { - void supertest(app) - .get('/1') - .expect(200, 'I am transaction #2', () => { - void supertest(app) - .get('/2') - .expect(200, '', () => done() as unknown); - }); - }); - }); -}); - -function run( - parallelRuns: number, - test: (executionId: number) => PromiseLike, - done: (error?: Error | null) => void, -) { - const testTaskNo = (id: number) => - (cb: (err?: Error | null) => void) => { - test(id).then(cb as (value: unknown) => void | PromiseLike, cb); - }; - - const testTasks = Array.from( - { length: parallelRuns }, - (val: undefined, key: number) => testTaskNo(key), - ); - - parallel(testTasks, done); -} - -function someTimeBetween(minimum: number, maximum: number) { - const min = Math.ceil(minimum); - const max = Math.floor(maximum); - return Math.floor(Math.random() * (max - min + 1)) + min; -} diff --git a/test/constants.test.ts b/test/constants.test.ts deleted file mode 100644 index eb66668d..00000000 --- a/test/constants.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DUPLICATED_CONTROLLER_NAME } from '../src/constants'; - -describe('Constants test', () => { - - it('should return correct message', () => { - expect(DUPLICATED_CONTROLLER_NAME('test')) - .toBe('Two controllers cannot have the same name: test'); - }); - -}); \ No newline at end of file diff --git a/test/content/jsonContent.test.ts b/test/content/jsonContent.test.ts deleted file mode 100644 index 1c8d64b5..00000000 --- a/test/content/jsonContent.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { JsonContent } from '../../src/content/jsonContent'; - -describe('JsonContent', () => { - it('should have application/json as the default media type', () => { - const content = new JsonContent({}); - expect(content.headers['content-type']).toBe('application/json'); - }); - - it('should respond with the original object', done => { - const mockObject = { - count: 6, - success: true, - type: 'fake' - }; - - const content = new JsonContent(mockObject); - - void content.readAsync().then(value => { - expect(value).toBe(mockObject); - done(); - }); - }); -}); diff --git a/test/content/streamContent.test.ts b/test/content/streamContent.test.ts deleted file mode 100644 index 4ed6facb..00000000 --- a/test/content/streamContent.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Readable, Writable } from 'stream'; -import { StreamContent } from '../../src/content/streamContent'; - -describe('StreamContent', () => { - it('should have text/plain as the set media type', () => { - const stream = new Readable(); - - const content = new StreamContent(stream, 'text/plain'); - - expect(content.headers['content-type']).toEqual('text/plain'); - }); - - it('should be able to pipe stream which was given to it', done => { - const stream = new Readable({ - read() { - this.push(Buffer.from('test')); - this.push(null); - }, - }); - - const content = new StreamContent(stream, 'text/plain'); - - void content.readAsync().then((readable: Readable) => { - const chunks: Array = []; - - let buffer: Buffer | null = null; - - readable.on('end', () => { - buffer = Buffer.concat(chunks); - - expect(buffer.toString()).toEqual('test'); - - done(); - }); - - const writableStream = new Writable({ - write(chunk) { - chunks.push(chunk as Buffer); - }, - }); - - readable.pipe(writableStream); - }); - }); -}); diff --git a/test/features/controller_inheritance.test.ts b/test/features/controller_inheritance.test.ts deleted file mode 100644 index e7b15b6d..00000000 --- a/test/features/controller_inheritance.test.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { Container, injectable } from 'inversify'; -import supertest from 'supertest'; -import { json, urlencoded } from 'express'; -import { InversifyExpressServer } from '../../src/server'; -import { controller, httpGet, requestParam, httpDelete, httpPost, httpPut, requestBody, httpOptions, } from '../../src/decorators'; -import { cleanUpMetadata } from '../../src/utils'; - -type ResponseBody = { args: string, status: number }; - -function getDemoServer() { - interface Movie { - name: string; - } - - const container = new Container(); - - @injectable() - class GenericController { - @httpGet('/') - public get() { - return { status: 'BASE GET!' }; - } - - @httpGet('/:id') - public getById( - @requestParam('id') id: string, - ) { - return { status: `BASE GET BY ID! ${id}` }; - } - - @httpPost('/') - public post( - @requestBody() body: T, - ) { - return { - args: body, - status: 'BASE POST!' - }; - } - - @httpPut('/:id') - public put( - @requestBody() body: T, - @requestParam('id') id: string, - ) { - return { - args: body, - status: `BASE PUT! ${id}` - }; - } - - @httpDelete('/:id') - public delete( - @requestParam('id') id: string, - ) { - return { status: `BASE DELETE! ${id}` }; - } - - @httpOptions('/:id') - public options( - @requestParam('id') id: string - ) { - return { status: `BASE OPTIONS! ${id}` }; - } - - } - - @controller('/api/v1/movies') - class MoviesController extends GenericController { - @httpDelete('/:movieId/actors/:actorId') - public deleteActor( - @requestParam('movieId') movieId: string, - @requestParam('actorId') actorId: string, - ) { - return { - status: `DERIVED DELETE ACTOR! MOVIECONTROLLER1 ${movieId} ${actorId}` - }; - } - } - - @controller('/api/v1/movies2') - class MoviesController2 extends GenericController { - @httpDelete('/:movieId2/actors/:actorId2') - public deleteActor( - @requestParam('movieId2') movieId: string, - @requestParam('actorId2') actorId: string, - ) { - return { - status: `DERIVED DELETE ACTOR! MOVIECONTROLLER2 ${movieId} ${actorId}` - }; - } - } - - @controller('/api/v1/movies3') - class MoviesController3 extends GenericController { - @httpDelete('/:movieId3/actors/:actorId3') - public deleteActor( - @requestParam('movieId3') movieId: string, - @requestParam('actorId3') actorId: string, - ) { - return { - status: `DERIVED DELETE ACTOR! MOVIECONTROLLER3 ${movieId} ${actorId}` - }; - } - } - - const app = new InversifyExpressServer(container); - - app.setConfig(a => { - a.use(json()); - a.use(urlencoded({ extended: true })); - }); - - const server = app.build(); - - return server; -} - -describe('Derived controller', () => { - beforeEach(done => { - cleanUpMetadata(); - done(); - }); - - it('Can access methods decorated with @httpGet from parent', done => { - const server = getDemoServer(); - - void supertest(server).get('/api/v1/movies') - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status).toEqual('BASE GET!'); - done(); - }); - }); - - it('Can access methods decorated with @httpGet from parent', done => { - const server = getDemoServer(); - const id = 5; - - void supertest(server).get(`/api/v1/movies/${id}`) - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status).toEqual(`BASE GET BY ID! ${id}`); - done(); - }); - }); - - it('Can access methods decorated with @httpPost from parent', done => { - const server = getDemoServer(); - const movie = { name: 'The Shining' }; - const status = 'BASE POST!'; - - void supertest(server).post('/api/v1/movies') - .send(movie) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json') - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status).toEqual(status); - expect(r.args).toEqual(movie); - done(); - }); - }); - - it('Can access methods decorated with @httpPut from parent', done => { - const server = getDemoServer(); - const id = 5; - const movie = { name: 'The Shining' }; - - void supertest(server).put(`/api/v1/movies/${id}`) - .send(movie) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json') - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status).toEqual(`BASE PUT! ${id}`); - expect(r.args).toEqual(movie); - done(); - }); - }); - - it('Can access methods decorated with @httpDelete from parent', done => { - const server = getDemoServer(); - const id = 5; - - void supertest(server).delete(`/api/v1/movies/${id}`) - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status).toEqual(`BASE DELETE! ${id}`); - done(); - }); - }); - - it('Can access methods decorated with @httpOptions from parent', (done) => { - - const server = getDemoServer(); - const id = 5; - - void supertest(server).options(`/api/v1/movies/${id}`) - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status).toEqual(`BASE OPTIONS! ${id}`); - done(); - }); - - }); - - it('Derived controller can have its own methods', done => { - const server = getDemoServer(); - const movieId = 5; - const actorId = 3; - - void supertest(server).delete(`/api/v1/movies/${movieId}/actors/${actorId}`) - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status) - .toEqual(`DERIVED DELETE ACTOR! MOVIECONTROLLER1 ${movieId} ${actorId}`); - done(); - }); - }); - - it('Derived controller 2 can have its own methods', done => { - const server = getDemoServer(); - const movieId = 5; - const actorId = 3; - - void supertest(server) - .delete(`/api/v1/movies2/${movieId}/actors/${actorId}`) - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status) - .toEqual(`DERIVED DELETE ACTOR! MOVIECONTROLLER2 ${movieId} ${actorId}`); - done(); - }); - }); - - it('Derived controller 3 can have its own methods', done => { - const server = getDemoServer(); - const movieId = 5; - const actorId = 3; - - void supertest(server) - .delete(`/api/v1/movies3/${movieId}/actors/${actorId}`) - .expect(200) - .then(res => { - const r = res.body as ResponseBody; - expect(r.status) - .toEqual(`DERIVED DELETE ACTOR! MOVIECONTROLLER3 ${movieId} ${actorId}`); - done(); - }); - }); -}); diff --git a/test/features/decorator_middleware.test.ts b/test/features/decorator_middleware.test.ts deleted file mode 100644 index d0121f7b..00000000 --- a/test/features/decorator_middleware.test.ts +++ /dev/null @@ -1,296 +0,0 @@ -import * as express from 'express'; -import supertest from 'supertest'; -import { Container } from 'inversify'; -import { METADATA_KEY } from '../../src/constants'; -import { BaseMiddleware, ControllerMethodMetadata, InversifyExpressServer, ControllerMetadata } from '../../src/index'; -import { controller, httpGet, httpMethod, httpPut, withMiddleware } from '../../src/decorators'; -import { cleanUpMetadata } from '../../src/utils'; -import assert from 'assert'; - -function cleanUpMidDecTestControllerMetadata() { - class MidDecTestController { } - Reflect.defineMetadata( - METADATA_KEY.middleware, - {}, - MidDecTestController.constructor - ); -} - -describe('Unit Test: @middleware decorator', () => { - beforeEach(done => { - cleanUpMetadata(); - cleanUpMidDecTestControllerMetadata(); - done(); - }); - - it('should add method metadata to a class when a handler is decorated with @withMiddleware', done => { - const functionMiddleware = () => { - // do nothing - }; - const identifierMiddleware = Symbol.for('foo'); - const path = 'foo'; - const method = 'get'; - - class MidDecTestController { - @httpMethod(method, path) - @withMiddleware(functionMiddleware) - public test() { - // do nothing - } - - @httpMethod(method, path) - @withMiddleware(functionMiddleware, identifierMiddleware) - public test2() { - // do nothing - } - } - - const methodMetadata = - Reflect.getMetadata( - METADATA_KEY.controllerMethod, - MidDecTestController, - ) as ControllerMethodMetadata[]; - - const [testMetaData, test2MetaData] = methodMetadata; - assert.strictEqual(testMetaData?.middleware.length, 1); - assert.strictEqual(test2MetaData?.middleware.length, 2); - assert.deepStrictEqual(testMetaData?.middleware, [functionMiddleware]); - assert.deepStrictEqual( - test2MetaData?.middleware, - [functionMiddleware, identifierMiddleware] - ); - done(); - }); - - it('should add class metadata to a controller class when decorated with @withMiddleware', done => { - const identifierMiddleware = Symbol.for('foo'); - const functionMiddleware = () => { - // do nothing - }; - - @controller('/foo') - @withMiddleware(identifierMiddleware, functionMiddleware) - class MidDecTestController { } - - const controllerMetaData: ControllerMetadata = - Reflect.getMetadata( - METADATA_KEY.controller, - MidDecTestController, - ) as ControllerMetadata; - - assert.strictEqual(controllerMetaData.middleware.length, 2); - assert.deepStrictEqual( - controllerMetaData.middleware, - [identifierMiddleware, functionMiddleware] - ); - done(); - }); - - it('should be able to add middleware from multiple decorations', done => { - const identifierMiddleware = Symbol.for('foo'); - const functionMiddleware = () => { - // do nothing - }; - - const first = withMiddleware(identifierMiddleware); - const second = withMiddleware(functionMiddleware); - - @controller('/foo') - @first - @second - class MidDecTestController { } - - const controllerMetaData: ControllerMetadata = - Reflect.getMetadata( - METADATA_KEY.controller, - MidDecTestController, - ) as ControllerMetadata; - - assert.strictEqual(controllerMetaData.middleware.length, 2); - assert.deepStrictEqual( - controllerMetaData.middleware, - [functionMiddleware, identifierMiddleware] - ); - done(); - }); - - it('should process all requests when decorating a controller', done => { - const addTestHeader = withMiddleware(( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - res.set('test-header', 'foo'); - next(); - }, - ); - - @controller('/foo') - @addTestHeader - class MidDecTestController { - @httpGet('/bar') - public get() { - return { data: 'hello' }; - } - - @httpPut('/baz') - public put() { - return { data: 'there' }; - } - } - - const container = new Container(); - container.bind('MidDecTestController') - .to(MidDecTestController); - const server = new InversifyExpressServer(container); - - const app = server.build(); - void supertest(app) - .get('/foo/bar') - .then((res: { header: Record }) => { - assert.strictEqual(res.header['test-header'], 'foo'); - }); - - void supertest(app) - .put('/foo/baz') - .then((res: { header: Record }) => { - assert.strictEqual(res.header['test-header'], 'foo'); - done(); - }); - }); - it('should process only specific requests when decorating a handler', done => { - const addTestHeader = withMiddleware(( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - res.set('test-header', 'foo'); - next(); - }, - ); - - @controller('/foo') - class MidDecTestController { - @httpGet('/bar') - public get() { - return { data: 'hello' }; - } - - @httpPut('/baz') - @addTestHeader - public put() { - return { data: 'there' }; - } - } - - const container = new Container(); - container.bind('MidDecTestController') - .to(MidDecTestController); - const server = new InversifyExpressServer(container); - - const app = server.build(); - void supertest(app) - .get('/foo/bar') - .then((res: { header: Record }) => { - assert.strictEqual(res.header['test-header'], undefined); - }); - - void supertest(app) - .put('/foo/baz') - .then((res: { header: Record }) => { - assert.strictEqual(res.header['test-header'], 'foo'); - done(); - }); - }); - it('should process requests with both controller- and handler middleware', done => { - const addHandlerHeader = withMiddleware(( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - res.set('test-handler', 'hello there!'); - next(); - }, - ); - const addControllerHeader = withMiddleware(( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - res.set('test-controller', 'general kenobi'); - next(); - }, - ); - - @controller('/foo') - @addControllerHeader - class MidDecTestController { - @httpGet('/bar') - public get() { - return { data: 'hello' }; - } - - @httpPut('/baz') - @addHandlerHeader - public put() { - return { data: 'there' }; - } - } - - const container = new Container(); - container.bind('MidDecTestController') - .to(MidDecTestController); - const server = new InversifyExpressServer(container); - - const app = server.build(); - void supertest(app) - .get('/foo/bar') - .end((req, res: { header: Record }) => { - assert.strictEqual(res.header['test-controller'], 'general kenobi'); - assert.strictEqual(res.header['test-handler'], undefined); - }); - - void supertest(app) - .put('/foo/baz') - .end((req, res: { header: Record }) => { - assert.strictEqual(res.header['test-controller'], 'general kenobi'); - assert.strictEqual(res.header['test-handler'], 'hello there!'); - done(); - }); - }); - it('should be able to inject BaseMiddleware services by identifier', done => { - const container = new Container(); - class MidDecTestMiddleware extends BaseMiddleware { - public handler( - req: express.Request, - res: express.Response, - next: express.NextFunction, - ) { - res.set('test-base-middleware', 'working'); - next(); - } - } - container.bind('TestMiddleware') - .to(MidDecTestMiddleware); - - @controller('/foo') - @withMiddleware('TestMiddleware') - class MidDecTestController { - @httpGet('/bar') - public get() { - return { data: 'hello' }; - } - } - container.bind('MidDecTestController') - .to(MidDecTestController); - - const server = new InversifyExpressServer(container); - const app = server.build(); - void supertest(app) - .get('/foo/bar') - .end((req, res: { header: Record }) => { - assert.strictEqual(res.header['test-base-middleware'], 'working'); - done(); - }); - }); -}); diff --git a/test/framework.test.ts b/test/framework.test.ts deleted file mode 100644 index 498592b4..00000000 --- a/test/framework.test.ts +++ /dev/null @@ -1,138 +0,0 @@ -import express, { Application, NextFunction, Request, Response, Router } from 'express'; -import { Container } from 'inversify'; -import { InversifyExpressServer } from '../src/server'; -import { controller } from '../src/decorators'; -import { cleanUpMetadata } from '../src/utils'; -import { RoutingConfig } from '../src/interfaces'; -import { HttpResponseMessage } from '../src/httpResponseMessage'; - -interface ServerWithTypes { - _app: Application; - _router: Router; - _routingConfig: RoutingConfig; - handleHttpResponseMessage: ( - message: HttpResponseMessage, - res: Response - ) => void; -} - -describe('Unit Test: InversifyExpressServer', () => { - beforeEach(done => { - cleanUpMetadata(); - done(); - }); - - it('should call the configFn before the errorConfigFn', done => { - const middleware = ( - req: Request, - res: Response, - next: NextFunction, - ) => { - // - }; - - const configFn = jest.fn((app: Application) => { - app.use(middleware); - }); - - const errorConfigFn = jest.fn((app: Application) => { - app.use(middleware); - }); - - const container = new Container(); - - @controller('/') - class TestController { } - - const server = new InversifyExpressServer(container); - - server.setConfig(configFn) - .setErrorConfig(errorConfigFn); - - expect(configFn).not.toBeCalled(); - expect(errorConfigFn).not.toBeCalled(); - - server.build(); - - expect(configFn).toHaveBeenCalledTimes(1); - expect(errorConfigFn).toHaveBeenCalledTimes(1); - done(); - }); - - it('Should allow to pass a custom Router instance as config', () => { - const container = new Container(); - - const customRouter = Router({ - caseSensitive: false, - mergeParams: false, - strict: false, - }); - - const serverWithDefaultRouter = new InversifyExpressServer(container); - const serverWithCustomRouter = new InversifyExpressServer( - container, - customRouter - ); - - expect((serverWithDefaultRouter as unknown as ServerWithTypes) - ._router === customRouter).toBe(false); - expect((serverWithCustomRouter as unknown as ServerWithTypes) - ._router === customRouter).toBe(true); - }); - - it('Should allow to provide custom routing configuration', () => { - const container = new Container(); - - const routingConfig = { - rootPath: '/such/root/path', - }; - - const serverWithDefaultConfig = new InversifyExpressServer(container); - const serverWithCustomConfig = new InversifyExpressServer( - container, - null, - routingConfig - ); - - expect((serverWithCustomConfig as unknown as ServerWithTypes) - ._routingConfig).toBe(routingConfig); - - expect((serverWithDefaultConfig as unknown as ServerWithTypes) - ._routingConfig).not.toEqual( - (serverWithCustomConfig as unknown as ServerWithTypes)._routingConfig, - ); - }); - - it('Should allow to provide a custom express application', () => { - const container = new Container(); - const app = express(); - const serverWithDefaultApp = new InversifyExpressServer(container); - const serverWithCustomApp = new InversifyExpressServer( - container, - null, - null, - app - ); - - expect((serverWithCustomApp as unknown as ServerWithTypes)._app).toBe(app); - expect((serverWithDefaultApp as unknown as ServerWithTypes)._app).not - .toEqual((serverWithCustomApp as unknown as ServerWithTypes)._app); - }); - - it('Should handle a HttpResponseMessage that has no content', () => { - const container = new Container(); - const server = new InversifyExpressServer(container); - - const httpResponseMessageWithoutContent = new HttpResponseMessage(404); - const mockResponse: Partial = { - sendStatus: jest.fn(), - }; - - (server as unknown as ServerWithTypes).handleHttpResponseMessage( - httpResponseMessageWithoutContent, - mockResponse as unknown as Response, - ); - - expect(mockResponse.sendStatus).toHaveBeenCalledWith(404); - }); -}); diff --git a/test/http_context.test.ts b/test/http_context.test.ts deleted file mode 100644 index c23ad44e..00000000 --- a/test/http_context.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Container, inject } from 'inversify'; -import supertest from 'supertest'; -import { InversifyExpressServer, controller, httpGet, injectHttpContext, HttpContext } from '../src/index'; -import { cleanUpMetadata } from '../src/utils'; - -describe('HttpContex', () => { - beforeEach(done => { - cleanUpMetadata(); - done(); - }); - - it('Should be able to httpContext manually with the @injectHttpContext decorator', done => { - interface SomeDependency { - name: string; - } - - @controller('/') - class TestController { - @injectHttpContext private readonly _httpContext!: HttpContext; - @inject('SomeDependency') - private readonly _someDependency!: SomeDependency; - - @httpGet('/') - public async getTest() { - const headerVal = this._httpContext.request.headers['x-custom']; - const { name } = this._someDependency; - const isAuthenticated = await this._httpContext.user.isAuthenticated(); - expect(isAuthenticated).toBe(false); - return `${headerVal as string} & ${name}`; - } - } - - const container = new Container(); - - container.bind('SomeDependency') - .toConstantValue({ name: 'SomeDependency!' }); - - const server = new InversifyExpressServer(container); - - void supertest(server.build()) - .get('/') - .set('x-custom', 'test-header!') - .expect(200, 'test-header! & SomeDependency!', done); - }); -}); diff --git a/test/issue_590.test.ts b/test/issue_590.test.ts deleted file mode 100644 index afe2050f..00000000 --- a/test/issue_590.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Container } from 'inversify'; -import { Application } from 'express'; -import { InversifyExpressServer, cleanUpMetadata } from '../src/index'; -import { NO_CONTROLLERS_FOUND } from '../src/constants'; - -describe('Issue 590', () => { - beforeEach(() => { - cleanUpMetadata(); - }); - - it('should throw if no bindings for controllers are declared', () => { - const container = new Container(); - const server = new InversifyExpressServer(container); - const throws = (): Application => server.build(); - expect(throws).toThrowError(NO_CONTROLLERS_FOUND); - }); - - it('should not throw if forceControllers is false and no bindings for controllers are declared', () => { - const container = new Container(); - const server = new InversifyExpressServer( - container, - null, - null, - null, - null, - false - ); - const throws = (): Application => server.build(); - expect(throws).not.toThrowError(); - }); -}); diff --git a/test/server.test.ts b/test/server.test.ts deleted file mode 100644 index 5225f8dd..00000000 --- a/test/server.test.ts +++ /dev/null @@ -1,812 +0,0 @@ -import supertest from "supertest"; -import { interfaces } from "inversify"; -import { - Request, - Response, - Router, - NextFunction, - RequestHandler, - json, - CookieOptions, -} from "express"; -import cookieParser from "cookie-parser"; -import { injectable, Container } from "inversify"; -import { AuthProvider, InversifyExpressServer, Principal } from "../src"; -import { - controller, - httpMethod, - all, - httpGet, - httpPost, - httpPut, - httpPatch, - httpHead, - httpDelete, - request, - response, - requestParam, - requestBody, - queryParam, - requestHeaders, - cookies, - next, - principal, -} from "../src/decorators"; -import { cleanUpMetadata } from "../src/utils"; - -describe("Integration Tests:", () => { - let server: InversifyExpressServer; - let container: interfaces.Container; - - beforeEach((done) => { - cleanUpMetadata(); - container = new Container(); - done(); - }); - - describe("Routing & Request Handling:", () => { - it("should work for async controller methods", (done) => { - @controller("/") - class TestController { - @httpGet("/") public getTest(req: Request, res: Response) { - return new Promise((resolve) => { - setTimeout(resolve, 100, "GET"); - }); - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, "GET", done); - }); - - it("should work for async controller methods that fails", (done) => { - @controller("/") - class TestController { - @httpGet("/") public getTest(req: Request, res: Response) { - return new Promise((resolve, reject) => { - setTimeout(reject, 100, "GET"); - }); - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(500, done); - }); - - it("should work for methods which call nextFunc()", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response, nextFunc: NextFunction) { - nextFunc(); - } - - @httpGet("/") public getTest2(req: Request, res: Response) { - return "GET"; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, "GET", done); - }); - - it("should work for async methods which call nextFunc()", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response, nextFunc: NextFunction) { - return new Promise((resolve) => { - setTimeout( - () => { - nextFunc(); - resolve(null); - }, - 100, - "GET" - ); - }); - } - - @httpGet("/") public getTest2(req: Request, res: Response) { - return "GET"; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, "GET", done); - }); - - it("should work for async methods called by nextFunc()", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response, nextFunc: NextFunction) { - return nextFunc; - } - - @httpGet("/") public getTest2(req: Request, res: Response) { - return new Promise((resolve) => { - setTimeout(resolve, 100, "GET"); - }); - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, "GET", done); - }); - - it("should work for each shortcut decorator", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response) { - res.send("GET"); - } - - @httpPost("/") - public postTest(req: Request, res: Response) { - res.send("POST"); - } - - @httpPut("/") - public putTest(req: Request, res: Response) { - res.send("PUT"); - } - - @httpPatch("/") - public patchTest(req: Request, res: Response) { - res.send("PATCH"); - } - - @httpHead("/") - public headTest(req: Request, res: Response) { - res.send("HEAD"); - } - - @httpDelete("/") - public deleteTest(req: Request, res: Response) { - res.send("DELETE"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - const deleteFn = () => { - void agent.delete("/").expect(200, "DELETE", done); - }; - const head = () => { - void agent.head("/").expect(200, "HEAD", deleteFn); - }; - const patch = () => { - void agent.patch("/").expect(200, "PATCH", head); - }; - const put = () => { - void agent.put("/").expect(200, "PUT", patch); - }; - const post = () => { - void agent.post("/").expect(200, "POST", put); - }; - const get = () => { - void agent.get("/").expect(200, "GET", post); - }; - - get(); - }); - - it("should work for more obscure HTTP methods using the httpMethod decorator", (done) => { - @controller("/") - class TestController { - @httpMethod("propfind", "/") - public getTest(req: Request, res: Response) { - res.send("PROPFIND"); - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).propfind("/").expect(200, "PROPFIND", done); - }); - - it("should use returned values as response", (done) => { - const result = { hello: "world" }; - - @controller("/") - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response) { - return result; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, JSON.stringify(result), done); - }); - - it("should use custom router passed from configuration", () => { - @controller("/CaseSensitive") - class TestController { - @httpGet("/Endpoint") public get() { - return "Such Text"; - } - } - - const customRouter = Router({ - caseSensitive: true, - }); - - server = new InversifyExpressServer(container, customRouter); - const app = server.build(); - - const expectedSuccess = supertest(app) - .get("/CaseSensitive/Endpoint") - .expect(200, "Such Text"); - - const expectedNotFound1 = supertest(app).get("/casesensitive/endpoint").expect(404); - - const expectedNotFound2 = supertest(app).get("/CaseSensitive/endpoint").expect(404); - - return Promise.all([expectedSuccess, expectedNotFound1, expectedNotFound2]); - }); - - it("should use custom routing configuration", () => { - @controller("/ping") - class TestController { - @httpGet("/endpoint") public get() { - return "pong"; - } - } - - server = new InversifyExpressServer(container, null, { rootPath: "/api/v1" }); - - return supertest(server.build()).get("/api/v1/ping/endpoint").expect(200, "pong"); - }); - - it("should work for controller methods who's return value is falsey", (done) => { - @controller("/user") - class TestController { - @httpDelete("/") public async delete(): Promise { - // - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()) - .delete("/user") - .timeout({ response: 1000, deadline: 2000 }) - .end((err, res) => { - if (err) { - if (err.timeout) { - // The request timed out as expected because no response was sent - done(); - } else { - // Some other error occurred - done(err); - } - } else { - // If we get here, the request did not hang, and a response was received - done(new Error("Expected request to hang, but a response was received")); - } - }); - }); - }); - - describe("Middleware:", () => { - let result: string; - type Middleware = { - a: (req: Request, res: Response, nextFunc: NextFunction) => void; - b: (req: Request, res: Response, nextFunc: NextFunction) => void; - c: (req: Request, res: Response, nextFunc: NextFunction) => void; - }; - const middleware: Middleware = { - a(req: Request, res: Response, nextFunc: NextFunction) { - result += "a"; - nextFunc(); - }, - b(req: Request, res: Response, nextFunc: NextFunction) { - result += "b"; - nextFunc(); - }, - c(req: Request, res: Response, nextFunc: NextFunction) { - result += "c"; - nextFunc(); - }, - }; - - const spyA = jest.fn().mockImplementation(middleware.a); - const spyB = jest.fn().mockImplementation(middleware.b); - const spyC = jest.fn().mockImplementation(middleware.c); - - beforeEach((done) => { - spyA.mockClear(); - spyB.mockClear(); - spyC.mockClear(); - result = ""; - done(); - }); - - it("should call method-level middleware correctly (GET)", (done) => { - @controller("/") - class TestController { - @httpGet("/", spyA, spyB, spyC) - public getTest(req: Request, res: Response) { - res.send("GET"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - void agent.get("/").expect(200, "GET", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call method-level middleware correctly (POST)", (done) => { - @controller("/") - class TestController { - @httpPost("/", spyA, spyB, spyC) - public postTest(req: Request, res: Response) { - res.send("POST"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - void agent.post("/").expect(200, "POST", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call method-level middleware correctly (PUT)", (done) => { - @controller("/") - class TestController { - @httpPut("/", spyA, spyB, spyC) - public postTest(req: Request, res: Response) { - res.send("PUT"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - void agent.put("/").expect(200, "PUT", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call method-level middleware correctly (PATCH)", (done) => { - @controller("/") - class TestController { - @httpPatch("/", spyA, spyB, spyC) - public postTest(req: Request, res: Response) { - res.send("PATCH"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - void agent.patch("/").expect(200, "PATCH", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call method-level middleware correctly (HEAD)", (done) => { - @controller("/") - class TestController { - @httpHead("/", spyA, spyB, spyC) - public postTest(req: Request, res: Response) { - res.send("HEAD"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - void agent.head("/").expect(200, "HEAD", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call method-level middleware correctly (DELETE)", (done) => { - @controller("/") - class TestController { - @httpDelete("/", spyA, spyB, spyC) - public postTest(req: Request, res: Response) { - res.send("DELETE"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - void agent.delete("/").expect(200, "DELETE", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call method-level middleware correctly (ALL)", (done) => { - @controller("/") - class TestController { - @all("/", spyA, spyB, spyC) - public postTest(req: Request, res: Response) { - res.send("ALL"); - } - } - - server = new InversifyExpressServer(container); - const agent = supertest(server.build()); - - void agent.get("/").expect(200, "ALL", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call controller-level middleware correctly", (done) => { - @controller("/", spyA, spyB, spyC) - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response) { - res.send("GET"); - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()) - .get("/") - .expect(200, "GET", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call server-level middleware correctly", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response) { - res.send("GET"); - } - } - - server = new InversifyExpressServer(container); - - server.setConfig((app) => { - app.use(spyA); - app.use(spyB); - app.use(spyC); - }); - - void supertest(server.build()) - .get("/") - .expect(200, "GET", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should call all middleware in correct order", (done) => { - @controller("/", spyB) - class TestController { - @httpGet("/", spyC) - public getTest(req: Request, res: Response) { - res.send("GET"); - } - } - - server = new InversifyExpressServer(container); - - server.setConfig((app) => { - app.use(spyA); - }); - - void supertest(server.build()) - .get("/") - .expect(200, "GET", () => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(spyC).toHaveBeenCalledTimes(1); - expect(result).toBe("abc"); - done(); - }); - }); - - it("should resolve controller-level middleware", () => { - const symbolId = Symbol.for("spyA"); - const strId = "spyB"; - - @controller("/", symbolId, strId) - class TestController { - @httpGet("/") - public getTest(req: Request, res: Response) { - res.send("GET"); - } - } - - container.bind(symbolId).toConstantValue(spyA); - container.bind(strId).toConstantValue(spyB); - - server = new InversifyExpressServer(container); - - const agent = supertest(server.build()); - - return agent - .get("/") - .expect(200, "GET") - .then(() => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(result).toBe("ab"); - }); - }); - - it("should resolve method-level middleware", () => { - const symbolId = Symbol.for("spyA"); - const strId = "spyB"; - - @controller("/") - class TestController { - @httpGet("/", symbolId, strId) - public getTest(req: Request, res: Response) { - res.send("GET"); - } - } - - container.bind(symbolId).toConstantValue(spyA); - container.bind(strId).toConstantValue(spyB); - - server = new InversifyExpressServer(container); - - const agent = supertest(server.build()); - - return agent - .get("/") - .expect(200, "GET") - .then(() => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(result).toBe("ab"); - }); - }); - - it("should compose controller- and method-level middleware", () => { - const symbolId = Symbol.for("spyA"); - const strId = "spyB"; - - @controller("/", symbolId) - class TestController { - @httpGet("/", strId) - public getTest(req: Request, res: Response) { - res.send("GET"); - } - } - - container.bind(symbolId).toConstantValue(spyA); - container.bind(strId).toConstantValue(spyB); - - server = new InversifyExpressServer(container); - - const agent = supertest(server.build()); - - return agent - .get("/") - .expect(200, "GET") - .then(() => { - expect(spyA).toHaveBeenCalledTimes(1); - expect(spyB).toHaveBeenCalledTimes(1); - expect(result).toBe("ab"); - }); - }); - }); - - describe("Parameters:", () => { - it("should bind a method parameter to the url parameter of the web request", (done) => { - @controller("/") - class TestController { - @httpGet(":id") - public getTest(@requestParam("id") id: string, req: Request, res: Response) { - return id; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/foo").expect(200, "foo", done); - }); - - it("should bind a method parameter to the request object", (done) => { - @controller("/") - class TestController { - @httpGet(":id") - public getTest(@request() req: Request) { - return req.params["id"]; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/GET").expect(200, "GET", done); - }); - - it("should bind a method parameter to the response object", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(@response() res: Response) { - return res.send("foo"); - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, "foo", done); - }); - - it("should bind a method parameter to a query parameter", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(@queryParam("id") id: string) { - return id; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").query("id=foo").expect(200, "foo", done); - }); - - it("should bind a method parameter to the request body", (done) => { - @controller("/") - class TestController { - @httpPost("/") public getTest(@requestBody() reqBody: string) { - return reqBody; - } - } - - server = new InversifyExpressServer(container); - const body = { foo: "bar" }; - server.setConfig((app) => { - app.use(json()); - }); - void supertest(server.build()).post("/").send(body).expect(200, body, done); - }); - - it("should bind a method parameter to the request headers", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(@requestHeaders("testhead") headers: Record) { - return headers; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").set("TestHead", "foo").expect(200, "foo", done); - }); - - it("should be case insensitive to request headers", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getTest(@requestHeaders("TestHead") headers: Record) { - return headers; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").set("TestHead", "foo").expect(200, "foo", done); - }); - - it("should bind a method parameter to a cookie", (done) => { - @controller("/") - class TestController { - @httpGet("/") public getCookie( - @cookies("Cookie") cookie: CookieOptions, - req: Request, - res: Response - ) { - return cookie; - } - } - - server = new InversifyExpressServer(container); - server.setConfig((app) => { - app.use(cookieParser()); - }); - void supertest(server.build()) - .get("/") - .set("Cookie", "Cookie=hey") - .expect(200, "hey", done); - }); - - it("should bind a method parameter to the next function", (done) => { - @controller("/") - class TestController { - @httpGet("/") public getTest(@next() nextFunc: NextFunction) { - return nextFunc(); - } - - @httpGet("/") public getResult() { - return "foo"; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, "foo", done); - }); - - it("should bind a method parameter to a principal with null (empty) details when no AuthProvider is set.", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getPrincipalTest(@principal() userPrincipal: Principal) { - return userPrincipal.details; - } - } - - server = new InversifyExpressServer(container); - void supertest(server.build()).get("/").expect(200, "", done); - }); - - it("should bind a method parameter to a principal with valid details when an AuthProvider is set.", (done) => { - @controller("/") - class TestController { - @httpGet("/") - public getPrincipalTest(@principal() userPrincipal: Principal) { - return userPrincipal.details; - } - } - - @injectable() - class CustomAuthProvider implements AuthProvider { - public async getUser( - req: Request, - res: Response, - nextFunc: NextFunction - ): Promise { - return Promise.resolve({ - details: "something", - isAuthenticated: () => Promise.resolve(true), - isInRole: () => Promise.resolve(true), - isResourceOwner: () => Promise.resolve(true), - } as Principal); - } - } - - server = new InversifyExpressServer(container, null, null, null, CustomAuthProvider); - void supertest(server.build()).get("/").expect(200, "something", done); - }); - }); -}); diff --git a/test/tsconfig.json b/test/tsconfig.json deleted file mode 100644 index d063107d..00000000 --- a/test/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "compilerOptions": { - "rootDir": ".", - "noUnusedLocals": false, - "strict": false - }, - "extends": "../tsconfig.json", - "include": [ - "./**/*.ts" - ], - "references": [ - { - "path": "../src" - } - ] -} \ No newline at end of file diff --git a/tsconfig.base.cjs.json b/tsconfig.base.cjs.json new file mode 100644 index 00000000..ff8518d7 --- /dev/null +++ b/tsconfig.base.cjs.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "NodeNext", + "moduleResolution": "NodeNext" + } +} diff --git a/tsconfig.base.esm.json b/tsconfig.base.esm.json new file mode 100644 index 00000000..f1de21c4 --- /dev/null +++ b/tsconfig.base.esm.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "ES2022", + "moduleResolution": "Bundler", + "resolveJsonModule": false + } +} diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 00000000..9e90bc6c --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "esModuleInterop": true, + "exactOptionalPropertyTypes": true, + "forceConsistentCasingInFileNames": true, + "lib": ["ES2022"], + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "ES2022" + } +} diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 00000000..86030e81 --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "./tsconfig.base.cjs.json", + "compilerOptions": { + "outDir": "./lib/cjs", + "rootDir": "./src", + "tsBuildInfoFile": "tsconfig.cjs.tsbuildinfo" + }, + "include": ["src"] +} diff --git a/tsconfig.cjs.tsbuildinfo b/tsconfig.cjs.tsbuildinfo new file mode 100644 index 00000000..b5f4594e --- /dev/null +++ b/tsconfig.cjs.tsbuildinfo @@ -0,0 +1 @@ +{"root":["./src/base_http_controller.ts","./src/base_middleware.ts","./src/constants.ts","./src/debug.ts","./src/decorators.ts","./src/httpResponseMessage.ts","./src/index.ts","./src/interfaces.ts","./src/server.ts","./src/utils.ts","./src/content/httpContent.ts","./src/content/jsonContent.ts","./src/content/streamContent.ts","./src/content/stringContent.ts","./src/results/BadRequestErrorMessageResult.ts","./src/results/BadRequestResult.ts","./src/results/ConflictResult.ts","./src/results/CreatedNegotiatedContentResult.ts","./src/results/ExceptionResult.ts","./src/results/InternalServerError.ts","./src/results/JsonResult.ts","./src/results/NotFoundResult.ts","./src/results/OkNegotiatedContentResult.ts","./src/results/OkResult.ts","./src/results/RedirectResult.ts","./src/results/ResponseMessageResult.ts","./src/results/StatusCodeResult.ts","./src/results/StreamResult.ts","./src/results/index.ts","./src/test/action_result.test.ts","./src/test/auth_provider.test.ts","./src/test/base_http_controller.test.ts","./src/test/base_middleware.test.ts","./src/test/constants.test.ts","./src/test/debug.test.ts","./src/test/decorators.test.ts","./src/test/framework.test.ts","./src/test/http_context.test.ts","./src/test/issue_590.test.ts","./src/test/server.test.ts","./src/test/content/jsonContent.test.ts","./src/test/content/streamContent.test.ts","./src/test/features/controller_inheritance.test.ts","./src/test/features/decorator_middleware.test.ts","./src/test/helpers/jest.setup.ts"],"version":"5.6.3"} \ No newline at end of file diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 00000000..f425bcff --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "./tsconfig.base.esm.json", + "compilerOptions": { + "outDir": "./lib/esm", + "rootDir": "./src", + "tsBuildInfoFile": "tsconfig.esm.tsbuildinfo" + }, + "include": ["src"] +} diff --git a/tsconfig.json b/tsconfig.json index d42ce20a..d3d8c589 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,46 +1,4 @@ { - "compilerOptions": { - "allowJs": true, - "allowSyntheticDefaultImports": true, - "allowUnreachableCode": false, - "allowUnusedLabels": false, - "alwaysStrict": true, - "assumeChangesOnlyAffectDirectDependencies": true, - "emitDecoratorMetadata": true, - "esModuleInterop": true, - "exactOptionalPropertyTypes": true, - "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "importsNotUsedAsValues": "remove", - "incremental": true, - "isolatedModules": true, - "module": "commonjs", - "moduleResolution": "node", - "noErrorTruncation": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noPropertyAccessFromIndexSignature": true, - "noUncheckedIndexedAccess": true, - "noUnusedParameters": false, - "pretty": true, - "removeComments": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "sourceMap": false, - "strict": true, - "strictNullChecks": true, - "types": [ - "node", - "jest" - ], - "typeRoots": [ - "node_modules/@types" - ] - }, - "exclude": [ - "node_modules" - ] -} \ No newline at end of file + "$schema": "http://json.schemastore.org/tsconfig", + "extends": "./tsconfig.cjs.json" +}