diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 000ce86..5938ba4 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -7,7 +7,7 @@ on: - main env: - NODE_VERSION: 20 + NODE_VERSION: 22 jobs: linting: diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 3cbfc79..d39beb9 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -30,11 +30,11 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' # Trusted publishing needs npm 11.5.1 or later. Pin the major rather than - # tracking `latest`: npm 12 requires Node >= 22.22.2, so `npm@latest` - # fails EBADENGINE against the Node 20 pinned above. + # tracking `latest` so a future npm major cannot change publish semantics + # or raise its Node floor out from under the version pinned above. - name: Update npm run: npm install -g npm@11 - run: npm ci diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml index c4efbf2..ffa6e59 100644 --- a/.github/workflows/run-tests.yaml +++ b/.github/workflows/run-tests.yaml @@ -25,6 +25,10 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - uses: actions/setup-node@v4 + with: + node-version: '22' + - name: Install dependencies run: npm ci diff --git a/.github/workflows/smoke-load-test.yaml b/.github/workflows/smoke-load-test.yaml index d70b5b2..1a38a34 100644 --- a/.github/workflows/smoke-load-test.yaml +++ b/.github/workflows/smoke-load-test.yaml @@ -52,7 +52,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: '20.18.0' + node-version: '22.12.0' cache: 'npm' - name: Install dependencies diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 5f520b6..ddb4de5 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -17,7 +17,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install dependencies run: npm ci diff --git a/Dockerfile b/Dockerfile index 880d4bb..88d5f2a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ # Stage 1: Build the TypeScript code -# Base image pinned by digest for reproducible, tamper-evident builds (node:20-alpine). -FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS build +# Pinned by digest for reproducible, tamper-evident builds; Dependabot's docker +# ecosystem keeps it current. Bump both stages together. +FROM node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2 AS build WORKDIR /app COPY package*.json ./ RUN npm ci @@ -9,7 +10,7 @@ COPY tsconfig.json ./ RUN npm run build # Stage 2: Runtime -FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 +FROM node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2 WORKDIR /app # tini as PID 1: forwards SIGTERM to node (so graceful shutdown runs) and reaps zombies. diff --git a/package-lock.json b/package-lock.json index 8a1e739..19c257a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,10 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@envelop/core": "^4.0.0", - "@envelop/disable-introspection": "^5.0.0", - "@envelop/graphql-jit": "^6.0.1", - "@envelop/opentelemetry": "^5.0.0", + "@envelop/core": "^5.5.1", + "@envelop/disable-introspection": "^9.1.1", + "@envelop/graphql-jit": "^11.1.1", + "@envelop/opentelemetry": "^9.1.1", "@graphql-tools/executor-http": "^3.0.4", "@graphql-tools/graphql-file-loader": "^8.1.2", "@graphql-tools/load": "^8.1.2", @@ -23,7 +23,7 @@ "blakejs": "^1.2.1", "dotenv": "^16.3.1", "graphql": "^16.8.0", - "graphql-yoga": "4.0.4", + "graphql-yoga": "5.21.2", "postgres": "^3.3.5", "prom-client": "^15.1.3" }, @@ -35,7 +35,7 @@ "@graphql-codegen/typescript": "^5.0.2", "@graphql-codegen/typescript-resolvers": "^5.0.1", "@graphql-eslint/eslint-plugin": "^4.4.0", - "@types/node": "^20.5.7", + "@types/node": "^22.20.1", "@typescript-eslint/eslint-plugin": "^6.5.0", "@typescript-eslint/parser": "^6.5.0", "artillery": "^2.0.0-36", @@ -49,6 +49,9 @@ "rimraf": "^5.0.5", "ts-node": "^10.9.2", "typescript": "^5.2.2" + }, + "engines": { + "node": ">=22.12.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -3161,46 +3164,51 @@ } }, "node_modules/@envelop/core": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@envelop/core/-/core-4.0.3.tgz", - "integrity": "sha512-O0Vz8E0TObT6ijAob8jYFVJavcGywKThM3UAsxUIBBVPYZTMiqI9lo2gmAnbMUnrDcAYkUTZEW9FDYPRdF5l6g==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@envelop/core/-/core-5.5.1.tgz", + "integrity": "sha512-3DQg8sFskDo386TkL5j12jyRAdip/8yzK3x7YGbZBgobZ4aKXrvDU0GppU0SnmrpQnNaiTUsxBs9LKkwQ/eyvw==", + "license": "MIT", "dependencies": { - "@envelop/types": "4.0.1", + "@envelop/instrumentation": "^1.0.0", + "@envelop/types": "^5.2.1", + "@whatwg-node/promise-helpers": "^1.2.4", "tslib": "^2.5.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@envelop/disable-introspection": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@envelop/disable-introspection/-/disable-introspection-5.0.3.tgz", - "integrity": "sha512-PoKbaeCVGdgkgQUGl46L33SBB/bYKVOe1QHEW8++n9lnTTTLJTyo8EbtJb++UcuQCaaKn277fkUyc9sR9fOh5w==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@envelop/disable-introspection/-/disable-introspection-9.1.1.tgz", + "integrity": "sha512-LujFcdpDv+i2DYXRL2XDlrGY2rFdrOWdrIvkotQILVAOc8Hbm2z0+kTRbpdoOFqC65J6WDfjUJ1440MWLQs45A==", + "license": "MIT", "dependencies": { "tslib": "^2.5.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^4.0.3", + "@envelop/core": "^5.5.1", "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@envelop/graphql-jit": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@envelop/graphql-jit/-/graphql-jit-6.0.5.tgz", - "integrity": "sha512-yrgZslAtOBPPfJlW4orT5Ge/k1gSy1gn/1QDNcPVv/6lprbHYaC/QXAo5WdHxSA0KYgzxqYOSX1jnSQjMDkOWA==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@envelop/graphql-jit/-/graphql-jit-11.1.1.tgz", + "integrity": "sha512-hXglHnwmxhIaHcwYJf+qSD1WouxlIPljDAFeA70KpBtnQbk0JvGKuPPB79gRJCtU8wyVPIpdSfhab2NEJ6XWpA==", + "license": "MIT", "dependencies": { - "graphql-jit": "^0.8.0", - "lru-cache": "^10.0.0", + "@whatwg-node/promise-helpers": "^1.2.3", + "graphql-jit": "0.8.7", "tslib": "^2.5.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^4.0.3", + "@envelop/core": "^5.5.1", "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, @@ -3218,44 +3226,60 @@ } }, "node_modules/@envelop/on-resolve": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@envelop/on-resolve/-/on-resolve-3.0.3.tgz", - "integrity": "sha512-Mo2w3CHmyLCScFuIO2VS2Co44vlPSc4zwujz0x+/zyaJ+eCwBQMRuE9u+9ORjvKImNxrbXI9FQVNlbF0iDk4iQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@envelop/on-resolve/-/on-resolve-7.1.1.tgz", + "integrity": "sha512-vOJbI53jrFxVQ5lJwwrwg8U9jU02jsLHCDEBEwYmB/FskjAHbQFbtNPOs49LvArb3w71pORiMsWV7jI354O9Tg==", + "license": "MIT", + "dependencies": { + "@whatwg-node/promise-helpers": "^1.0.0" + }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^4.0.3", + "@envelop/core": "^5.5.1", "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@envelop/opentelemetry": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@envelop/opentelemetry/-/opentelemetry-5.0.3.tgz", - "integrity": "sha512-nYIy4Xc5XmCnCTNKlzdmTso+Eh5UyPqQhtXYSs7L2G8eLsvIqHkZDc9LTYktgWE0GY9Ecu6zqtJcFieR4R+4aA==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@envelop/opentelemetry/-/opentelemetry-9.1.1.tgz", + "integrity": "sha512-vQ1TkRnx4lTes2IXeszl0ACzeEE3pgPZss8JXa4SSG/QlAwcIfeJDzlDUy3mlnsTeFtGtQHNO3jnnOCZxblleQ==", + "license": "MIT", "dependencies": { - "@envelop/on-resolve": "^3.0.3", - "@opentelemetry/api": "^1.0.0", + "@envelop/on-resolve": "^7.1.1", + "@opentelemetry/api": "^1.8.0", "@opentelemetry/sdk-trace-base": "^1.11.0", "tslib": "^2.5.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^4.0.3", + "@envelop/core": "^5.5.1", "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, + "node_modules/@envelop/opentelemetry/node_modules/@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@envelop/types": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@envelop/types/-/types-4.0.1.tgz", - "integrity": "sha512-ULo27/doEsP7uUhm2iTnElx13qTO6I5FKvmLoX41cpfuw8x6e0NUFknoqhEsLzAbgz8xVS5mjwcxGCXh4lDYzg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@envelop/types/-/types-5.2.1.tgz", + "integrity": "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==", + "license": "MIT", "dependencies": { + "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.5.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@eslint-community/eslint-utils": { @@ -3373,6 +3397,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" } @@ -4105,34 +4130,6 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/executor-common/node_modules/@envelop/core": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@envelop/core/-/core-5.5.1.tgz", - "integrity": "sha512-3DQg8sFskDo386TkL5j12jyRAdip/8yzK3x7YGbZBgobZ4aKXrvDU0GppU0SnmrpQnNaiTUsxBs9LKkwQ/eyvw==", - "license": "MIT", - "dependencies": { - "@envelop/instrumentation": "^1.0.0", - "@envelop/types": "^5.2.1", - "@whatwg-node/promise-helpers": "^1.2.4", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@graphql-tools/executor-common/node_modules/@envelop/types": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@envelop/types/-/types-5.2.1.tgz", - "integrity": "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==", - "license": "MIT", - "dependencies": { - "@whatwg-node/promise-helpers": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@graphql-tools/executor-common/node_modules/@graphql-tools/utils": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-11.0.0.tgz", @@ -4812,50 +4809,63 @@ } }, "node_modules/@graphql-yoga/logger": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@graphql-yoga/logger/-/logger-1.0.0.tgz", - "integrity": "sha512-JYoxwnPggH2BfO+dWlWZkDeFhyFZqaTRGLvFhy+Pjp2UxitEW6nDrw+pEDw/K9tJwMjIFMmTT9VfTqrnESmBHg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@graphql-yoga/logger/-/logger-2.0.1.tgz", + "integrity": "sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA==", + "license": "MIT", "dependencies": { - "tslib": "^2.5.2" + "tslib": "^2.8.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, + "node_modules/@graphql-yoga/logger/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/@graphql-yoga/subscription": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@graphql-yoga/subscription/-/subscription-4.0.0.tgz", - "integrity": "sha512-0qsN/BPPZNMoC2CZ8i+P6PgiJyHh1H35aKDt37qARBDaIOKDQuvEOq7+4txUKElcmXi7DYFo109FkhSQoEajrg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@graphql-yoga/subscription/-/subscription-5.0.5.tgz", + "integrity": "sha512-oCMWOqFs6QV96/NZRt/ZhTQvzjkGB4YohBOpKM4jH/lDT4qb7Lex/aGCxpi/JD9njw3zBBtMqxbaC22+tFHVvw==", + "license": "MIT", "dependencies": { - "@graphql-yoga/typed-event-target": "^2.0.0", + "@graphql-yoga/typed-event-target": "^3.0.2", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/events": "^0.1.0", - "tslib": "^2.5.2" + "tslib": "^2.8.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, - "node_modules/@graphql-yoga/subscription/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "engines": { - "node": ">=16.0.0" - } + "node_modules/@graphql-yoga/subscription/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/@graphql-yoga/typed-event-target": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@graphql-yoga/typed-event-target/-/typed-event-target-2.0.0.tgz", - "integrity": "sha512-oA/VGxGmaSDym1glOHrltw43qZsFwLLjBwvh57B79UKX/vo3+UQcRgOyE44c5RP7DCYjkrC2tuArZmb6jCzysw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@graphql-yoga/typed-event-target/-/typed-event-target-3.0.2.tgz", + "integrity": "sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA==", + "license": "MIT", "dependencies": { "@repeaterjs/repeater": "^3.0.4", - "tslib": "^2.5.2" + "tslib": "^2.8.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, + "node_modules/@graphql-yoga/typed-event-target/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/@grpc/grpc-js": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.2.tgz", @@ -5129,16 +5139,6 @@ "node": ">=18" } }, - "node_modules/@inquirer/core/node_modules/@types/node": { - "version": "22.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.8.tgz", - "integrity": "sha512-a922jJy31vqR5sk+kAdIENJjHblqcZ4RmERviFsER4WJcEONqxKcjNOlk0q7OUfrF5sddT+vng070cdfMlrPLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, "node_modules/@inquirer/core/node_modules/mute-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", @@ -5162,13 +5162,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@inquirer/core/node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, - "license": "MIT" - }, "node_modules/@inquirer/core/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -6465,11 +6458,6 @@ "jsep": "^0.4.0||^1.0.0" } }, - "node_modules/@kamilkisiela/fast-url-parser": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@kamilkisiela/fast-url-parser/-/fast-url-parser-1.1.4.tgz", - "integrity": "sha512-gbkePEBupNydxCelHCESvFSFM8XPh1Zs/OAVRW/rKpEqPAl5PbOM90Si8mv9bvnR53uPD2s/FiRxdvSejpRJew==" - }, "node_modules/@ngneat/falso": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@ngneat/falso/-/falso-7.2.0.tgz", @@ -10258,12 +10246,13 @@ } }, "node_modules/@types/node": { - "version": "20.11.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz", - "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==", + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", "devOptional": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.21.0" } }, "node_modules/@types/responselike": { @@ -10613,6 +10602,24 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/@whatwg-node/events": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.2.tgz", + "integrity": "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/events/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/@whatwg-node/fetch": { "version": "0.10.13", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.13.tgz", @@ -10666,51 +10673,26 @@ "license": "0BSD" }, "node_modules/@whatwg-node/server": { - "version": "0.9.25", - "resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.9.25.tgz", - "integrity": "sha512-DlPqPPcfyzh4/9Lz1fl4c5bZsGp/1wCh7B+cK8FE1bWoW7tlZkVguvGn/XnYPKthGzEIwo/fLdHwevH44z+eeg==", - "dependencies": { - "@whatwg-node/fetch": "^0.9.10", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@whatwg-node/server/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@whatwg-node/server/node_modules/@whatwg-node/fetch": { - "version": "0.9.16", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.16.tgz", - "integrity": "sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.11.0.tgz", + "integrity": "sha512-VSdkwnJRr8Yv9UgB2aXB3VUPWwd6Oqnn0hycFwhg9pZgWxJXb7JmhsiXe9tmpMwjHFxli12PGcz9aI63YYloGQ==", + "license": "MIT", "dependencies": { - "@whatwg-node/node-fetch": "^0.5.5", - "urlpattern-polyfill": "^10.0.0" + "@envelop/instrumentation": "^1.0.0", + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/fetch": "^0.10.13", + "@whatwg-node/promise-helpers": "^1.3.2", + "tslib": "^2.6.3" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, - "node_modules/@whatwg-node/server/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz", - "integrity": "sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw==", - "dependencies": { - "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } + "node_modules/@whatwg-node/server/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/abbrev": { "version": "1.1.1", @@ -10817,9 +10799,10 @@ } }, "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -10833,24 +10816,42 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats/node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/amdefine": { "version": "1.0.1", @@ -11312,6 +11313,7 @@ "version": "14.2.0", "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-14.2.0.tgz", "integrity": "sha512-sF308EhTenb/pDRPakm+WgiN+VdM/T1RaHj1x+MvAuT8UiQP8JmOEbxVqtkbfR4LrvOg5n7ic01kRBDGXjYikA==", + "deprecated": "prom-client has been replaced by @prometheus-io/client", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11788,17 +11790,6 @@ "node": ">= 0.10.x" } }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/c8": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/c8/-/c8-11.0.0.tgz", @@ -13229,15 +13220,6 @@ "present": "^0.0.3" } }, - "node_modules/dset": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", - "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -13778,11 +13760,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-decode-uri-component": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", - "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -13821,13 +13798,14 @@ "dev": true }, "node_modules/fast-json-stringify": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.12.0.tgz", - "integrity": "sha512-7Nnm9UPa7SfHRbHVA1kJQrGXCRzB7LMlAAqHXQFkEQqueJm1V8owm0FsE/2Do55/4CcdhwiLQERaKomOnKQkyA==", + "version": "5.16.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", + "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", + "license": "MIT", "dependencies": { "@fastify/merge-json-schemas": "^0.1.0", "ajv": "^8.10.0", - "ajv-formats": "^2.1.1", + "ajv-formats": "^3.0.1", "fast-deep-equal": "^3.1.3", "fast-uri": "^2.1.0", "json-schema-ref-resolver": "^1.0.1", @@ -13835,24 +13813,42 @@ } }, "node_modules/fast-json-stringify/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/fast-json-stringify/node_modules/ajv/node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "3.0.0", @@ -13864,18 +13860,11 @@ "fastest-levenshtein": "^1.0.7" } }, - "node_modules/fast-querystring": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", - "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", - "dependencies": { - "fast-decode-uri-component": "^1.0.1" - } - }, "node_modules/fast-uri": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.3.0.tgz", - "integrity": "sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", + "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==", + "license": "MIT" }, "node_modules/fast-xml-parser": { "version": "4.2.5", @@ -14267,6 +14256,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "license": "MIT", "dependencies": { "is-property": "^1.0.2" } @@ -14653,12 +14643,13 @@ } }, "node_modules/graphql-jit": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/graphql-jit/-/graphql-jit-0.8.4.tgz", - "integrity": "sha512-4KRrJ1ROy3Usgbl3eAoUMfdfZCRjkcw9cCGT7QwTUIHm9dPGaSaldxzGUttyjErU0rsYEb6WWyb6mMh5r6lEoQ==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/graphql-jit/-/graphql-jit-0.8.7.tgz", + "integrity": "sha512-KGzCrsxQPfEiXOUIJCexWKiWF6ycjO89kAO6SdO8OWRGwYXbG0hsLuTnbFfMq0gj7d7/ib/Gh7jtst7FHZEEjw==", + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.2.0", - "fast-json-stringify": "^5.7.0", + "fast-json-stringify": "^5.16.1", "generate-function": "^2.3.1", "lodash.memoize": "^4.1.2", "lodash.merge": "4.6.2", @@ -14725,63 +14716,36 @@ } }, "node_modules/graphql-yoga": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-4.0.4.tgz", - "integrity": "sha512-MvCLhFecYNIKuxAZisPjpIL9lxRYbpgPSNKENDO/8CV3oiFlsLJHZb5dp2sVAeLafXHeZ9TgkijLthUBc1+Jag==", + "version": "5.21.2", + "resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-5.21.2.tgz", + "integrity": "sha512-IIRF/3xtjj2D6caAWL9177hQ8tV3mWB3hve1GRnz7njPhQ3iY1jFtSp98fNGv0yV9kaPh9kKQ8JWdJZnedVmDw==", + "license": "MIT", "dependencies": { - "@envelop/core": "^4.0.0", - "@graphql-tools/executor": "^1.0.0", - "@graphql-tools/schema": "^10.0.0", - "@graphql-tools/utils": "^10.0.0", - "@graphql-yoga/logger": "^1.0.0", - "@graphql-yoga/subscription": "^4.0.0", - "@whatwg-node/fetch": "^0.9.7", - "@whatwg-node/server": "^0.9.1", - "dset": "^3.1.1", + "@envelop/core": "^5.5.1", + "@envelop/instrumentation": "^1.0.0", + "@graphql-tools/executor": "^1.5.0", + "@graphql-tools/schema": "^10.0.11", + "@graphql-tools/utils": "^10.11.0", + "@graphql-yoga/logger": "^2.0.1", + "@graphql-yoga/subscription": "^5.0.5", + "@whatwg-node/fetch": "^0.10.6", + "@whatwg-node/promise-helpers": "^1.3.2", + "@whatwg-node/server": "^0.11.0", "lru-cache": "^10.0.0", - "tslib": "^2.5.2" + "tslib": "^2.8.1" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "peerDependencies": { "graphql": "^15.2.0 || ^16.0.0" } }, - "node_modules/graphql-yoga/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/graphql-yoga/node_modules/@whatwg-node/fetch": { - "version": "0.9.16", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.16.tgz", - "integrity": "sha512-mqasZiUNquRe3ea9+aCAuo81BR6vq5opUKprPilIHTnrg8a21Z1T1OrI+KiMFX8OmwO5HUJe/vro47lpj2JPWQ==", - "dependencies": { - "@whatwg-node/node-fetch": "^0.5.5", - "urlpattern-polyfill": "^10.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/graphql-yoga/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.6.tgz", - "integrity": "sha512-cmAsGMHoI0S3AHi3CmD3ma1Q234ZI2JNmXyDyM9rLtbXejBKxU3ZWdhS+mzRIAyUxZCMGlFW1tHmROv0MDdxpw==", - "dependencies": { - "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", - "busboy": "^1.6.0", - "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0" - } + "node_modules/graphql-yoga/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/has-flag": { "version": "4.0.0", @@ -15739,7 +15703,8 @@ "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "license": "MIT" }, "node_modules/is-regexp": { "version": "1.0.0", @@ -16159,6 +16124,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" } @@ -16635,7 +16601,8 @@ "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -16645,7 +16612,8 @@ "node_modules/lodash.mergewith": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", @@ -18923,6 +18891,7 @@ "version": "15.1.3", "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-15.1.3.tgz", "integrity": "sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==", + "deprecated": "prom-client has been replaced by @prometheus-io/client", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.4.0", @@ -19340,6 +19309,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -20107,14 +20077,6 @@ "npm": ">=6" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -21230,10 +21192,11 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "devOptional": true, + "license": "MIT" }, "node_modules/unique-filename": { "version": "3.0.0", @@ -21365,6 +21328,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -21373,6 +21337,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } diff --git a/package.json b/package.json index edc7256..a064f88 100644 --- a/package.json +++ b/package.json @@ -50,12 +50,15 @@ ], "author": "O(1) Labs ", "license": "ISC", + "engines": { + "node": ">=22.12.0" + }, "devDependencies": { "@graphql-codegen/cli": "^6.0.1", "@graphql-codegen/typescript": "^5.0.2", "@graphql-codegen/typescript-resolvers": "^5.0.1", "@graphql-eslint/eslint-plugin": "^4.4.0", - "@types/node": "^20.5.7", + "@types/node": "^22.20.1", "@typescript-eslint/eslint-plugin": "^6.5.0", "@typescript-eslint/parser": "^6.5.0", "artillery": "^2.0.0-36", @@ -71,10 +74,10 @@ "typescript": "^5.2.2" }, "dependencies": { - "@envelop/core": "^4.0.0", - "@envelop/disable-introspection": "^5.0.0", - "@envelop/graphql-jit": "^6.0.1", - "@envelop/opentelemetry": "^5.0.0", + "@envelop/core": "^5.5.1", + "@envelop/disable-introspection": "^9.1.1", + "@envelop/graphql-jit": "^11.1.1", + "@envelop/opentelemetry": "^9.1.1", "@graphql-tools/executor-http": "^3.0.4", "@graphql-tools/graphql-file-loader": "^8.1.2", "@graphql-tools/load": "^8.1.2", @@ -85,11 +88,11 @@ "blakejs": "^1.2.1", "dotenv": "^16.3.1", "graphql": "^16.8.0", - "graphql-yoga": "4.0.4", + "graphql-yoga": "5.21.2", "postgres": "^3.3.5", "prom-client": "^15.1.3" }, "volta": { - "node": "20.18.0" + "node": "22.12.0" } } diff --git a/src/server/plugins.ts b/src/server/plugins.ts index 44018fa..db28e82 100644 --- a/src/server/plugins.ts +++ b/src/server/plugins.ts @@ -29,7 +29,10 @@ async function buildPlugins() { variables: true, // Includes the operation variables values as part of the metadata collected result: true, // Includes execution result object as part of the metadata collected }, - provider + // BasicTracerProvider satisfies the TracerProvider interface; the cast + // bridges duplicate @opentelemetry/api copies across packages by + // targeting the exact parameter type useOpenTelemetry expects. + provider as unknown as Parameters[1] ) ); } diff --git a/tests/unit/yoga-http-contract.test.ts b/tests/unit/yoga-http-contract.test.ts new file mode 100644 index 0000000..1b1ee6c --- /dev/null +++ b/tests/unit/yoga-http-contract.test.ts @@ -0,0 +1,49 @@ +/** + * Pins the GraphQL-over-HTTP behaviour that browser clients depend on. + * + * The mina-explorer's archive client throws on any non-2xx *before* it reads the + * GraphQL body, then keys its graceful degradation on the exact message + * "Cannot query field". Both were verified by hand across the yoga 4 → 5 upgrade + * and are unchanged — but they rest on an implicit content-negotiation default + * (yoga only switches to 400 under `Accept: application/graphql-response+json`, + * which that client never sends), so a later bump could flip them unnoticed. + * These tests turn that from "someone checked once" into a standing guard. + */ +import { describe, test } from 'node:test'; +import assert from 'node:assert'; +import { createYoga } from 'graphql-yoga'; +import { schema } from '../../src/resolvers.js'; + +/** The exact request shape the Explorer sends: POST, JSON, no Accept header. */ +function browserClientRequest(query: string) { + const yoga = createYoga({ schema, graphqlEndpoint: '/' }); + return yoga.fetch('http://localhost/', { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ query }), + }); +} + +describe('GraphQL-over-HTTP contract', () => { + test('a validation error is HTTP 200, not 400', async () => { + const response = await browserClientRequest('{ __definitelyNotAField }'); + assert.strictEqual( + response.status, + 200, + 'a 400 here would make the Explorer throw before reading the error body' + ); + }); + + test('a validation error carries the "Cannot query field" contract string', async () => { + const response = await browserClientRequest('{ __definitelyNotAField }'); + const body = await response.json(); + assert.match(body.errors[0].message, /Cannot query field/); + }); + + test('a valid query is unaffected', async () => { + const response = await browserClientRequest('{ __typename }'); + assert.strictEqual(response.status, 200); + const body = await response.json(); + assert.strictEqual(body.data.__typename, 'Query'); + }); +});