From ed221b807756fb59be12f66467e19df73b8b93f6 Mon Sep 17 00:00:00 2001 From: CocoisBuggy Date: Tue, 13 May 2025 11:24:24 +0200 Subject: [PATCH 1/4] upgrade to node 20 I've skipped 19 since it's not an lts. No needed changes needed to bump to 20 Server runs, tests pass, yarn is happy --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index eb9421e0..0d47ee19 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,6 @@ }, "type": "module", "engines": { - "node": ">=18.20.0 <19" + "node": ">=20.19.0 < 21" } -} +} \ No newline at end of file From 43528b72fd2bee8b39927d5f95d2390e272e82bb Mon Sep 17 00:00:00 2001 From: CocoisBuggy Date: Wed, 14 May 2025 09:30:56 +0200 Subject: [PATCH 2/4] Support node v22 This is the current LTS, so we NEED to get here, but upgrading gives us a couple of problems: 1. ts-standard doesn't jive well with modern typescript, and the mystery of import assertions has only deepened with age. 2. I have therefore moved to the non-deprecated versions of these tools (which leaves us with a tasty >2k lint issues) resolves #473 There are now two choices: Disable the failing rules to get rid of the two thousand lint issues, or simply fix them so we can go forward with modern eslint standards. The rules do appear to relate to newer TS practices, rather than noise caused by adding semicolons or changing every instance of a single quote to a double quote. I will make a seperate branch so we can look at the fixes as opposed to just silencing them --- .vscode/settings.json | 16 +- eslint.config.js | 82 ++ package.json | 30 +- src/GradeUtils.ts | 17 +- src/__tests__/bulkImport.test.ts | 2 +- src/db/import/usa/AreaTransformer.ts | 4 - src/db/import/usa/USADay0Seed.ts | 1 - src/db/utils/jobs/AddCountriesJob.ts | 5 +- .../utils/jobs/TreeUpdaters/updateAllAreas.ts | 1 - src/model/MutableAreaDataSource.ts | 5 +- tsconfig.json | 28 +- yarn.lock | 820 +++++++++++++++++- 12 files changed, 919 insertions(+), 92 deletions(-) create mode 100644 eslint.config.js diff --git a/.vscode/settings.json b/.vscode/settings.json index e5e150b7..a4ba4936 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,21 +1,13 @@ { "git.ignoreLimitWarning": true, - "[typescriptreact]": { - "editor.formatOnType": true, - "editor.formatOnSave": true, - "editor.defaultFormatter": "standard.vscode-standard" - }, "[typescript]": { "editor.formatOnSave": true, - "editor.defaultFormatter": "standard.vscode-standard" }, - "standard.enable": true, - "standard.autoFixOnSave": true, - "standard.engine": "ts-standard", - "standard.treatErrorsAsWarnings": true, "javascript.format.enable": false, "javascript.format.semicolons": "remove", "typescript.format.enable": false, - "prettier.enable": false, - "editor.defaultFormatter": "standard.vscode-standard" + "eslint.format.enable": true, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features" + } } \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..cadaeda8 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,82 @@ +// @ts-check + +import tseslint from 'typescript-eslint'; +import love from 'eslint-config-love' + +export default tseslint.config( + { + ignores: ['./hacks', './db-migrations', './build', 'jest.config.cjs'], + }, + { + files: ['**/*.ts'], + }, + tseslint.configs.strictTypeChecked, + tseslint.configs.stylisticTypeChecked, + love, + { + rules: { + 'promise/avoid-new': 'off', + 'dot-notation': 'off', + '@typescript-eslint/dot-notation': "error", + 'prefer-const': 'off', + 'no-console': 'off', + 'max-nested-callbacks': 'off', + 'max-lines': 'off', + 'logical-assignment-operators': 'off', + 'guard-for-in': 'off', + 'eslint-comments/require-description': 'off', + 'eslint-comments/no-unlimited-disable': 'off', + 'complexity': 'off', + 'arrow-body-style': 'off', + '@typescript-eslint/unbound-method': 'off', + '@typescript-eslint/switch-exhaustiveness-check': 'off', + '@typescript-eslint/strict-boolean-expressions': 'off', + '@typescript-eslint/return-await': 'off', + '@typescript-eslint/require-await': 'off', + '@typescript-eslint/promise-function-async': 'off', + '@typescript-eslint/prefer-return-this-type': 'off', + '@typescript-eslint/prefer-promise-reject-errors': 'off', + '@typescript-eslint/prefer-optional-chain': 'off', + '@typescript-eslint/prefer-nullish-coalescing': 'off', + '@typescript-eslint/prefer-destructuring': 'off', + '@typescript-eslint/non-nullable-type-assertion-style': 'off', + '@typescript-eslint/no-wrapper-object-types': 'off', + '@typescript-eslint/no-unsafe-type-assertion': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unnecessary-type-assertion': 'off', + '@typescript-eslint/no-unnecessary-type-arguments': 'off', + '@typescript-eslint/no-unnecessary-condition': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-misused-spread': 'off', + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-magic-numbers': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-empty-object-type': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-duplicate-type-constituents': 'off', + '@typescript-eslint/no-confusing-void-expression': 'off', + '@typescript-eslint/max-params': 'off', + '@typescript-eslint/init-declarations': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/consistent-type-imports': 'off', + '@typescript-eslint/consistent-type-exports': 'off', + '@typescript-eslint/consistent-indexed-object-style': 'off', + '@typescript-eslint/class-methods-use-this': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/await-thenable': 'off', + '@typescript-eslint/array-type': 'off', + }, + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: './tsconfig.json', + }, + }, + } +) diff --git a/package.json b/package.json index 0d47ee19..80674f0d 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,12 @@ "@types/node": "^18.13.0", "@types/supertest": "^2.0.12", "@types/underscore": "^1.11.4", + "@typescript-eslint/eslint-plugin": "^8.32.1", + "@typescript-eslint/parser": "^8.32.1", "cross-env": "^7.0.3", + "eslint": "^9.26.0", + "eslint-config-love": "^119.0.0", + "eslint-plugin-import": "^2.31.0", "husky": "^8.0.1", "jest": "^29.7.0", "jest-extended": "^4.0.2", @@ -21,7 +26,8 @@ "supertest": "^6.3.3", "ts-jest": "^29.2.5", "ts-standard": "^12.0.0", - "typescript": "4.9.5", + "typescript": "^5.8.3", + "typescript-eslint": "^8.32.1", "wait-for-expect": "^3.0.2" }, "dependencies": { @@ -71,13 +77,13 @@ "yup": "^1.1.1" }, "scripts": { - "lint": "yarn ts-standard", - "fix": "yarn ts-standard --fix", + "lint": "yarn eslint", + "fix": "yarn eslint --fix", "test": "cross-env NODE_OPTIONS=\"--experimental-vm-modules\" jest --runInBand", "build": "tsc -p tsconfig.json", "build-release": "tsc -p tsconfig.release.json", "clean": "tsc -b --clean && rm -rf build/*", - "serve": "yarn build && node --experimental-json-modules build/main.js", + "serve": "yarn build && node build/main.js", "serve-dev": "echo \"🚨 LOCAL_DEV_BYPASS_AUTH enabled 🚨\" && LOCAL_DEV_BYPASS_AUTH=true yarn serve", "seed-db": "./seed-db.sh", "add-countries": "yarn build && node build/db/utils/jobs/AddCountriesJob.js", @@ -93,22 +99,8 @@ "maptiles:upload": "./scripts/upload-tiles.sh", "maptiles:full": "yarn build && yarn maptiles:export-db && yarn maptiles:upload" }, - "standard": { - "plugins": [ - "html" - ], - "parser": "babel-eslint" - }, - "ts-standard": { - "ignore": [ - "build", - "hacks", - "**/*.test.ts", - "db-migrations" - ] - }, "type": "module", "engines": { - "node": ">=20.19.0 < 21" + "node": ">=22.14.0 <= 24" } } \ No newline at end of file diff --git a/src/GradeUtils.ts b/src/GradeUtils.ts index ee20ba36..64e121c8 100644 --- a/src/GradeUtils.ts +++ b/src/GradeUtils.ts @@ -129,14 +129,17 @@ export const createGradeObject = (gradeStr: string, disciplines: DisciplineType if (disciplines[curr] === true) { const scaleTxt = context[curr] const scaleApi = getScale(scaleTxt) - if (scaleApi != null && !(scaleApi.getScore(gradeStr) < 0)) { - // only assign valid grade - if (acc == null) { - acc = { - [scaleTxt]: gradeStr + if (scaleApi != null) { + const grade = scaleApi.getScore(gradeStr) + if ((typeof grade === 'number' && grade > 0) || grade[0] > 0 || grade[1] > 0) { + // only assign valid grade + if (acc == null) { + acc = { + [scaleTxt]: gradeStr + } + } else { + acc[scaleTxt] = gradeStr } - } else { - acc[scaleTxt] = gradeStr } } } diff --git a/src/__tests__/bulkImport.test.ts b/src/__tests__/bulkImport.test.ts index be8a54c3..96548c94 100644 --- a/src/__tests__/bulkImport.test.ts +++ b/src/__tests__/bulkImport.test.ts @@ -4,7 +4,7 @@ import express from "express"; import {InMemoryDB} from "../utils/inMemoryDB.js"; import {queryAPI, setUpServer} from "../utils/testUtils.js"; import {muuidToString} from "../utils/helpers.js"; -import exampleImportData from './import-example.json' assert {type: 'json'}; +import exampleImportData from './import-example.json' import {AreaType} from "../db/AreaTypes.js"; import {BulkImportResultType} from "../db/BulkImportTypes.js"; import MutableClimbDataSource from "../model/MutableClimbDataSource.js"; diff --git a/src/db/import/usa/AreaTransformer.ts b/src/db/import/usa/AreaTransformer.ts index 4b3815d5..d68f6d77 100644 --- a/src/db/import/usa/AreaTransformer.ts +++ b/src/db/import/usa/AreaTransformer.ts @@ -1,15 +1,12 @@ import mongoose from 'mongoose' import { geometry, Point } from '@turf/helpers' import isoCountries from 'i18n-iso-countries' -import enJson from 'i18n-iso-countries/langs/en.json' assert { type: 'json' } import { getAreaModel } from '../../AreaSchema.js' import { AreaType } from '../../AreaTypes' import { Tree, AreaNode, createRootNode } from './AreaTree.js' import { MUUID } from 'uuid-mongodb' -isoCountries.registerLocale(enJson) - export const createRoot = async (countryCode: string, shortCode?: string): Promise => { if (!isoCountries.isValid(countryCode)) { throw new Error('ISO code must be alpha 2 or 3') @@ -33,7 +30,6 @@ export const createAreas = async (root: AreaNode, areas: any[], areaModel: mongo const tree = new Tree(root) areas.forEach(record => { const { path }: { path: string } = record - /* eslint-disable-next-line */ const fullPath = `${record.us_state}|${path}` // 'path' doesn't have a parent (a US state) tree.insertMany(fullPath, record) }) diff --git a/src/db/import/usa/USADay0Seed.ts b/src/db/import/usa/USADay0Seed.ts index 6540f86b..38ba9fcd 100644 --- a/src/db/import/usa/USADay0Seed.ts +++ b/src/db/import/usa/USADay0Seed.ts @@ -45,7 +45,6 @@ const main = async (): Promise => { const fAreas = `${contentDir}/${code}-areas.jsonlines` if (fs.existsSync(fRoutes) && fs.existsSync(fAreas)) { - /* eslint-disable-next-line */ return limiter(seedState, rootNode, code, fRoutes, fAreas) } return await Promise.resolve() diff --git a/src/db/utils/jobs/AddCountriesJob.ts b/src/db/utils/jobs/AddCountriesJob.ts index 0234c307..65d5d608 100644 --- a/src/db/utils/jobs/AddCountriesJob.ts +++ b/src/db/utils/jobs/AddCountriesJob.ts @@ -1,8 +1,7 @@ -import enJson from 'i18n-iso-countries/langs/en.json' assert { type: 'json' } - import { connectDB, gracefulExit } from '../../index.js' import MutableAreaDataSource from '../../../model/MutableAreaDataSource.js' import { logger } from '../../../logger.js' +import countries from 'i18n-iso-countries' const onConnected = async (): Promise => { logger.info('Adding all countries (except USA)') @@ -14,7 +13,7 @@ const onConnected = async (): Promise => { const insertAllCountries = async (): Promise => { const areaDS = MutableAreaDataSource.getInstance() await Promise.all( - Object.keys(enJson.countries).map(async code => { + Object.keys(countries).map(async code => { if (code === 'US') return null return await areaDS.addCountry(code) }) diff --git a/src/db/utils/jobs/TreeUpdaters/updateAllAreas.ts b/src/db/utils/jobs/TreeUpdaters/updateAllAreas.ts index e7ff4201..921f32d4 100644 --- a/src/db/utils/jobs/TreeUpdaters/updateAllAreas.ts +++ b/src/db/utils/jobs/TreeUpdaters/updateAllAreas.ts @@ -78,7 +78,6 @@ async function postOrderVisit (node: AreaMongoType): Promise { const results = await Promise.all( nodeWithSubAreas.children.map(async entry => { const area: any = entry - /* eslint-disable-next-line */ return limiter(postOrderVisit, (area as AreaMongoType)) } )) diff --git a/src/model/MutableAreaDataSource.ts b/src/model/MutableAreaDataSource.ts index 0ba2dec2..6c9c7947 100644 --- a/src/model/MutableAreaDataSource.ts +++ b/src/model/MutableAreaDataSource.ts @@ -3,14 +3,12 @@ import { geometry, Point } from '@turf/helpers' import { GraphQLError } from 'graphql' import { ApolloServerErrorCode } from '@apollo/server/errors' import isoCountries from 'i18n-iso-countries' -import enJson from 'i18n-iso-countries/langs/en.json' assert {type: 'json'} import { produce } from 'immer' import mongoose, { ClientSession } from 'mongoose' import { NIL, v5 as uuidv5 } from 'uuid' import muuid, { MUUID } from 'uuid-mongodb' import { GradeContexts } from '../GradeUtils.js' -import CountriesLngLat from '../data/countries-with-lnglat.json' assert {type: 'json'} import { AreaDocumnent, AreaEditableFieldsType, @@ -31,8 +29,9 @@ import AreaDataSource from './AreaDataSource.js' import ChangeLogDataSource from './ChangeLogDataSource.js' import { withTransaction } from '../utils/helpers.js' import { getAreaModel } from '../db/AreaSchema.js' +import fs from 'fs' -isoCountries.registerLocale(enJson) +const CountriesLngLat = JSON.parse(fs.readFileSync('./src/data/countries-with-lnglat.json').toString()) export interface AddAreaOptions { user: MUUID diff --git a/tsconfig.json b/tsconfig.json index 3b503295..7d5a2a7a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,23 +1,33 @@ { "compilerOptions": { + "rootDirs": [ + "src" + ], + "outDir": "build", + "lib": [ + "es2022" + ], + "target": "es2022", + "module": "esnext", + "moduleResolution": "node", "types": [ "node", - "jest", + "jest" ], "allowJs": true, "skipLibCheck": true, - "target": "ESNext", - "module": "ESNext", - "esModuleInterop": true, - "moduleResolution": "Node", - "outDir": "build", - "sourceMap": true, "strictNullChecks": true, + "resolveJsonModule": true, + "esModuleInterop": true, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true }, "include": [ "src/**/*.ts", + "eslint.config.js" + ], + "exclude": [ + "hacks", + "db-migrations" ] -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c19a69ad..280953e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -438,6 +438,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.5.0", "@eslint-community/eslint-utils@^4.7.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a" + integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw== + dependencies: + eslint-visitor-keys "^3.4.3" + "@eslint-community/eslint-utils@^4.2.0": version "4.4.1" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" @@ -445,11 +452,32 @@ dependencies: eslint-visitor-keys "^3.4.3" -"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.11.0", "@eslint-community/regexpp@^4.12.1", "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== +"@eslint/config-array@^0.20.0": + version "0.20.0" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.20.0.tgz#7a1232e82376712d3340012a2f561a2764d1988f" + integrity sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ== + dependencies: + "@eslint/object-schema" "^2.1.6" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/config-helpers@^0.2.1": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.2.2.tgz#3779f76b894de3a8ec4763b79660e6d54d5b1010" + integrity sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg== + +"@eslint/core@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.13.0.tgz#bf02f209846d3bf996f9e8009db62df2739b458c" + integrity sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw== + dependencies: + "@types/json-schema" "^7.0.15" + "@eslint/eslintrc@^2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" @@ -465,11 +493,44 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.1.tgz#e55f7f1dd400600dd066dbba349c4c0bac916964" + integrity sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + "@eslint/js@8.57.1": version "8.57.1" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@eslint/js@9.26.0": + version "9.26.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.26.0.tgz#1e13126b67a3db15111d2dcc61f69a2acff70bd5" + integrity sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ== + +"@eslint/object-schema@^2.1.6": + version "2.1.6" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f" + integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== + +"@eslint/plugin-kit@^0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz#47488d8f8171b5d4613e833313f3ce708e3525f8" + integrity sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA== + dependencies: + "@eslint/core" "^0.13.0" + levn "^0.4.1" + "@google-cloud/paginator@^3.0.7": version "3.0.7" resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-3.0.7.tgz#fb6f8e24ec841f99defaebf62c75c2e744dd419b" @@ -590,6 +651,19 @@ resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + dependencies: + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.3.0" + "@humanwhocodes/config-array@^0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" @@ -609,6 +683,16 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@humanwhocodes/retry@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + +"@humanwhocodes/retry@^0.4.2": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba" + integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -861,6 +945,22 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@modelcontextprotocol/sdk@^1.8.0": + version "1.11.2" + resolved "https://registry.yarnpkg.com/@modelcontextprotocol/sdk/-/sdk-1.11.2.tgz#d81784c140d1a9cc937f61af9f071d8b78befe30" + integrity sha512-H9vwztj5OAqHg9GockCQC06k1natgcxWQSRpQcPJf6i5+MWBzfKkRtxGbjQf0X2ihii0ffLZCRGbYV2f2bjNCQ== + dependencies: + content-type "^1.0.5" + cors "^2.8.5" + cross-spawn "^7.0.3" + eventsource "^3.0.2" + express "^5.0.1" + express-rate-limit "^7.5.0" + pkce-challenge "^5.0.0" + raw-body "^3.0.0" + zod "^3.23.8" + zod-to-json-schema "^3.24.1" + "@mongodb-js/saslprep@^1.1.0", "@mongodb-js/saslprep@^1.1.9": version "1.1.9" resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz#e974bab8eca9faa88677d4ea4da8d09a52069004" @@ -1111,6 +1211,11 @@ resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.5.tgz#14a3e83fa641beb169a2dd8422d91c3c345a9a78" integrity sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q== +"@types/estree@^1.0.6": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8" + integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== + "@types/express-serve-static-core@^4.17.30", "@types/express-serve-static-core@^4.17.33": version "4.19.6" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" @@ -1170,7 +1275,7 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -1337,6 +1442,21 @@ resolved "https://registry.yarnpkg.com/@types/yup/-/yup-0.29.13.tgz#21b137ba60841307a3c8a1050d3bf4e63ad561e9" integrity sha512-qRyuv+P/1t1JK1rA+elmK1MmCL1BapEzKKfbEhDBV/LMMse4lmhZ/XbgETI39JveDJRpLjmToOI6uFtMW/WR2g== +"@typescript-eslint/eslint-plugin@8.32.1", "@typescript-eslint/eslint-plugin@^8.32.1": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz#9185b3eaa3b083d8318910e12d56c68b3c4f45b4" + integrity sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.32.1" + "@typescript-eslint/type-utils" "8.32.1" + "@typescript-eslint/utils" "8.32.1" + "@typescript-eslint/visitor-keys" "8.32.1" + graphemer "^1.4.0" + ignore "^7.0.0" + natural-compare "^1.4.0" + ts-api-utils "^2.1.0" + "@typescript-eslint/eslint-plugin@^5.0.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" @@ -1353,6 +1473,17 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/parser@8.32.1", "@typescript-eslint/parser@^8.32.1": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.32.1.tgz#18b0e53315e0bc22b2619d398ae49a968370935e" + integrity sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg== + dependencies: + "@typescript-eslint/scope-manager" "8.32.1" + "@typescript-eslint/types" "8.32.1" + "@typescript-eslint/typescript-estree" "8.32.1" + "@typescript-eslint/visitor-keys" "8.32.1" + debug "^4.3.4" + "@typescript-eslint/parser@^5.0.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" @@ -1371,6 +1502,14 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" +"@typescript-eslint/scope-manager@8.32.1": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz#9a6bf5fb2c5380e14fe9d38ccac6e4bbe17e8afc" + integrity sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA== + dependencies: + "@typescript-eslint/types" "8.32.1" + "@typescript-eslint/visitor-keys" "8.32.1" + "@typescript-eslint/type-utils@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" @@ -1381,11 +1520,26 @@ debug "^4.3.4" tsutils "^3.21.0" +"@typescript-eslint/type-utils@8.32.1": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz#b9292a45f69ecdb7db74d1696e57d1a89514d21e" + integrity sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA== + dependencies: + "@typescript-eslint/typescript-estree" "8.32.1" + "@typescript-eslint/utils" "8.32.1" + debug "^4.3.4" + ts-api-utils "^2.1.0" + "@typescript-eslint/types@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== +"@typescript-eslint/types@8.32.1": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.32.1.tgz#b19fe4ac0dc08317bae0ce9ec1168123576c1d4b" + integrity sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg== + "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" @@ -1399,6 +1553,20 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@8.32.1": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz#9023720ca4ecf4f59c275a05b5fed69b1276face" + integrity sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg== + dependencies: + "@typescript-eslint/types" "8.32.1" + "@typescript-eslint/visitor-keys" "8.32.1" + 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 "^2.1.0" + "@typescript-eslint/utils@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" @@ -1413,6 +1581,16 @@ eslint-scope "^5.1.1" semver "^7.3.7" +"@typescript-eslint/utils@8.32.1", "@typescript-eslint/utils@^8.26.0": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.32.1.tgz#4d6d5d29b9e519e9a85e9a74e9f7bdb58abe9704" + integrity sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA== + dependencies: + "@eslint-community/eslint-utils" "^4.7.0" + "@typescript-eslint/scope-manager" "8.32.1" + "@typescript-eslint/types" "8.32.1" + "@typescript-eslint/typescript-estree" "8.32.1" + "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" @@ -1421,6 +1599,14 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@8.32.1": + version "8.32.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz#4321395cc55c2eb46036cbbb03e101994d11ddca" + integrity sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w== + dependencies: + "@typescript-eslint/types" "8.32.1" + eslint-visitor-keys "^4.2.0" + "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" @@ -1433,6 +1619,14 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +accepts@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895" + integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng== + dependencies: + mime-types "^3.0.0" + negotiator "^1.0.0" + accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -1446,6 +1640,11 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn@^8.14.0: + version "8.14.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" + integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== + acorn@^8.9.0: version "8.14.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" @@ -1856,6 +2055,21 @@ body-parser@1.20.3, body-parser@^1.20.2: type-is "~1.6.18" unpipe "1.0.0" +body-parser@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.0.tgz#f7a9656de305249a715b549b7b8fd1ab9dfddcfa" + integrity sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg== + dependencies: + bytes "^3.1.2" + content-type "^1.0.5" + debug "^4.4.0" + http-errors "^2.0.0" + iconv-lite "^0.6.3" + on-finished "^2.4.1" + qs "^6.14.0" + raw-body "^3.0.0" + type-is "^2.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1942,11 +2156,19 @@ builtins@^5.0.1: dependencies: semver "^7.0.0" -bytes@3.1.2: +bytes@3.1.2, bytes@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" @@ -1958,6 +2180,14 @@ call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: get-intrinsic "^1.2.4" set-function-length "^1.2.1" +call-bound@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2147,7 +2377,14 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4, content-type@~1.0.5: +content-disposition@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.0.0.tgz#844426cb398f934caefcbb172200126bc7ceace2" + integrity sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg== + dependencies: + safe-buffer "5.2.1" + +content-type@^1.0.5, content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -2162,11 +2399,21 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +cookie-signature@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793" + integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg== + cookie@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== +cookie@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + cookiejar@^2.1.3, cookiejar@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" @@ -2200,7 +2447,7 @@ cross-env@^7.0.3: dependencies: cross-spawn "^7.0.1" -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -2274,6 +2521,13 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.5, debug@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== + dependencies: + ms "^2.1.3" + decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -2329,7 +2583,7 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0: +depd@2.0.0, depd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -2438,6 +2692,15 @@ dotenv@^16.4.4: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + duplexify@^4.0.0, duplexify@^4.1.1: version "4.1.3" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.3.tgz#a07e1c0d0a2c001158563d32592ba58bddb0236f" @@ -2492,16 +2755,16 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +encodeurl@^2.0.0, encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -2509,6 +2772,14 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" +enhanced-resolve@^5.17.1: + version "5.18.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" + integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + ent@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.1.tgz#68dc99a002f115792c26239baedaaea9e70c0ca2" @@ -2587,6 +2858,11 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + es-errors@^1.2.1, es-errors@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" @@ -2620,6 +2896,13 @@ es-object-atoms@^1.0.0: dependencies: es-errors "^1.3.0" +es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + es-set-tostringtag@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" @@ -2650,11 +2933,16 @@ escalade@^3.1.1, escalade@^3.2.0: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-html@~1.0.3: +escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + escape-string-regexp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" @@ -2665,6 +2953,25 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +eslint-compat-utils@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz#7fc92b776d185a70c4070d03fd26fde3d59652e4" + integrity sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q== + dependencies: + semver "^7.5.4" + +eslint-config-love@^119.0.0: + version "119.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-love/-/eslint-config-love-119.0.0.tgz#372ded9afea83d2be570074c666dc7a1a46197c6" + integrity sha512-O6iYQcFPR3lTzSlMSdKmfdKUCIX8ESHM9LV448vw6q6gxWuVzfA5iBCvVuogIeRQLZpH72Jc7W/fz27jcgtNdg== + dependencies: + "@typescript-eslint/utils" "^8.26.0" + eslint-plugin-eslint-comments "^3.2.0" + eslint-plugin-import "^2.31.0" + eslint-plugin-n "^17.0.0" + eslint-plugin-promise "^7.0.0" + typescript-eslint "^8.26.0" + eslint-config-standard-jsx@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-11.0.0.tgz#70852d395731a96704a592be5b0bfaccfeded239" @@ -2699,6 +3006,15 @@ eslint-module-utils@^2.12.0: dependencies: debug "^3.2.7" +eslint-plugin-es-x@^7.8.0: + version "7.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz#a207aa08da37a7923f2a9599e6d3eb73f3f92b74" + integrity sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ== + dependencies: + "@eslint-community/eslint-utils" "^4.1.2" + "@eslint-community/regexpp" "^4.11.0" + eslint-compat-utils "^0.5.1" + eslint-plugin-es@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz#f0822f0c18a535a97c3e714e89f88586a7641ec9" @@ -2707,7 +3023,15 @@ eslint-plugin-es@^4.1.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@^2.25.2: +eslint-plugin-eslint-comments@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa" + integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + +eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.31.0: version "2.31.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7" integrity sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A== @@ -2746,11 +3070,32 @@ eslint-plugin-n@^15.0.0: resolve "^1.22.1" semver "^7.3.8" +eslint-plugin-n@^17.0.0: + version "17.18.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-17.18.0.tgz#8515979b49ef8db7bb16e457b8ed22cc695d2a84" + integrity sha512-hvZ/HusueqTJ7VDLoCpjN0hx4N4+jHIWTXD4TMLHy9F23XkDagR9v+xQWRWR57yY55GPF8NnD4ox9iGTxirY8A== + dependencies: + "@eslint-community/eslint-utils" "^4.5.0" + enhanced-resolve "^5.17.1" + eslint-plugin-es-x "^7.8.0" + get-tsconfig "^4.8.1" + globals "^15.11.0" + ignore "^5.3.2" + minimatch "^9.0.5" + semver "^7.6.3" + eslint-plugin-promise@^6.0.0: version "6.6.0" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz#acd3fd7d55cead7a10f92cf698f36c0aafcd717a" integrity sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ== +eslint-plugin-promise@^7.0.0: + version "7.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz#a0652195700aea40b926dc3c74b38e373377bfb0" + integrity sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + eslint-plugin-react@^7.28.0: version "7.37.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz#cd0935987876ba2900df2f58339f6d92305acc7a" @@ -2791,6 +3136,14 @@ eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" +eslint-scope@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.3.0.tgz#10cd3a918ffdd722f5f3f7b5b83db9b23c87340d" + integrity sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + eslint-utils@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" @@ -2820,6 +3173,11 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + eslint@^8.0.1: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" @@ -2864,6 +3222,58 @@ eslint@^8.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" +eslint@^9.26.0: + version "9.26.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.26.0.tgz#978fe029adc2aceed28ab437bca876e83461c3b4" + integrity sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.20.0" + "@eslint/config-helpers" "^0.2.1" + "@eslint/core" "^0.13.0" + "@eslint/eslintrc" "^3.3.1" + "@eslint/js" "9.26.0" + "@eslint/plugin-kit" "^0.2.8" + "@humanfs/node" "^0.16.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.2" + "@modelcontextprotocol/sdk" "^1.8.0" + "@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.3.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" + zod "^3.24.2" + +espree@^10.0.1, espree@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" @@ -2878,7 +3288,7 @@ esprima@^4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: +esquery@^1.4.2, esquery@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== @@ -2907,7 +3317,7 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -etag@~1.8.1: +etag@^1.8.1, etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== @@ -2917,6 +3327,18 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +eventsource-parser@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.1.tgz#5e358dba9a55ba64ca90da883c4ca35bd82467bd" + integrity sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA== + +eventsource@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-3.0.7.tgz#1157622e2f5377bb6aef2114372728ba0c156989" + integrity sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA== + dependencies: + eventsource-parser "^3.0.1" + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -2953,6 +3375,11 @@ expect@^29.0.0, expect@^29.7.0: jest-message-util "^29.7.0" jest-util "^29.7.0" +express-rate-limit@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-7.5.0.tgz#6a67990a724b4fbbc69119419feef50c51e8b28f" + integrity sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg== + express@^4.18.2, express@^4.21.1: version "4.21.1" resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" @@ -2990,6 +3417,39 @@ express@^4.18.2, express@^4.21.1: utils-merge "1.0.1" vary "~1.1.2" +express@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/express/-/express-5.1.0.tgz#d31beaf715a0016f0d53f47d3b4d7acf28c75cc9" + integrity sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA== + dependencies: + accepts "^2.0.0" + body-parser "^2.2.0" + content-disposition "^1.0.0" + content-type "^1.0.5" + cookie "^0.7.1" + cookie-signature "^1.2.1" + debug "^4.4.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + finalhandler "^2.1.0" + fresh "^2.0.0" + http-errors "^2.0.0" + merge-descriptors "^2.0.0" + mime-types "^3.0.0" + on-finished "^2.4.1" + once "^1.4.0" + parseurl "^1.3.3" + proxy-addr "^2.0.7" + qs "^6.14.0" + range-parser "^1.2.1" + router "^2.2.0" + send "^1.1.0" + serve-static "^2.2.0" + statuses "^2.0.1" + type-is "^2.0.1" + vary "^1.1.2" + extend@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -3016,6 +3476,17 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" + integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== + 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.8" + fast-json-parse@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" @@ -3074,6 +3545,13 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== + dependencies: + flat-cache "^4.0.0" + filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" @@ -3101,6 +3579,18 @@ finalhandler@1.3.1: statuses "2.0.1" unpipe "~1.0.0" +finalhandler@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-2.1.0.tgz#72306373aa89d05a8242ed569ed86a1bff7c561f" + integrity sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q== + dependencies: + debug "^4.4.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + on-finished "^2.4.1" + parseurl "^1.3.3" + statuses "^2.0.1" + find-cache-dir@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" @@ -3150,6 +3640,14 @@ flat-cache@^3.0.4: keyv "^4.5.3" rimraf "^3.0.2" +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.4" + flatstr@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931" @@ -3218,6 +3716,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-2.0.0.tgz#8dd7df6a1b3a1b3a5cf186c05a5dd267622635a4" + integrity sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A== + fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" @@ -3292,11 +3795,35 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + get-stdin@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" @@ -3316,6 +3843,13 @@ get-symbol-description@^1.0.2: es-errors "^1.3.0" get-intrinsic "^1.2.4" +get-tsconfig@^4.8.1: + version "4.10.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz#403a682b373a823612475a4c2928c7326fc0f6bb" + integrity sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A== + dependencies: + resolve-pkg-maps "^1.0.0" + github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" @@ -3371,6 +3905,16 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== + +globals@^15.11.0: + version "15.15.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.15.0.tgz#7c4761299d41c32b075715a4ce1ede7897ff72a8" + integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg== + globalthis@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" @@ -3420,7 +3964,12 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.15, graceful-fs@^4.2.9: +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + +graceful-fs@^4.1.15, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -3501,6 +4050,11 @@ has-symbols@^1.0.2, has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" @@ -3535,7 +4089,7 @@ htmlparser2@^8.0.0: domutils "^3.0.1" entities "^4.4.0" -http-errors@2.0.0: +http-errors@2.0.0, http-errors@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== @@ -3595,16 +4149,28 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.3, iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.1.1, ignore@^5.2.0: +ignore@^5.0.5, ignore@^5.1.1, ignore@^5.2.0, ignore@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== +ignore@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.4.tgz#a12c70d0f2607c5bf508fb65a40c75f037d7a078" + integrity sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A== + immer@^9.0.15: version "9.0.21" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" @@ -3812,6 +4378,11 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== +is-promise@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -4540,7 +5111,7 @@ kareem@2.5.1: resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.5.1.tgz#7b8203e11819a8e77a34b3517d3ead206764d15d" integrity sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA== -keyv@^4.5.3: +keyv@^4.5.3, keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -4782,11 +5353,21 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== +media-typer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + memory-pager@^1.0.2: version "1.5.0" resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" @@ -4797,6 +5378,11 @@ merge-descriptors@1.0.3: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== +merge-descriptors@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808" + integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -4812,7 +5398,7 @@ methods@^1.1.2, methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -micromatch@^4.0.4: +micromatch@^4.0.4, micromatch@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -4830,6 +5416,11 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.53.0.tgz#3cb63cd820fc29896d9d4e8c32ab4fcd74ccb447" integrity sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg== +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + mime-types@^2.0.8, mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" @@ -4837,6 +5428,13 @@ mime-types@^2.0.8, mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: dependencies: mime-db "1.52.0" +mime-types@^3.0.0, mime-types@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.1.tgz#b1d94d6997a9b32fd69ebaed0db73de8acb519ce" + integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== + dependencies: + mime-db "^1.54.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -4876,7 +5474,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.4: +minimatch@^9.0.4, minimatch@^9.0.5: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== @@ -5042,6 +5640,11 @@ negotiator@^0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + new-find-package-json@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/new-find-package-json/-/new-find-package-json-2.0.0.tgz#96553638781db35061f351e8ccb4d07126b6407d" @@ -5181,7 +5784,7 @@ on-exit-leak-free@^2.1.0: resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== -on-finished@2.4.1: +on-finished@2.4.1, on-finished@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -5310,7 +5913,7 @@ parse-srcset@^1.0.2: resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q== -parseurl@~1.3.3: +parseurl@^1.3.3, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -5373,6 +5976,11 @@ path-to-regexp@0.1.10: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== +path-to-regexp@^8.0.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.2.0.tgz#73990cc29e57a3ff2a0d914095156df5db79e8b4" + integrity sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -5464,6 +6072,11 @@ pirates@^4.0.4: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== +pkce-challenge@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-5.0.0.tgz#c3a405cb49e272094a38e890a2b51da0228c4d97" + integrity sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ== + pkg-conf@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-3.1.0.tgz#d9f9c75ea1bae0e77938cde045b276dac7cc69ae" @@ -5575,7 +6188,7 @@ property-expr@^2.0.4, property-expr@^2.0.5: resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== -proxy-addr@~2.0.7: +proxy-addr@^2.0.7, proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== @@ -5634,6 +6247,13 @@ qs@^6.10.3, qs@^6.11.0: dependencies: side-channel "^1.0.6" +qs@^6.14.0: + version "6.14.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" + integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== + dependencies: + side-channel "^1.1.0" + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -5654,7 +6274,7 @@ quickselect@^2.0.0: resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== -range-parser@~1.2.1: +range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== @@ -5669,6 +6289,16 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.0.tgz#25b3476f07a51600619dae3fe82ddc28a36e5e0f" + integrity sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.6.3" + unpipe "1.0.0" + rbush@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/rbush/-/rbush-3.0.1.tgz#5fafa8a79b3b9afdfe5008403a720cc1de882ecf" @@ -5765,6 +6395,11 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -5828,6 +6463,17 @@ robust-predicates@^2.0.4: resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-2.0.4.tgz#0a2367a93abd99676d075981707f29cfb402248b" integrity sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg== +router@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/router/-/router-2.2.0.tgz#019be620b711c87641167cc79b99090f00b146ef" + integrity sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ== + dependencies: + debug "^4.4.0" + depd "^2.0.0" + is-promise "^4.0.0" + parseurl "^1.3.3" + path-to-regexp "^8.0.0" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -5864,7 +6510,7 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -5896,6 +6542,11 @@ semver@^7.0.0, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semve resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +semver@^7.6.0: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + send@0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" @@ -5915,6 +6566,23 @@ send@0.19.0: range-parser "~1.2.1" statuses "2.0.1" +send@^1.1.0, send@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/send/-/send-1.2.0.tgz#32a7554fb777b831dfa828370f773a3808d37212" + integrity sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw== + dependencies: + debug "^4.3.5" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + fresh "^2.0.0" + http-errors "^2.0.0" + mime-types "^3.0.1" + ms "^2.1.3" + on-finished "^2.4.1" + range-parser "^1.2.1" + statuses "^2.0.1" + sentence-case@^1.1.1, sentence-case@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-1.1.3.tgz#8034aafc2145772d3abe1509aa42c9e1042dc139" @@ -5932,6 +6600,16 @@ serve-static@1.16.2: parseurl "~1.3.3" send "0.19.0" +serve-static@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-2.2.0.tgz#9c02564ee259bdd2251b82d659a2e7e1938d66f9" + integrity sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ== + dependencies: + encodeurl "^2.0.0" + escape-html "^1.0.3" + parseurl "^1.3.3" + send "^1.2.0" + set-function-length@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" @@ -5993,6 +6671,35 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + side-channel@^1.0.4, side-channel@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" @@ -6003,6 +6710,17 @@ side-channel@^1.0.4, side-channel@^1.0.6: get-intrinsic "^1.2.4" object-inspect "^1.13.1" +side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" + sift@16.0.1: version "16.0.1" resolved "https://registry.yarnpkg.com/sift/-/sift-16.0.1.tgz#e9c2ccc72191585008cf3e36fc447b2d2633a053" @@ -6148,7 +6866,7 @@ standard-engine@^15.0.0: pkg-conf "^3.1.0" xdg-basedir "^4.0.0" -statuses@2.0.1: +statuses@2.0.1, statuses@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== @@ -6396,6 +7114,11 @@ swap-case@^1.1.0: lower-case "^1.1.1" upper-case "^1.1.1" +tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + tar-fs@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" @@ -6541,6 +7264,11 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +ts-api-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" + integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== + ts-jest@^29.2.5: version "29.2.5" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.5.tgz#591a3c108e1f5ebd013d3152142cb5472b399d63" @@ -6645,6 +7373,15 @@ type-fest@^2.19.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== +type-is@^2.0.0, type-is@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97" + integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw== + dependencies: + content-type "^1.0.5" + media-typer "^1.1.0" + mime-types "^3.0.0" + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -6698,10 +7435,19 @@ typed-array-length@^1.0.6: possible-typed-array-names "^1.0.0" reflect.getprototypeof "^1.0.6" -typescript@4.9.5: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript-eslint@^8.26.0, typescript-eslint@^8.32.1: + version "8.32.1" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.32.1.tgz#1784335c781491be528ff84ab666e2f0f7591fd1" + integrity sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg== + dependencies: + "@typescript-eslint/eslint-plugin" "8.32.1" + "@typescript-eslint/parser" "8.32.1" + "@typescript-eslint/utils" "8.32.1" + +typescript@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== typesense@^1.8.2: version "1.8.2" @@ -6819,7 +7565,7 @@ value-or-promise@^1.0.12: resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.12.tgz#0e5abfeec70148c78460a849f6b003ea7986f15c" integrity sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q== -vary@^1, vary@~1.1.2: +vary@^1, vary@^1.1.2, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== @@ -7056,3 +7802,13 @@ yup@^1.1.1: tiny-case "^1.0.3" toposort "^2.0.2" type-fest "^2.19.0" + +zod-to-json-schema@^3.24.1: + version "3.24.5" + resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz#d1095440b147fb7c2093812a53c54df8d5df50a3" + integrity sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g== + +zod@^3.23.8, zod@^3.24.2: + version "3.24.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.4.tgz#e2e2cca5faaa012d76e527d0d36622e0a90c315f" + integrity sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg== From 91f9a80e9572691595e7c3d383728a3f5ca7cb6a Mon Sep 17 00:00:00 2001 From: CocoisBuggy Date: Wed, 14 May 2025 10:38:27 +0200 Subject: [PATCH 3/4] improve compliance and enforce the proper styles that we had before --- eslint.config.js | 26 +- package.json | 3 +- src/__tests__/bulkImport.test.ts | 42 +- src/auth/middleware.ts | 2 +- src/db/export/queries/get-all-climbs.ts | 44 +-- src/db/import/usa/AreaTree.ts | 2 +- src/db/index.ts | 2 +- src/db/utils/jobs/MapTiles/exportCmd.ts | 26 +- src/graphql/history/HistoryFieldResolvers.ts | 8 +- src/graphql/resolvers.ts | 8 +- src/model/MutableMediaDataSource.ts | 20 +- src/model/TickDataSource.ts | 2 +- src/model/UserDataSource.ts | 14 +- src/model/__tests__/BulkDataSource.test.ts | 182 ++++----- .../__tests__/MutableAreaDataSource.test.ts | 358 +++++++++--------- src/model/__tests__/MutableClimbDataSource.ts | 10 +- yarn.lock | 11 +- 17 files changed, 389 insertions(+), 371 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index cadaeda8..9afca976 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,23 +1,31 @@ // @ts-check -import tseslint from 'typescript-eslint'; +import tseslint from 'typescript-eslint' import love from 'eslint-config-love' +import stylisticTs from '@stylistic/eslint-plugin-ts' export default tseslint.config( { - ignores: ['./hacks', './db-migrations', './build', 'jest.config.cjs'], + ignores: ['./hacks', './db-migrations', './build', 'jest.config.cjs'] }, { - files: ['**/*.ts'], + files: ['**/*.ts'] }, tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked, love, { + plugins: { + '@stylistic/ts': stylisticTs + }, rules: { + '@stylistic/ts/quotes': ['error', 'single'], + '@stylistic/ts/indent': ['error', 2], + '@stylistic/ts/semi': ['error', 'never'], + 'comma-dangle': ['error', 'never'], 'promise/avoid-new': 'off', 'dot-notation': 'off', - '@typescript-eslint/dot-notation': "error", + '@typescript-eslint/dot-notation': 'error', 'prefer-const': 'off', 'no-console': 'off', 'max-nested-callbacks': 'off', @@ -26,7 +34,7 @@ export default tseslint.config( 'guard-for-in': 'off', 'eslint-comments/require-description': 'off', 'eslint-comments/no-unlimited-disable': 'off', - 'complexity': 'off', + complexity: 'off', 'arrow-body-style': 'off', '@typescript-eslint/unbound-method': 'off', '@typescript-eslint/switch-exhaustiveness-check': 'off', @@ -70,13 +78,13 @@ export default tseslint.config( '@typescript-eslint/class-methods-use-this': 'off', '@typescript-eslint/ban-ts-comment': 'off', '@typescript-eslint/await-thenable': 'off', - '@typescript-eslint/array-type': 'off', + '@typescript-eslint/array-type': 'off' }, languageOptions: { parser: tseslint.parser, parserOptions: { - project: './tsconfig.json', - }, - }, + project: './tsconfig.json' + } + } } ) diff --git a/package.json b/package.json index 80674f0d..87855120 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "author": "", "license": "AGPL-3.0-or-later", "devDependencies": { + "@stylistic/eslint-plugin-ts": "^4.2.0", "@types/auth0": "^3.3.2", "@types/jest": "^29.4.0", "@types/node": "^18.13.0", @@ -103,4 +104,4 @@ "engines": { "node": ">=22.14.0 <= 24" } -} \ No newline at end of file +} diff --git a/src/__tests__/bulkImport.test.ts b/src/__tests__/bulkImport.test.ts index 96548c94..ba982ca2 100644 --- a/src/__tests__/bulkImport.test.ts +++ b/src/__tests__/bulkImport.test.ts @@ -1,14 +1,14 @@ -import {ApolloServer} from "@apollo/server"; -import muuid from "uuid-mongodb"; -import express from "express"; -import {InMemoryDB} from "../utils/inMemoryDB.js"; -import {queryAPI, setUpServer} from "../utils/testUtils.js"; -import {muuidToString} from "../utils/helpers.js"; +import {ApolloServer} from '@apollo/server' +import muuid from 'uuid-mongodb' +import express from 'express' +import {InMemoryDB} from '../utils/inMemoryDB.js' +import {queryAPI, setUpServer} from '../utils/testUtils.js' +import {muuidToString} from '../utils/helpers.js' import exampleImportData from './import-example.json' -import {AreaType} from "../db/AreaTypes.js"; -import {BulkImportResultType} from "../db/BulkImportTypes.js"; -import MutableClimbDataSource from "../model/MutableClimbDataSource.js"; -import BulkImportDataSource from "../model/BulkImportDataSource.js"; +import {AreaType} from '../db/AreaTypes.js' +import {BulkImportResultType} from '../db/BulkImportTypes.js' +import MutableClimbDataSource from '../model/MutableClimbDataSource.js' +import BulkImportDataSource from '../model/BulkImportDataSource.js' describe('bulkImportAreas', () => { const query = ` @@ -56,7 +56,7 @@ describe('bulkImportAreas', () => { beforeEach(async () => { await inMemoryDB.clear() await bulkImport.addCountry('usa') - testArea = await bulkImport.addArea(user, "Test Area", null, "us") + testArea = await bulkImport.addArea(user, 'Test Area', null, 'us') }) afterAll(async () => { @@ -112,25 +112,25 @@ describe('bulkImportAreas', () => { ...exampleImportData.areas, { uuid: testArea.metadata.area_id, - areaName: "Updated Test Area", + areaName: 'Updated Test Area' } ] } } - }); + }) expect(res.body.errors).toBeFalsy() const result = res.body.data.bulkImportAreas as BulkImportResultType expect(result.addedAreas.length).toBe(4) - const committedAreas = await Promise.all(result.addedAreas.map((area) => bulkImport.findOneAreaByUUID(muuid.from(area.metadata.area_id)))); - expect(committedAreas.length).toBe(4); + const committedAreas = await Promise.all(result.addedAreas.map((area) => bulkImport.findOneAreaByUUID(muuid.from(area.metadata.area_id)))) + expect(committedAreas.length).toBe(4) - const committedClimbs = await Promise.all(result.addedOrUpdatedClimbs.map((climb) => climbs.findOneClimbByMUUID(climb._id))); - expect(committedClimbs.length).toBe(2); + const committedClimbs = await Promise.all(result.addedOrUpdatedClimbs.map((climb) => climbs.findOneClimbByMUUID(climb._id))) + expect(committedClimbs.length).toBe(2) - const updatedAreas = await Promise.all(result.updatedAreas.map((area) => bulkImport.findOneAreaByUUID(muuid.from(area.metadata.area_id)))); - expect(updatedAreas.length).toBe(1); - expect(updatedAreas[0].area_name).toBe("Updated Test Area"); + const updatedAreas = await Promise.all(result.updatedAreas.map((area) => bulkImport.findOneAreaByUUID(muuid.from(area.metadata.area_id)))) + expect(updatedAreas.length).toBe(1) + expect(updatedAreas[0].area_name).toBe('Updated Test Area') }) -}); \ No newline at end of file +}) \ No newline at end of file diff --git a/src/auth/middleware.ts b/src/auth/middleware.ts index d6437e21..39886b31 100644 --- a/src/auth/middleware.ts +++ b/src/auth/middleware.ts @@ -45,7 +45,7 @@ async function validateTokenAndExtractUser (req: Request): Promise([ - { - $lookup: { - from: 'areas', // other collection name - localField: 'metadata.areaRef', - foreignField: 'metadata.area_id', - as: 'area', // clobber array of climb IDs with climb objects - pipeline: [ - { - $project: { + { + $lookup: { + from: 'areas', // other collection name + localField: 'metadata.areaRef', + foreignField: 'metadata.area_id', + as: 'area', // clobber array of climb IDs with climb objects + pipeline: [ + { + $project: { // only include specific fields - _id: 0, - ancestors: 1, - pathTokens: 1 + _id: 0, + ancestors: 1, + pathTokens: 1 + } } - } - ] - } - }, - { $unwind: '$area' }, // Previous stage returns as an array of 1 element. 'unwind' turn it into an object. - { - $replaceWith: { + ] + } + }, + { $unwind: '$area' }, // Previous stage returns as an array of 1 element. 'unwind' turn it into an object. + { + $replaceWith: { // Merge area.* with top-level object - $mergeObjects: ['$$ROOT', '$area'] + $mergeObjects: ['$$ROOT', '$area'] + } } - } - ]) + ]) .skip(pageNum * chunkSize) .limit(chunkSize) diff --git a/src/db/import/usa/AreaTree.ts b/src/db/import/usa/AreaTree.ts index 1855e85f..303768d8 100644 --- a/src/db/import/usa/AreaTree.ts +++ b/src/db/import/usa/AreaTree.ts @@ -40,7 +40,7 @@ export class Tree { } else { // find this new node's parent const parent = this.getParent(key) - if (parent === undefined) assert(false, "Parent path exists but parent node doesn't") + if (parent === undefined) assert(false, 'Parent path exists but parent node doesn\'t') parent?.linkChild(newNode) newNode.setParent(parent) } diff --git a/src/db/index.ts b/src/db/index.ts index e31ae385..7dd168e8 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -58,7 +58,7 @@ export const connectDB = async (onConnected: () => any = defaultFn): Promise { const cursor = model .find({ 'metadata.leaf': true, 'metadata.lnglat': { $ne: null } }) .populate<{ climbs: ClimbType[] }>({ - path: 'climbs', - model: getClimbModel() - }) + path: 'climbs', + model: getClimbModel() + }) .batchSize(10) .allowDiskUse(true) .lean() @@ -195,9 +195,9 @@ async function exportAreas (): Promise { ]) const features: Array< - Feature< - Polygon - > + Feature< + Polygon + > > = [] for await (const doc of rs) { @@ -267,13 +267,13 @@ async function exportLCOs (): Promise { }]) const features: Array< - Feature< - Polygon, - { - id: string - name: string - } - > + Feature< + Polygon, + { + id: string + name: string + } + > > = [] // for each organization diff --git a/src/graphql/history/HistoryFieldResolvers.ts b/src/graphql/history/HistoryFieldResolvers.ts index ee6d2014..f8a9f1ee 100644 --- a/src/graphql/history/HistoryFieldResolvers.ts +++ b/src/graphql/history/HistoryFieldResolvers.ts @@ -24,10 +24,10 @@ const resolvers = { updateDescription: ({ updateDescription }: BaseChangeRecordType) => updateDescription == null ? ({ - updatedFields: [], - removedFields: [], - truncatedArrays: [] - }) + updatedFields: [], + removedFields: [], + truncatedArrays: [] + }) : updateDescription }, diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts index b173a03d..b6ba88e6 100644 --- a/src/graphql/resolvers.ts +++ b/src/graphql/resolvers.ts @@ -189,10 +189,10 @@ const resolvers = { content: (node: ClimbGQLQueryType) => node.content == null ? { - description: '', - location: '', - protection: '' - } + description: '', + location: '', + protection: '' + } : node.content, authorMetadata: getAuthorMetadataFromBaseNode, diff --git a/src/model/MutableMediaDataSource.ts b/src/model/MutableMediaDataSource.ts index 46afd86f..ffcb4fd3 100644 --- a/src/model/MutableMediaDataSource.ts +++ b/src/model/MutableMediaDataSource.ts @@ -124,16 +124,16 @@ export default class MutableMediaDataSource extends MediaDataSource { async removeEntityTag ({ mediaId, tagId }: EntityTagDeleteInput): Promise { const rs = await this.mediaObjectModel .updateOne( - { - _id: mediaId, - 'entityTags._id': tagId - }, - { - $pull: { - entityTags: { _id: tagId } - } - }, - { multi: true }) + { + _id: mediaId, + 'entityTags._id': tagId + }, + { + $pull: { + entityTags: { _id: tagId } + } + }, + { multi: true }) .orFail(new GraphQLError('Tag not found', { extensions: { code: ApolloServerErrorCode.BAD_USER_INPUT diff --git a/src/model/TickDataSource.ts b/src/model/TickDataSource.ts index a353ad2d..a42a7a2f 100644 --- a/src/model/TickDataSource.ts +++ b/src/model/TickDataSource.ts @@ -74,7 +74,7 @@ export default class TickDataSource extends MongoDataSource { const res: TickType[] = await this.tickModel.insertMany(ticks) return res } else { - throw new Error("Can't import an empty tick list, check your import url or mutation") + throw new Error('Can\'t import an empty tick list, check your import url or mutation') } } diff --git a/src/model/UserDataSource.ts b/src/model/UserDataSource.ts index b9070eeb..679274e3 100644 --- a/src/model/UserDataSource.ts +++ b/src/model/UserDataSource.ts @@ -196,13 +196,13 @@ export default class UserDataSource extends MongoDataSource { */ const rs = await this.userModel .find( - { _id: userUuid }, - { - _id: 1, - username: '$usernameInfo.username', - updatedAt: '$usernameInfo.updatedAt' - } - ).lean() + { _id: userUuid }, + { + _id: 1, + username: '$usernameInfo.username', + updatedAt: '$usernameInfo.updatedAt' + } + ).lean() if (rs?.length === 1) { // @ts-expect-error diff --git a/src/model/__tests__/BulkDataSource.test.ts b/src/model/__tests__/BulkDataSource.test.ts index c9e8744f..8677061e 100644 --- a/src/model/__tests__/BulkDataSource.test.ts +++ b/src/model/__tests__/BulkDataSource.test.ts @@ -1,81 +1,81 @@ -import {ChangeStream} from 'mongodb'; -import muuid from 'uuid-mongodb'; -import ChangeLogDataSource from '../ChangeLogDataSource.js'; -import MutableClimbDataSource from '../MutableClimbDataSource.js'; -import {AreaType} from '../../db/AreaTypes.js'; -import {ClimbType} from '../../db/ClimbTypes.js'; -import streamListener from '../../db/edit/streamListener.js'; -import inMemoryDB from "../../utils/inMemoryDB.js"; -import {isFulfilled} from "../../utils/testUtils.js"; -import BulkImportDataSource from "../BulkImportDataSource.js"; -import {BulkImportAreaInputType, BulkImportResultType} from "../../db/BulkImportTypes.js"; +import {ChangeStream} from 'mongodb' +import muuid from 'uuid-mongodb' +import ChangeLogDataSource from '../ChangeLogDataSource.js' +import MutableClimbDataSource from '../MutableClimbDataSource.js' +import {AreaType} from '../../db/AreaTypes.js' +import {ClimbType} from '../../db/ClimbTypes.js' +import streamListener from '../../db/edit/streamListener.js' +import inMemoryDB from '../../utils/inMemoryDB.js' +import {isFulfilled} from '../../utils/testUtils.js' +import BulkImportDataSource from '../BulkImportDataSource.js' +import {BulkImportAreaInputType, BulkImportResultType} from '../../db/BulkImportTypes.js' describe('bulk import e2e', () => { - let bulkImport: BulkImportDataSource; - let climbs: MutableClimbDataSource; - let stream: ChangeStream; - const testUser = muuid.v4(); + let bulkImport: BulkImportDataSource + let climbs: MutableClimbDataSource + let stream: ChangeStream + const testUser = muuid.v4() const assertBulkImport = async (...input: BulkImportAreaInputType[]): Promise => { const result = await bulkImport.bulkImport({ user: testUser, input: {areas: input}, climbs - }); + }) const addedAreas = await Promise.allSettled( result.addedAreas.map((area) => bulkImport.findOneAreaByUUID(area.metadata.area_id) ) - ); + ) const updatedAreas = await Promise.allSettled( result.updatedAreas.map((area) => bulkImport.findOneAreaByUUID(area.metadata.area_id) ) - ); + ) const addedOrUpdatedClimbs = await Promise.allSettled( result.addedOrUpdatedClimbs.map((climb) => climbs.findOneClimbByMUUID(climb._id)) - ); + ) return { addedAreas: addedAreas.filter(isFulfilled).map((p) => p.value), updatedAreas: updatedAreas.filter(isFulfilled).map((p) => p.value), - addedOrUpdatedClimbs: addedOrUpdatedClimbs.filter(isFulfilled).map((p) => p.value as ClimbType), - }; - }; + addedOrUpdatedClimbs: addedOrUpdatedClimbs.filter(isFulfilled).map((p) => p.value as ClimbType) + } + } beforeAll(async () => { await inMemoryDB.connect() - stream = await streamListener(); - }); + stream = await streamListener() + }) afterAll(async () => { try { - await stream.close(); + await stream.close() await inMemoryDB.close() } catch (e) { - console.log('error closing mongoose', e); + console.log('error closing mongoose', e) } - }); + }) beforeEach(async () => { - bulkImport = BulkImportDataSource.getInstance(); - climbs = MutableClimbDataSource.getInstance(); + bulkImport = BulkImportDataSource.getInstance() + climbs = MutableClimbDataSource.getInstance() - await bulkImport.addCountry('us'); - }); + await bulkImport.addCountry('us') + }) afterEach(async () => { - await ChangeLogDataSource.getInstance()._testRemoveAll(); + await ChangeLogDataSource.getInstance()._testRemoveAll() await inMemoryDB.clear() - }); + }) describe('adding new areas and climbs', () => { it('should commit a new minimal area to the database', async () => { await expect( assertBulkImport({ areaName: 'Minimal Area', - countryCode: 'us', + countryCode: 'us' }) ).resolves.toMatchObject({ addedAreas: [ @@ -84,26 +84,26 @@ describe('bulk import e2e', () => { gradeContext: 'US', metadata: { leaf: false, - isBoulder: false, - }, - }, - ], - }); - }); + isBoulder: false + } + } + ] + }) + }) it('should rollback when one of the areas fails to import', async () => { await expect( assertBulkImport( { areaName: 'Test Area', - countryCode: 'us', + countryCode: 'us' }, { - areaName: 'Test Area 2', + areaName: 'Test Area 2' } ) - ).rejects.toThrowError("Must provide parent Id or country code"); - }); + ).rejects.toThrowError('Must provide parent Id or country code') + }) it('should import nested areas with children', async () => { await expect( @@ -112,17 +112,17 @@ describe('bulk import e2e', () => { countryCode: 'us', children: [ { - areaName: 'Child Area 2', - }, - ], + areaName: 'Child Area 2' + } + ] }) ).resolves.toMatchObject({ addedAreas: [ {area_name: 'Parent Area', gradeContext: 'US'}, - {area_name: 'Child Area 2', gradeContext: 'US'}, - ] as Partial[], - }); - }); + {area_name: 'Child Area 2', gradeContext: 'US'} + ] as Partial[] + }) + }) it('should import nested areas with children and grandchildren', async () => { await expect( @@ -134,25 +134,25 @@ describe('bulk import e2e', () => { areaName: 'Test Area 2', children: [ { - areaName: 'Test Area 3', - }, - ], - }, - ], + areaName: 'Test Area 3' + } + ] + } + ] }) ).resolves.toMatchObject({ addedAreas: [ { area_name: 'Test Area', - pathTokens: ['United States of America', 'Test Area'], + pathTokens: ['United States of America', 'Test Area'] }, { area_name: 'Test Area 2', pathTokens: [ 'United States of America', 'Test Area', - 'Test Area 2', - ], + 'Test Area 2' + ] }, { area_name: 'Test Area 3', @@ -160,12 +160,12 @@ describe('bulk import e2e', () => { 'United States of America', 'Test Area', 'Test Area 2', - 'Test Area 3', - ], - }, - ] as Partial[], - }); - }); + 'Test Area 3' + ] + } + ] as Partial[] + }) + }) it('should import leaf areas with climbs', async () => { await expect( @@ -176,9 +176,9 @@ describe('bulk import e2e', () => { { name: 'Test Climb', grade: '5.10a', - disciplines: {sport: true}, - }, - ], + disciplines: {sport: true} + } + ] }) ).resolves.toMatchObject({ addedAreas: [ @@ -187,47 +187,47 @@ describe('bulk import e2e', () => { gradeContext: 'US', metadata: { leaf: true, - isBoulder: false, + isBoulder: false }, climbs: [{ name: 'Test Climb', grades: { - yds: '5.10a', - }, - }], - }, + yds: '5.10a' + } + }] + } ], addedOrUpdatedClimbs: [ { name: 'Test Climb', grades: { - yds: '5.10a', - }, - }, - ], - }); - }); - }); + yds: '5.10a' + } + } + ] + }) + }) + }) describe('updating existing areas', () => { - let area: AreaType; + let area: AreaType beforeEach(async () => { const result = await assertBulkImport({ areaName: 'Existing Area', - countryCode: 'us', - }); - area = result.addedAreas[0] as AreaType; - }); + countryCode: 'us' + }) + area = result.addedAreas[0] as AreaType + }) it('should update an existing area', async () => { await expect( assertBulkImport({ uuid: area.metadata.area_id, - areaName: 'New Name', + areaName: 'New Name' }) ).resolves.toMatchObject({ - updatedAreas: [{area_name: 'New Name'}], - }); - }); - }); -}); + updatedAreas: [{area_name: 'New Name'}] + }) + }) + }) +}) diff --git a/src/model/__tests__/MutableAreaDataSource.test.ts b/src/model/__tests__/MutableAreaDataSource.test.ts index 3d48c035..37581217 100644 --- a/src/model/__tests__/MutableAreaDataSource.test.ts +++ b/src/model/__tests__/MutableAreaDataSource.test.ts @@ -1,189 +1,189 @@ -import { GraphQLError } from "graphql" -import { getAreaModel, createIndexes } from "../../db" -import inMemoryDB from "../../utils/inMemoryDB" -import MutableAreaDataSource from "../MutableAreaDataSource" +import { GraphQLError } from 'graphql' +import { getAreaModel, createIndexes } from '../../db' +import inMemoryDB from '../../utils/inMemoryDB' +import MutableAreaDataSource from '../MutableAreaDataSource' import muid, { MUUID } from 'uuid-mongodb' -import { AreaType, OperationType } from "../../db/AreaTypes" -import { ChangeRecordMetadataType } from "../../db/ChangeLogType" - - -describe("Test area mutations", () => { - let areas: MutableAreaDataSource - let rootCountry: AreaType - let areaCounter = 0 - const testUser = muid.v4() - - async function addArea(name?: string, extra?: Partial<{ leaf: boolean, boulder: boolean, parent: MUUID | AreaType}>) { - function isArea(x: any): x is AreaType { - return typeof x.metadata?.area_id !== 'undefined' - } - - areaCounter += 1 - if (name === undefined || name === 'test') { - name = process.uptime().toString() + '-' + areaCounter.toString() - } - - let parent: MUUID | undefined = undefined - if (extra?.parent) { - if (isArea(extra.parent)) { - parent = extra.parent.metadata?.area_id - } else { - parent = extra.parent - } - } - - return areas.addArea( - testUser, - name, - parent ?? rootCountry.metadata.area_id, - undefined, - undefined, - extra?.leaf, - extra?.boulder - ) +import { AreaType, OperationType } from '../../db/AreaTypes' +import { ChangeRecordMetadataType } from '../../db/ChangeLogType' + + +describe('Test area mutations', () => { + let areas: MutableAreaDataSource + let rootCountry: AreaType + let areaCounter = 0 + const testUser = muid.v4() + + async function addArea(name?: string, extra?: Partial<{ leaf: boolean, boulder: boolean, parent: MUUID | AreaType}>) { + function isArea(x: any): x is AreaType { + return typeof x.metadata?.area_id !== 'undefined' } - beforeAll(async () => { - await inMemoryDB.connect() - await getAreaModel().collection.drop() - await createIndexes() - - areas = MutableAreaDataSource.getInstance() - // We need a root country, and it is beyond the scope of these tests - rootCountry = await areas.addCountry("USA") - }) - - afterAll(inMemoryDB.close) - - describe("Add area param cases", () => { - test("Add a simple area with no specifications using a parent UUID", () => areas - .addArea(testUser, 'Texas2', rootCountry.metadata.area_id) - .then(area => { - expect(area?._change).toMatchObject({ - user: testUser, - operation: OperationType.addArea, - } satisfies Partial) - })) - - test("Add an area with an unknown UUID parent should fail", - async () => await expect(() => areas.addArea(testUser, 'Texas', muid.v4())).rejects.toThrow()) - - test("Add a simple area with no specifications using a country code", () => areas.addArea(testUser, 'Texas part 2', null, 'USA') - .then(texas => areas.addArea(testUser, 'Texas Child', texas.metadata.area_id))) - - test("Add a simple area, then specify a new child one level deep", () => addArea('California') - .then(async parent => { - let child = await addArea('Child', { parent }) - expect(child).toMatchObject({ area_name: 'Child' }) - let parentCheck = await areas.findOneAreaByUUID(parent.metadata.area_id) - expect(parentCheck?.children ?? []).toContainEqual(child._id) - })) - - test("Add a leaf area", () => addArea('Somewhere').then(parent => addArea('Child', { leaf: true, parent })) - .then(async leaf => { - expect(leaf).toMatchObject({ metadata: { leaf: true }}) - let area = await areas.areaModel.findById(leaf._id) - expect(area).toMatchObject({ metadata: { leaf: true }}) - })) - - test("Add a leaf area that is a boulder", () => addArea('Maine') - .then(parent => addArea('Child', {leaf: true, boulder: true, parent} )) - .then(area => { - expect(area).toMatchObject({ - metadata: { - leaf: true, - isBoulder: true, - }, - } satisfies Partial & { metadata: Partial}>) - })) - - test("Add a NON-leaf area that is a boulder", () => addArea('Wisconcin') - .then(texas => addArea('Child', { leaf: false, boulder: true })) - .then(area => { - expect(area).toMatchObject({ - metadata: { - // Even though we specified false to leaf on the input, we expect it to be true - // after write because a boulder cannot contain sub-areas - leaf: true, - isBoulder: true, - }, - } satisfies Partial & { metadata: Partial}>) - })) - - test("Adding a child to a leaf area should cause it to become a normal area", () => addArea() - .then(parent => Promise.all(new Array(5).map(() => addArea('test', { leaf: true, parent } )))) - .then(([leaf]) => leaf) - .then(leaf => addArea('test', { parent: leaf })) - .then(leaf => expect(leaf).toMatchObject({ metadata: { leaf: false }}))) - - test("area names should be unique in their parent context", () => addArea('test').then(async parent => { - await addArea('Big ol boulder', { parent }) - await expect(() => addArea('Big ol boulder', { parent })).rejects.toThrow(GraphQLError) - })) - }) - - test("Delete Area", () => addArea("test").then(area => areas.deleteArea(testUser, area.metadata.area_id)).then(async deleted => { - expect(deleted).toBeDefined() - // TODO: this test fails based on the data returned, which appears to omit the _deleting field. - let d = await areas.areaModel.findById(deleted?._id) - - expect(d).toBeDefined() - expect(d).not.toBeNull() - expect(d?._deleting).toBeDefined() + areaCounter += 1 + if (name === undefined || name === 'test') { + name = process.uptime().toString() + '-' + areaCounter.toString() + } + + let parent: MUUID | undefined = undefined + if (extra?.parent) { + if (isArea(extra.parent)) { + parent = extra.parent.metadata?.area_id + } else { + parent = extra.parent + } + } + + return areas.addArea( + testUser, + name, + parent ?? rootCountry.metadata.area_id, + undefined, + undefined, + extra?.leaf, + extra?.boulder + ) + } + + beforeAll(async () => { + await inMemoryDB.connect() + await getAreaModel().collection.drop() + await createIndexes() + + areas = MutableAreaDataSource.getInstance() + // We need a root country, and it is beyond the scope of these tests + rootCountry = await areas.addCountry('USA') + }) + + afterAll(inMemoryDB.close) + + describe('Add area param cases', () => { + test('Add a simple area with no specifications using a parent UUID', () => areas + .addArea(testUser, 'Texas2', rootCountry.metadata.area_id) + .then(area => { + expect(area?._change).toMatchObject({ + user: testUser, + operation: OperationType.addArea + } satisfies Partial) + })) + + test('Add an area with an unknown UUID parent should fail', + async () => await expect(() => areas.addArea(testUser, 'Texas', muid.v4())).rejects.toThrow()) + + test('Add a simple area with no specifications using a country code', () => areas.addArea(testUser, 'Texas part 2', null, 'USA') + .then(texas => areas.addArea(testUser, 'Texas Child', texas.metadata.area_id))) + + test('Add a simple area, then specify a new child one level deep', () => addArea('California') + .then(async parent => { + let child = await addArea('Child', { parent }) + expect(child).toMatchObject({ area_name: 'Child' }) + let parentCheck = await areas.findOneAreaByUUID(parent.metadata.area_id) + expect(parentCheck?.children ?? []).toContainEqual(child._id) })) - test("Delete Area that is already deleted should throw", () => addArea("test") - .then(area => areas.deleteArea(testUser, area.metadata.area_id)) - .then(async area => { - expect(area).not.toBeNull() - await expect(() => areas.deleteArea(testUser, area!.metadata.area_id)).rejects.toThrow() - })) - - - - describe("Area update cases", () => { - test("Updating an area should superficially pass", () => addArea('test').then(area => areas.updateArea(testUser, area.metadata.area_id, { areaName: `New Name! ${process.uptime()}`}))) - test("Updating an area should produce a change entry in the changelog", () => addArea('test') - .then(area => areas.updateArea(testUser, area.metadata.area_id, { areaName: process.uptime().toString() })) - .then(area => { - expect(area?._change).toMatchObject({ - user: testUser, - operation: OperationType.updateArea, - } satisfies Partial) - })) - - test("Area name uniqueness in its current parent context", () => addArea('test').then(async parent => { - let [area, newArea, divorcedArea] = await Promise.all([ - addArea('original', { parent }), - addArea('wannabe', { parent }), - addArea(undefined, { parent: rootCountry }), - ]) - - await Promise.all([ - // Case where an area gets changed to what it already is, which should not throw an error - areas.updateArea(testUser, area.metadata.area_id, { areaName: area.area_name }), - // name-uniqueness should not be global, so this shouldn't throw - areas.updateArea(testUser, divorcedArea.metadata.area_id, { areaName: area.area_name }), - // if we update one of the areas to have a name for which another area already exists, we should expect this to throw. - expect(() => areas.updateArea(testUser, newArea.metadata.area_id, { areaName: area.area_name })).rejects.toThrow(GraphQLError), - ]) - })) - }) - - test("Area name uniqueness should not create a UUID shadow via deletion", () => addArea('test').then(async parent => { - let name = 'Big ol boulder' - let big = await addArea(name, { boulder: true, parent }) - await areas.deleteArea(testUser, big.metadata.area_id) - await addArea(name, { boulder: true, parent }) + test('Add a leaf area', () => addArea('Somewhere').then(parent => addArea('Child', { leaf: true, parent })) + .then(async leaf => { + expect(leaf).toMatchObject({ metadata: { leaf: true }}) + let area = await areas.areaModel.findById(leaf._id) + expect(area).toMatchObject({ metadata: { leaf: true }}) + })) + + test('Add a leaf area that is a boulder', () => addArea('Maine') + .then(parent => addArea('Child', {leaf: true, boulder: true, parent} )) + .then(area => { + expect(area).toMatchObject({ + metadata: { + leaf: true, + isBoulder: true + } + } satisfies Partial & { metadata: Partial}>) + })) + + test('Add a NON-leaf area that is a boulder', () => addArea('Wisconcin') + .then(texas => addArea('Child', { leaf: false, boulder: true })) + .then(area => { + expect(area).toMatchObject({ + metadata: { + // Even though we specified false to leaf on the input, we expect it to be true + // after write because a boulder cannot contain sub-areas + leaf: true, + isBoulder: true + } + } satisfies Partial & { metadata: Partial}>) + })) + + test('Adding a child to a leaf area should cause it to become a normal area', () => addArea() + .then(parent => Promise.all(new Array(5).map(() => addArea('test', { leaf: true, parent } )))) + .then(([leaf]) => leaf) + .then(leaf => addArea('test', { parent: leaf })) + .then(leaf => expect(leaf).toMatchObject({ metadata: { leaf: false }}))) + + test('area names should be unique in their parent context', () => addArea('test').then(async parent => { + await addArea('Big ol boulder', { parent }) + await expect(() => addArea('Big ol boulder', { parent })).rejects.toThrow(GraphQLError) + })) + }) + + test('Delete Area', () => addArea('test').then(area => areas.deleteArea(testUser, area.metadata.area_id)).then(async deleted => { + expect(deleted).toBeDefined() + // TODO: this test fails based on the data returned, which appears to omit the _deleting field. + let d = await areas.areaModel.findById(deleted?._id) + + expect(d).toBeDefined() + expect(d).not.toBeNull() + expect(d?._deleting).toBeDefined() + })) + + test('Delete Area that is already deleted should throw', () => addArea('test') + .then(area => areas.deleteArea(testUser, area.metadata.area_id)) + .then(async area => { + expect(area).not.toBeNull() + await expect(() => areas.deleteArea(testUser, area!.metadata.area_id)).rejects.toThrow() })) - test("Area name uniqueness should not create a UUID shadow via edit of name", () => addArea('test').then(async parent => { - let nameShadow = 'Big ol boulder 2' - let big = await addArea(nameShadow, { boulder: true, parent }) - // We change the name of the original owner of the nameshadow, and then try to add a - // name claming the original name in this area structure context - await areas.updateArea(testUser, big.metadata.area_id, { areaName: "Still big ol bolder"}) - await addArea(nameShadow, { boulder: true, parent }) + + describe('Area update cases', () => { + test('Updating an area should superficially pass', () => addArea('test').then(area => areas.updateArea(testUser, area.metadata.area_id, { areaName: `New Name! ${process.uptime()}`}))) + test('Updating an area should produce a change entry in the changelog', () => addArea('test') + .then(area => areas.updateArea(testUser, area.metadata.area_id, { areaName: process.uptime().toString() })) + .then(area => { + expect(area?._change).toMatchObject({ + user: testUser, + operation: OperationType.updateArea + } satisfies Partial) + })) + + test('Area name uniqueness in its current parent context', () => addArea('test').then(async parent => { + let [area, newArea, divorcedArea] = await Promise.all([ + addArea('original', { parent }), + addArea('wannabe', { parent }), + addArea(undefined, { parent: rootCountry }) + ]) + + await Promise.all([ + // Case where an area gets changed to what it already is, which should not throw an error + areas.updateArea(testUser, area.metadata.area_id, { areaName: area.area_name }), + // name-uniqueness should not be global, so this shouldn't throw + areas.updateArea(testUser, divorcedArea.metadata.area_id, { areaName: area.area_name }), + // if we update one of the areas to have a name for which another area already exists, we should expect this to throw. + expect(() => areas.updateArea(testUser, newArea.metadata.area_id, { areaName: area.area_name })).rejects.toThrow(GraphQLError) + ]) })) + }) + + test('Area name uniqueness should not create a UUID shadow via deletion', () => addArea('test').then(async parent => { + let name = 'Big ol boulder' + let big = await addArea(name, { boulder: true, parent }) + await areas.deleteArea(testUser, big.metadata.area_id) + await addArea(name, { boulder: true, parent }) + })) + + test('Area name uniqueness should not create a UUID shadow via edit of name', () => addArea('test').then(async parent => { + let nameShadow = 'Big ol boulder 2' + let big = await addArea(nameShadow, { boulder: true, parent }) + + // We change the name of the original owner of the nameshadow, and then try to add a + // name claming the original name in this area structure context + await areas.updateArea(testUser, big.metadata.area_id, { areaName: 'Still big ol bolder'}) + await addArea(nameShadow, { boulder: true, parent }) + })) }) \ No newline at end of file diff --git a/src/model/__tests__/MutableClimbDataSource.ts b/src/model/__tests__/MutableClimbDataSource.ts index f4d4dbd1..58733b85 100644 --- a/src/model/__tests__/MutableClimbDataSource.ts +++ b/src/model/__tests__/MutableClimbDataSource.ts @@ -204,12 +204,12 @@ describe('Climb CRUD', () => { ...climbIn.description === undefined ? {} : { - content: { - description: climbIn.description, - location: climbIn.location, - protection: climbIn.protection - } + content: { + description: climbIn.description, + location: climbIn.location, + protection: climbIn.protection } + } }) } diff --git a/yarn.lock b/yarn.lock index 280953e2..11a5d886 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1081,6 +1081,15 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@stylistic/eslint-plugin-ts@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-4.2.0.tgz#8f5bd6673b735a51deb2a981d8c263830166b769" + integrity sha512-j2o2GvOx9v66x8hmp/HJ+0T+nOppiO5ycGsCkifh7JPGgjxEhpkGmIGx3RWsoxpWbad3VCX8e8/T8n3+7ze1Zg== + dependencies: + "@typescript-eslint/utils" "^8.23.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -1581,7 +1590,7 @@ eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/utils@8.32.1", "@typescript-eslint/utils@^8.26.0": +"@typescript-eslint/utils@8.32.1", "@typescript-eslint/utils@^8.23.0", "@typescript-eslint/utils@^8.26.0": version "8.32.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.32.1.tgz#4d6d5d29b9e519e9a85e9a74e9f7bdb58abe9704" integrity sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA== From 901914601e4b59359390944386c7f52a058ff241 Mon Sep 17 00:00:00 2001 From: CocoisBuggy Date: Wed, 14 May 2025 11:04:42 +0200 Subject: [PATCH 4/4] Update dockerfile node versions --- Dockerfile | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index a9e6dc79..12cde2f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM registry.gitlab.com/openbeta/openbeta-nodejs-docker:18 +FROM node:22-alpine ENV APP_DIR=/apps/openbeta-graphql @@ -13,4 +13,4 @@ COPY . *.env ./ RUN yarn install --no-progress && \ yarn build-release -CMD node --experimental-json-modules build/main.js +CMD ["node", "build/main.js"] diff --git a/package.json b/package.json index 87855120..351a40bc 100644 --- a/package.json +++ b/package.json @@ -104,4 +104,4 @@ "engines": { "node": ">=22.14.0 <= 24" } -} +} \ No newline at end of file