From 82eaa1f58859ccaf07c19cd2bf57e1f034047a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Pintos=20L=C3=B3pez?= Date: Fri, 24 Jan 2025 01:58:13 +0100 Subject: [PATCH 1/2] chore: update build, lint and formatter --- .eslintrc.json | 78 - .npmignore | 10 +- .publishrc | 13 - .travis.yml | 8 - eslint.config.js | 5 - eslint.config.mjs | 177 + jest.config.json | 2 +- package-lock.json | 7777 +++++++---------- package.json | 50 +- prettier.config.mjs | 11 + renovate.json | 22 + rollup.config.mjs | 71 + scripts/writeCommonJsPackageJson.mjs | 43 + scripts/writeEsmPackageJson.mjs | 43 + src/base_http_controller.ts | 31 +- src/base_middleware.ts | 3 +- src/constants.ts | 37 +- src/content/httpContent.ts | 4 +- src/content/jsonContent.ts | 10 +- src/content/streamContent.ts | 20 +- src/content/stringContent.ts | 8 +- src/debug.ts | 150 +- src/decorators.ts | 141 +- src/httpResponseMessage.ts | 35 +- src/interfaces.ts | 38 +- src/results/BadRequestErrorMessageResult.ts | 12 +- src/results/BadRequestResult.ts | 3 +- src/results/ConflictResult.ts | 3 +- src/results/CreatedNegotiatedContentResult.ts | 18 +- src/results/ExceptionResult.ts | 12 +- src/results/InternalServerError.ts | 5 +- src/results/JsonResult.ts | 17 +- src/results/NotFoundResult.ts | 5 +- src/results/OkNegotiatedContentResult.ts | 12 +- src/results/OkResult.ts | 5 +- src/results/RedirectResult.ts | 13 +- src/results/ResponseMessageResult.ts | 4 +- src/results/StatusCodeResult.ts | 6 +- src/results/StreamResult.ts | 23 +- src/results/index.ts | 8 +- src/server.ts | 834 +- src/test/action_result.test.ts | 175 + {test => src/test}/auth_provider.test.ts | 53 +- src/test/base_http_controller.test.ts | 109 + src/test/base_middleware.test.ts | 283 + src/test/constants.test.ts | 11 + src/test/content/jsonContent.test.ts | 22 + src/test/content/streamContent.test.ts | 51 + {test => src/test}/debug.test.ts | 45 +- {test => src/test}/decorators.test.ts | 95 +- .../features/controller_inheritance.test.ts | 262 + .../features/decorator_middleware.test.ts | 322 + src/test/framework.test.ts | 152 + {test => src/test}/helpers/jest.setup.ts | 0 src/test/http_context.test.ts | 54 + src/test/issue_590.test.ts | 36 + src/test/server.test.ts | 838 ++ src/tsconfig-es.json | 7 - src/tsconfig-es6.json | 7 - src/tsconfig.json | 13 - src/utils.ts | 77 +- test/.eslintrc.js | 8 - test/action_result.test.ts | 140 - test/base_http_controller.test.ts | 96 - test/base_middleware.test.ts | 293 - test/constants.test.ts | 10 - test/content/jsonContent.test.ts | 23 - test/content/streamContent.test.ts | 45 - test/features/controller_inheritance.test.ts | 260 - test/features/decorator_middleware.test.ts | 296 - test/framework.test.ts | 138 - test/http_context.test.ts | 45 - test/issue_590.test.ts | 31 - test/server.test.ts | 812 -- test/tsconfig.json | 16 - tsconfig.base.cjs.json | 8 + tsconfig.base.esm.json | 9 + tsconfig.base.json | 23 + tsconfig.cjs.json | 10 + tsconfig.cjs.tsbuildinfo | 1 + tsconfig.esm.json | 10 + tsconfig.json | 48 +- 82 files changed, 6808 insertions(+), 7893 deletions(-) delete mode 100644 .eslintrc.json delete mode 100644 .publishrc delete mode 100644 .travis.yml delete mode 100644 eslint.config.js create mode 100644 eslint.config.mjs create mode 100644 prettier.config.mjs create mode 100644 renovate.json create mode 100644 rollup.config.mjs create mode 100644 scripts/writeCommonJsPackageJson.mjs create mode 100755 scripts/writeEsmPackageJson.mjs create mode 100644 src/test/action_result.test.ts rename {test => src/test}/auth_provider.test.ts (51%) create mode 100644 src/test/base_http_controller.test.ts create mode 100644 src/test/base_middleware.test.ts create mode 100644 src/test/constants.test.ts create mode 100644 src/test/content/jsonContent.test.ts create mode 100644 src/test/content/streamContent.test.ts rename {test => src/test}/debug.test.ts (68%) rename {test => src/test}/decorators.test.ts (51%) create mode 100644 src/test/features/controller_inheritance.test.ts create mode 100644 src/test/features/decorator_middleware.test.ts create mode 100644 src/test/framework.test.ts rename {test => src/test}/helpers/jest.setup.ts (100%) create mode 100644 src/test/http_context.test.ts create mode 100644 src/test/issue_590.test.ts create mode 100644 src/test/server.test.ts delete mode 100644 src/tsconfig-es.json delete mode 100644 src/tsconfig-es6.json delete mode 100644 src/tsconfig.json delete mode 100644 test/.eslintrc.js delete mode 100644 test/action_result.test.ts delete mode 100644 test/base_http_controller.test.ts delete mode 100644 test/base_middleware.test.ts delete mode 100644 test/constants.test.ts delete mode 100644 test/content/jsonContent.test.ts delete mode 100644 test/content/streamContent.test.ts delete mode 100644 test/features/controller_inheritance.test.ts delete mode 100644 test/features/decorator_middleware.test.ts delete mode 100644 test/framework.test.ts delete mode 100644 test/http_context.test.ts delete mode 100644 test/issue_590.test.ts delete mode 100644 test/server.test.ts delete mode 100644 test/tsconfig.json create mode 100644 tsconfig.base.cjs.json create mode 100644 tsconfig.base.esm.json create mode 100644 tsconfig.base.json create mode 100644 tsconfig.cjs.json create mode 100644 tsconfig.cjs.tsbuildinfo create mode 100644 tsconfig.esm.json 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..fa360839 100644 --- a/package.json +++ b/package.json @@ -11,20 +11,17 @@ "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 +36,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 da7fbab0..01e93e55 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() @@ -17,6 +18,6 @@ export abstract class BaseMiddleware implements BaseMiddleware { public abstract handler( req: Request, res: Response, - next: NextFunction + next: NextFunction, ): void; } 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 1994f31b..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 => { - const mReq = this._container.get(middlewareItem); - mReq.httpContext = this._getHttpContext(req); - 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" +} From 5c20778f7ca0b77bd4c85552fa0f09bbe7500c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Pintos=20L=C3=B3pez?= Date: Fri, 24 Jan 2025 02:00:42 +0100 Subject: [PATCH 2/2] chore: update exports with right ones --- package.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fa360839..e6e43f38 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,14 @@ "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"