From 2f4f7b0e5aa0725c4e50997ce71a1caee1b587ba Mon Sep 17 00:00:00 2001 From: dkijania Date: Sun, 28 Jun 2026 18:42:23 +0200 Subject: [PATCH 1/3] build(deps): upgrade to graphql-yoga 5 and Node 22 LTS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring the server stack onto current majors: - graphql-yoga 4 → 5, @envelop/core 4 → 5, @envelop/graphql-jit 6 → 11, @envelop/disable-introspection 5 → 9, @envelop/opentelemetry 5 → 9. - Node 20 → 22 LTS across the Dockerfile, Volta pin, and the lint / unit-test / publish / smoke-load workflows. The only code change required is a targeted cast where useOpenTelemetry now types its provider argument against a duplicate @opentelemetry/api copy; the cast targets the exact expected parameter type. Build, unit tests, lint, and prettier all pass; the node:22 image builds and runs v22.x locally. Note: the OpenTelemetry SDK is intentionally not bumped here — the modern OTel packages drop the Jaeger exporter in favour of OTLP, so clearing the remaining @opentelemetry/* audit advisories is a separate Jaeger→OTLP migration. Closes #176. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01QSuak9smCHbp4N17xjjLF6 --- .github/workflows/lint.yaml | 2 +- .github/workflows/publish-npm.yml | 2 +- .github/workflows/smoke-load-test.yaml | 2 +- .github/workflows/unit-tests.yaml | 2 +- Dockerfile | 7 +- package-lock.json | 491 ++++++++++++------------- package.json | 12 +- src/server/plugins.ts | 5 +- 8 files changed, 251 insertions(+), 272 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 000ce866..5938ba45 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 3cbfc795..269d6373 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -30,7 +30,7 @@ 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` diff --git a/.github/workflows/smoke-load-test.yaml b/.github/workflows/smoke-load-test.yaml index d70b5b2f..1a38a345 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 5f520b64..ddb4de5a 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 880d4bb9..88d5f2a0 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 8a1e739d..81d8b877 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" }, @@ -3161,47 +3161,52 @@ } }, "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.6.0", + "resolved": "https://registry.npmjs.org/@envelop/core/-/core-5.6.0.tgz", + "integrity": "sha512-cD7HNfAzJVw/0Pxneu51UAKzUGLvkctk9rr9DVJ9b7FDe4nSa9kAGMRxx145H6ooELIUMjTd2buk3PuvjJmp/A==", + "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.2.0", + "resolved": "https://registry.npmjs.org/@envelop/disable-introspection/-/disable-introspection-9.2.0.tgz", + "integrity": "sha512-rkY2T6aafv1TMI0/kBcgoeYWHxlhOrJLJd1JRtlokL5Hahm5aS34MnQ77fRmy8HMIkBS/EN45ijWAQLVHuVBbg==", + "license": "MIT", "dependencies": { "tslib": "^2.5.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^4.0.3", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "@envelop/core": "^5.6.0", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.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.2.0", + "resolved": "https://registry.npmjs.org/@envelop/graphql-jit/-/graphql-jit-11.2.0.tgz", + "integrity": "sha512-4Qc1AK555aOJLpPrfqR7IEPK8wb8CdGFtcBaoIiPe8LVI0HHWXjVu5QXWXZNTPu5NnSjnLudg8StajDjCA7QMQ==", + "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", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "@envelop/core": "^5.6.0", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "node_modules/@envelop/instrumentation": { @@ -3218,44 +3223,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.2.0", + "resolved": "https://registry.npmjs.org/@envelop/on-resolve/-/on-resolve-7.2.0.tgz", + "integrity": "sha512-oxwfTx3DC8jz3Yj4X2pOhfTBdQ/FnnmbD1gXOK+admqM/B/+XrEpG6IFSl/BX0aVH5h1gECGtTI7gswfiX6fyQ==", + "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", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "@envelop/core": "^5.6.0", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.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.2.0", + "resolved": "https://registry.npmjs.org/@envelop/opentelemetry/-/opentelemetry-9.2.0.tgz", + "integrity": "sha512-URpEIkpkajLjLOop9SSHmtzIzHozLD4+SRtybHKjLtxTu0wLc564DP4yvYWVfxMR/AgBv+hfkdYnCflR1GUduw==", + "license": "MIT", "dependencies": { - "@envelop/on-resolve": "^3.0.3", - "@opentelemetry/api": "^1.0.0", + "@envelop/on-resolve": "^7.2.0", + "@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", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + "@envelop/core": "^5.6.0", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.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 +3394,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 +4127,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 +4806,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", @@ -6465,11 +6472,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", @@ -10613,6 +10615,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 +10686,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 +10812,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 +10829,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.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", + "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", + "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", @@ -11788,17 +11802,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 +13232,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 +13772,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 +13810,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 +13825,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.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", + "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", + "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 +13872,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.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.5.tgz", + "integrity": "sha512-k9Nq2gfGrPow/wJcIQ+dbhLqSTdHx2eH+e6IAjAam0Xs9W5Uda8eXu6Ns73byuuyYvIXYnEJ9ziARtlXm9opgw==", + "license": "MIT" }, "node_modules/fast-xml-parser": { "version": "4.2.5", @@ -14267,6 +14268,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 +14655,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 +14728,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 +15715,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 +16136,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 +16613,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 +16624,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", @@ -19340,6 +19320,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 +20088,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", @@ -21365,6 +21338,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 +21347,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 edc72562..46e13bf9 100644 --- a/package.json +++ b/package.json @@ -71,10 +71,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 +85,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 44018fa9..db28e82d 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] ) ); } From 82e1bc835db4e712b50974fa563712c44df79464 Mon Sep 17 00:00:00 2001 From: dkijania Date: Fri, 17 Jul 2026 11:38:08 +0200 Subject: [PATCH 2/3] build: pin node:22 by digest, bump @types/node, pin the HTTP contract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pins both Dockerfile stages to node:22-alpine@sha256:16e22a55… (v22.23.1, verified by pull and build). Without this, moving to a floating 22 tag would silently drop the digest pin #189 adds, reverting its reproducible/tamper-evident build hardening depending on merge order. Once #192 lands, Dependabot's docker ecosystem keeps the digest fresh. Bumps @types/node to ^22 so the types match the runtime rather than staying on 20. Adds tests pinning the GraphQL-over-HTTP behaviour the mina-explorer depends on: validation errors return 200 (its client throws on non-2xx before reading the body) and carry the literal "Cannot query field" (its fallbacks key on that string). Both were verified by hand across the 4 → 5 upgrade and are unchanged, but they rest on an implicit content-negotiation default — yoga only returns 400 under an Accept header that client never sends — so a later bump could flip them unnoticed. Now a standing guard rather than a one-time check. Addresses review feedback on #194. Co-Authored-By: Claude Opus 4.8 (1M context) --- package-lock.json | 37 ++++++-------------- package.json | 2 +- tests/unit/yoga-http-contract.test.ts | 49 +++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 27 deletions(-) create mode 100644 tests/unit/yoga-http-contract.test.ts diff --git a/package-lock.json b/package-lock.json index 81d8b877..a1e43089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", @@ -5136,16 +5136,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", @@ -5169,13 +5159,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", @@ -10260,12 +10243,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": { @@ -21203,10 +21187,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", diff --git a/package.json b/package.json index 46e13bf9..5bdac073 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,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", diff --git a/tests/unit/yoga-http-contract.test.ts b/tests/unit/yoga-http-contract.test.ts new file mode 100644 index 00000000..1b1ee6c5 --- /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'); + }); +}); From b286715fd1d0f32893af1566092f4004621643c4 Mon Sep 17 00:00:00 2001 From: dkijania Date: Wed, 19 Aug 2026 13:43:38 +0200 Subject: [PATCH 3/3] ci: pin node 22 and yoga runtime constraints --- .github/workflows/publish-npm.yml | 4 +- .github/workflows/run-tests.yaml | 4 ++ package-lock.json | 71 +++++++++++++++++-------------- package.json | 3 ++ 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 269d6373..d39beb95 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -33,8 +33,8 @@ jobs: 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 c4efbf23..ffa6e596 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/package-lock.json b/package-lock.json index a1e43089..19c257ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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,9 +3164,9 @@ } }, "node_modules/@envelop/core": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@envelop/core/-/core-5.6.0.tgz", - "integrity": "sha512-cD7HNfAzJVw/0Pxneu51UAKzUGLvkctk9rr9DVJ9b7FDe4nSa9kAGMRxx145H6ooELIUMjTd2buk3PuvjJmp/A==", + "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", @@ -3176,9 +3179,9 @@ } }, "node_modules/@envelop/disable-introspection": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@envelop/disable-introspection/-/disable-introspection-9.2.0.tgz", - "integrity": "sha512-rkY2T6aafv1TMI0/kBcgoeYWHxlhOrJLJd1JRtlokL5Hahm5aS34MnQ77fRmy8HMIkBS/EN45ijWAQLVHuVBbg==", + "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" @@ -3187,14 +3190,14 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^5.6.0", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + "@envelop/core": "^5.5.1", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@envelop/graphql-jit": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@envelop/graphql-jit/-/graphql-jit-11.2.0.tgz", - "integrity": "sha512-4Qc1AK555aOJLpPrfqR7IEPK8wb8CdGFtcBaoIiPe8LVI0HHWXjVu5QXWXZNTPu5NnSjnLudg8StajDjCA7QMQ==", + "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": { "@whatwg-node/promise-helpers": "^1.2.3", @@ -3205,8 +3208,8 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^5.6.0", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + "@envelop/core": "^5.5.1", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@envelop/instrumentation": { @@ -3223,9 +3226,9 @@ } }, "node_modules/@envelop/on-resolve": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@envelop/on-resolve/-/on-resolve-7.2.0.tgz", - "integrity": "sha512-oxwfTx3DC8jz3Yj4X2pOhfTBdQ/FnnmbD1gXOK+admqM/B/+XrEpG6IFSl/BX0aVH5h1gECGtTI7gswfiX6fyQ==", + "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" @@ -3234,17 +3237,17 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^5.6.0", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + "@envelop/core": "^5.5.1", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@envelop/opentelemetry": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@envelop/opentelemetry/-/opentelemetry-9.2.0.tgz", - "integrity": "sha512-URpEIkpkajLjLOop9SSHmtzIzHozLD4+SRtybHKjLtxTu0wLc564DP4yvYWVfxMR/AgBv+hfkdYnCflR1GUduw==", + "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": "^7.2.0", + "@envelop/on-resolve": "^7.1.1", "@opentelemetry/api": "^1.8.0", "@opentelemetry/sdk-trace-base": "^1.11.0", "tslib": "^2.5.0" @@ -3253,8 +3256,8 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@envelop/core": "^5.6.0", - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + "@envelop/core": "^5.5.1", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, "node_modules/@envelop/opentelemetry/node_modules/@opentelemetry/api": { @@ -10829,9 +10832,9 @@ } }, "node_modules/ajv-formats/node_modules/fast-uri": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", - "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", + "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", @@ -11310,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": { @@ -13825,9 +13829,9 @@ } }, "node_modules/fast-json-stringify/node_modules/ajv/node_modules/fast-uri": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", - "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", + "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", @@ -13857,9 +13861,9 @@ } }, "node_modules/fast-uri": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.5.tgz", - "integrity": "sha512-k9Nq2gfGrPow/wJcIQ+dbhLqSTdHx2eH+e6IAjAam0Xs9W5Uda8eXu6Ns73byuuyYvIXYnEJ9ziARtlXm9opgw==", + "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": { @@ -18887,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", diff --git a/package.json b/package.json index 5bdac073..a064f88d 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,9 @@ ], "author": "O(1) Labs ", "license": "ISC", + "engines": { + "node": ">=22.12.0" + }, "devDependencies": { "@graphql-codegen/cli": "^6.0.1", "@graphql-codegen/typescript": "^5.0.2",