From 85dcba58a7ed3f90eb91292952c1313da3703103 Mon Sep 17 00:00:00 2001 From: Jan Hug Date: Sun, 7 Dec 2025 13:10:23 +0100 Subject: [PATCH 01/44] separate shared types for nuxt/nitro code --- src/runtime/helpers/composables.ts | 119 ++---------------- src/runtime/helpers/shared-types.ts | 107 ++++++++++++++++ .../server/utils/useGraphqlMutation.ts | 2 +- src/runtime/server/utils/useGraphqlQuery.ts | 2 +- 4 files changed, 122 insertions(+), 108 deletions(-) create mode 100644 src/runtime/helpers/shared-types.ts diff --git a/src/runtime/helpers/composables.ts b/src/runtime/helpers/composables.ts index cbe10d7..75cfbc9 100644 --- a/src/runtime/helpers/composables.ts +++ b/src/runtime/helpers/composables.ts @@ -1,8 +1,3 @@ -import type { FetchOptions } from 'ofetch' -import type { RequestCacheOptions } from './../types' -import { CLIENT_CONTEXT_PREFIX } from '../settings' -import type { GraphqlClientContext } from '#nuxt-graphql-middleware/client-options' -import type { Query, Mutation } from '#nuxt-graphql-middleware/operation-types' import type { NuxtApp } from '#app' import type { AppConfig } from 'nuxt/schema' import { GraphqlMiddlewareCache } from './ClientCache' @@ -11,107 +6,19 @@ import { importMetaServer, } from '#nuxt-graphql-middleware/config' -export type GraphqlComposableOptions = { - fetchOptions?: FetchOptions - graphqlCaching?: RequestCacheOptions - clientContext?: Partial -} - -// Determine the argument signature for the query method. -// Variables are either not required at all, required or optional. -export type GetQueryArgs< - K extends keyof Query, - Q extends Query[K] = Query[K], -> = Q['variables'] extends null - ? [K, (null | undefined)?, GraphqlComposableOptions?] - : Q['needsVariables'] extends true - ? [K, Q['variables'], GraphqlComposableOptions?] - : [K, (Q['variables'] | null)?, GraphqlComposableOptions?] - -// Determine the argument signature for the mutation method. -export type GetMutationArgs< - K extends keyof Mutation, - M extends Mutation[K] = Mutation[K], -> = M['needsVariables'] extends true - ? [K, M['variables'], GraphqlComposableOptions?] - : [K, (M['variables'] | null)?, GraphqlComposableOptions?] - -// Determine the query result. -export type GetQueryResult< - K extends keyof Query, - Q extends Query[K] = Query[K], -> = Q['response'] - -// Determine the query result. -export type GetMutationResult< - K extends keyof Mutation, - M extends Mutation[K] = Mutation[K], -> = M['response'] - -export type QueryObjectArgs< - K extends keyof Query, - Q extends Query[K] = Query[K], -> = Q['needsVariables'] extends true - ? { - name: K - fetchOptions?: FetchOptions - graphqlCaching?: RequestCacheOptions - clientContext?: Partial - variables: Q['variables'] - } - : { - name: K - variables?: Q['variables'] | null - fetchOptions?: FetchOptions - graphqlCaching?: RequestCacheOptions - clientContext?: Partial - } - -export type MutationObjectArgs< - K extends keyof Mutation, - M extends Mutation[K] = Mutation[K], -> = M['needsVariables'] extends true - ? { - name: K - variables: M['variables'] - fetchOptions?: FetchOptions - clientContext?: Partial - } - : { - name: K - variables?: M['variables'] | null - fetchOptions?: FetchOptions - clientContext?: Partial - } - -export type PickFrom> = - T extends Array - ? T - : T extends Record - ? keyof T extends K[number] - ? T - : K[number] extends never - ? T - : Pick - : T - -export type KeysOf = Array< - T extends T ? (keyof T extends string ? keyof T : never) : never -> - -export function encodeContext( - context: Record, -) { - return Object.entries(context).reduce>( - (acc, [key, value]) => { - if (typeof value === 'string') { - acc[CLIENT_CONTEXT_PREFIX + key] = value - } - return acc - }, - {}, - ) -} +// Re-export shared types that don't depend on #app +export { + type GraphqlComposableOptions, + type GetQueryArgs, + type GetMutationArgs, + type GetQueryResult, + type GetMutationResult, + type QueryObjectArgs, + type MutationObjectArgs, + type PickFrom, + type KeysOf, + encodeContext, +} from './shared-types' export function getOrCreateClientCache( app: NuxtApp, diff --git a/src/runtime/helpers/shared-types.ts b/src/runtime/helpers/shared-types.ts new file mode 100644 index 0000000..ad5d682 --- /dev/null +++ b/src/runtime/helpers/shared-types.ts @@ -0,0 +1,107 @@ +import type { FetchOptions } from 'ofetch' +import type { RequestCacheOptions } from './../types' +import { CLIENT_CONTEXT_PREFIX } from '../settings' +import type { GraphqlClientContext } from '#nuxt-graphql-middleware/client-options' +import type { Query, Mutation } from '#nuxt-graphql-middleware/operation-types' + +export type GraphqlComposableOptions = { + fetchOptions?: FetchOptions + graphqlCaching?: RequestCacheOptions + clientContext?: Partial +} + +// Determine the argument signature for the query method. +// Variables are either not required at all, required or optional. +export type GetQueryArgs< + K extends keyof Query, + Q extends Query[K] = Query[K], +> = Q['variables'] extends null + ? [K, (null | undefined)?, GraphqlComposableOptions?] + : Q['needsVariables'] extends true + ? [K, Q['variables'], GraphqlComposableOptions?] + : [K, (Q['variables'] | null)?, GraphqlComposableOptions?] + +// Determine the argument signature for the mutation method. +export type GetMutationArgs< + K extends keyof Mutation, + M extends Mutation[K] = Mutation[K], +> = M['needsVariables'] extends true + ? [K, M['variables'], GraphqlComposableOptions?] + : [K, (M['variables'] | null)?, GraphqlComposableOptions?] + +// Determine the query result. +export type GetQueryResult< + K extends keyof Query, + Q extends Query[K] = Query[K], +> = Q['response'] + +// Determine the query result. +export type GetMutationResult< + K extends keyof Mutation, + M extends Mutation[K] = Mutation[K], +> = M['response'] + +export type QueryObjectArgs< + K extends keyof Query, + Q extends Query[K] = Query[K], +> = Q['needsVariables'] extends true + ? { + name: K + fetchOptions?: FetchOptions + graphqlCaching?: RequestCacheOptions + clientContext?: Partial + variables: Q['variables'] + } + : { + name: K + variables?: Q['variables'] | null + fetchOptions?: FetchOptions + graphqlCaching?: RequestCacheOptions + clientContext?: Partial + } + +export type MutationObjectArgs< + K extends keyof Mutation, + M extends Mutation[K] = Mutation[K], +> = M['needsVariables'] extends true + ? { + name: K + variables: M['variables'] + fetchOptions?: FetchOptions + clientContext?: Partial + } + : { + name: K + variables?: M['variables'] | null + fetchOptions?: FetchOptions + clientContext?: Partial + } + +export type PickFrom> = + T extends Array + ? T + : T extends Record + ? keyof T extends K[number] + ? T + : K[number] extends never + ? T + : Pick + : T + +export type KeysOf = Array< + T extends T ? (keyof T extends string ? keyof T : never) : never +> + +export function encodeContext( + context: Record, +) { + return Object.entries(context).reduce>( + (acc, [key, value]) => { + if (typeof value === 'string') { + acc[CLIENT_CONTEXT_PREFIX + key] = value + } + return acc + }, + {}, + ) +} diff --git a/src/runtime/server/utils/useGraphqlMutation.ts b/src/runtime/server/utils/useGraphqlMutation.ts index 296490b..86b6be2 100644 --- a/src/runtime/server/utils/useGraphqlMutation.ts +++ b/src/runtime/server/utils/useGraphqlMutation.ts @@ -4,7 +4,7 @@ import { type MutationObjectArgs, type GetMutationResult, encodeContext, -} from './../../helpers/composables' +} from './../../helpers/shared-types' import { performRequest } from '.' import type { Mutation } from '#nuxt-graphql-middleware/operation-types' diff --git a/src/runtime/server/utils/useGraphqlQuery.ts b/src/runtime/server/utils/useGraphqlQuery.ts index 496a025..b9e2b9d 100644 --- a/src/runtime/server/utils/useGraphqlQuery.ts +++ b/src/runtime/server/utils/useGraphqlQuery.ts @@ -4,7 +4,7 @@ import { type QueryObjectArgs, type GetQueryResult, encodeContext, -} from './../../helpers/composables' +} from './../../helpers/shared-types' import { encodeVariables } from './../../helpers/queryEncoding' import { performRequest } from '.' import type { Query } from '#nuxt-graphql-middleware/operation-types' From 3d1e187716b90d32ebfe5eb48ad5ff290f4b2592 Mon Sep 17 00:00:00 2001 From: Jan Hug Date: Sun, 7 Dec 2025 13:10:41 +0100 Subject: [PATCH 02/44] mcp integration --- CLAUDE.md | 107 +++ nuxt.config.ts | 3 + package-lock.json | 1118 ++++++++++++++++++++++++-- package.json | 14 +- playground/nuxt.config.ts | 10 + src/module.ts | 12 +- src/runtime/server/mcp/index.ts | 30 + src/runtime/server/mcp/tsconfig.json | 7 + tsconfig.json | 3 +- 9 files changed, 1235 insertions(+), 69 deletions(-) create mode 100644 CLAUDE.md create mode 100644 nuxt.config.ts create mode 100644 src/runtime/server/mcp/index.ts create mode 100644 src/runtime/server/mcp/tsconfig.json diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b699a6e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,107 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Common Commands + +### Development Setup +```sh +npm install # Install dependencies +npm run dev:prepare # Generate types (required before development) +``` + +### Start Apollo Server (Required for Playground) +```sh +cd apollo && npm install && npm run compile && npm run start +``` + +### Development +```sh +npm run dev # Start playground at localhost:3000 +npm run dev:layers # Start playground-layers +``` + +### Testing +```sh +npm run test # Run Vitest in watch mode +npm run test:ci # Run Vitest once +npm run test:coverage # Run with coverage report +``` + +### E2E Testing (Cypress) +```sh +npm run dev:build # Build playground first +npm run dev:start # Start built playground +npm run cypress # Run Cypress tests +npm run cypress:open # Open Cypress UI +``` + +### Linting & Formatting +```sh +npm run lint # ESLint check +npm run lint:fix # ESLint fix +npm run prettier # Prettier check +npm run prettier:fix # Prettier fix +npm run typecheck # TypeScript check (module + playgrounds) +``` + +### Build +```sh +npm run prepack # Full module build (styles + module + client) +``` + +## Architecture + +This is a Nuxt 3 module that exposes GraphQL queries and mutations as fully-typed server-side API routes. GraphQL requests happen only on the server; no GraphQL documents are included in the client bundle. + +### Directory Structure + +- `src/` - Module source code + - `module.ts` - Main module entry point + - `build/` - Build-time code generation + - `Collector.ts` - Discovers and validates GraphQL documents + - `SchemaProvider.ts` - Loads/downloads GraphQL schema + - `ModuleHelper.ts` - Manages paths, resolvers, configuration + - `ModuleContext.ts` - Public API for module hooks + - `templates/definitions/` - Code generation templates + - `runtime/` - Runtime code (browser + server) + - `composables/` - Client-side composables (`useGraphqlQuery`, `useGraphqlMutation`, etc.) + - `server/api/` - Server handlers for `/api/graphql_middleware/query/:name` and `/api/graphql_middleware/mutation/:name` + - `server/utils/` - Server utilities including `doGraphqlRequest.ts` + - `plugins/` - Nuxt plugins (`provideState.ts`, `devMode.ts`) + - `helpers/` - Shared helpers (`ClientCache.ts`, `queryEncoding.ts`) +- `playground/` - Example Nuxt app for development +- `playground-layers/` - Example with Nuxt layers +- `apollo/` - Apollo server used by playground +- `docs/` - VitePress documentation +- `test/` - Vitest unit tests +- `cypress/` - E2E tests + +### Key Patterns + +**Code Generation Flow**: GraphQL schema is loaded via `SchemaProvider`, documents are collected by `Collector`, then `graphql-typescript-deluxe` generates TypeScript types. Templates in `src/build/templates/definitions/` produce runtime code and type definitions. + +**Server Routes**: Each GraphQL operation becomes an API route. Queries use GET (`/api/graphql_middleware/query/:name`), mutations use POST (`/api/graphql_middleware/mutation/:name`). + +**Customization Hooks**: +- `nuxt-graphql-middleware:init` - Add documents/files before initialization +- `nuxt-graphql-middleware:build` - React to code generation output + +**Server Options** (defined via `defineGraphqlServerOptions`): +- `graphqlEndpoint()` - Dynamic endpoint resolution +- `serverFetchOptions()` - Custom headers/auth +- `onServerResponse()` - Transform responses +- `onServerError()` - Custom error handling +- `doGraphqlRequest()` - Complete request override + +**Client Options** (defined via `defineGraphqlClientOptions`): +- `buildClientContext()` - Pass dynamic context (language, locale) to server + +### Module Aliases +- `#nuxt-graphql-middleware` - Generated module files +- `#graphql-operations` - Generated GraphQL operation types + +### Testing Notes +- Unit tests are in `test/` and use Vitest +- E2E tests are in `cypress/e2e/` and run against the built playground +- Tests require running `npm run dev:prepare` first for type generation diff --git a/nuxt.config.ts b/nuxt.config.ts new file mode 100644 index 0000000..5a50be2 --- /dev/null +++ b/nuxt.config.ts @@ -0,0 +1,3 @@ +export default defineNuxtConfig({ + modules: ['@nuxtjs/mcp-toolkit'], +}) diff --git a/package-lock.json b/package-lock.json index a246fc4..e4a3eb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "nuxt-graphql-middleware", - "version": "5.2.2", + "version": "5.2.3", "license": "MIT", "dependencies": { "@clack/prompts": "^0.10.0", @@ -26,6 +26,7 @@ "@nuxt/kit": "^4.2.0", "@nuxt/module-builder": "^1.0.1", "@nuxt/schema": "^4.2.0", + "@nuxtjs/mcp-toolkit": "^0.5.1", "@types/micromatch": "^4.0.9", "cypress": "^13.12.0", "cypress-wait-until": "^3.0.2", @@ -50,7 +51,8 @@ "vitepress": "^1.6.3", "vitepress-plugin-mermaid": "^2.0.17", "vitest": "^1.6.0", - "vue-tsc": "^2.2.12" + "vue-tsc": "^2.2.12", + "zod": "^4.1.13" } }, "node_modules/@algolia/autocomplete-core": { @@ -187,7 +189,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.21.0.tgz", "integrity": "sha512-nZfgJH4njBK98tFCmCW1VX/ExH4bNOl9DSboxeXGgvhoL0fG1+4DDr/mrLe21OggVCQqHwXBMh6fFInvBeyhiQ==", "dev": true, - "peer": true, "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", @@ -393,7 +394,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -2937,6 +2937,96 @@ "langium": "3.0.0" } }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.24.3", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.24.3.tgz", + "integrity": "sha512-YgSHW29fuzKKAHTGe9zjNoo+yF8KaQPzDC2W9Pv41E7/57IfY+AMGJ/aDFlgTLcVVELoggKE4syABCE75u3NCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "jose": "^6.1.1", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/@napi-rs/wasm-runtime": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", @@ -2991,7 +3081,6 @@ "integrity": "sha512-48GYmH4SyzR5pqd02UXVzBfrvEGaurPKMjSWxlHgqnpI5buwOYCvH+OqvHOmvnLrDP2bxR9hbDod/UIphOjMhg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "c12": "^3.3.0", "citty": "^0.1.6", @@ -4369,7 +4458,6 @@ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -4380,7 +4468,6 @@ "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -4450,6 +4537,112 @@ } } }, + "node_modules/@nuxtjs/mcp-toolkit": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@nuxtjs/mcp-toolkit/-/mcp-toolkit-0.5.1.tgz", + "integrity": "sha512-jCpLxEonf+36aHWb2y/wvUTJHHIgkwwJY95bX1iHz5vxuDa/IpCc3IzgjfoS5uCJCTyP1PZzfIbeXtVnw2p6Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/prompts": "^0.11.0", + "@modelcontextprotocol/sdk": "^1.23.0", + "@nuxt/kit": "^4.2.1", + "automd": "^0.4.2", + "chokidar": "^4.0.3", + "defu": "^6.1.4", + "ms": "^2.1.3", + "pathe": "^2.0.3", + "satori": "^0.18.3", + "scule": "^1.3.0", + "tinyglobby": "^0.2.15" + }, + "peerDependencies": { + "zod": "^4.1.13" + }, + "peerDependenciesMeta": { + "zod": { + "optional": false + } + } + }, + "node_modules/@nuxtjs/mcp-toolkit/node_modules/@clack/core": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", + "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@nuxtjs/mcp-toolkit/node_modules/@clack/prompts": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", + "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/core": "0.5.0", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@nuxtjs/mcp-toolkit/node_modules/@nuxt/kit": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.2.1.tgz", + "integrity": "sha512-lLt8KLHyl7IClc3RqRpRikz15eCfTRlAWL9leVzPyg5N87FfKE/7EWgWvpiL/z4Tf3dQCIqQb88TmHE0JTIDvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "c12": "^3.3.1", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.7", + "ignore": "^7.0.5", + "jiti": "^2.6.1", + "klona": "^2.0.6", + "mlly": "^1.8.0", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.3.0", + "rc9": "^2.1.2", + "scule": "^1.3.0", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxtjs/mcp-toolkit/node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/@nuxtjs/mcp-toolkit/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@oxc-minify/binding-android-arm64": { "version": "0.95.0", "resolved": "https://registry.npmjs.org/@oxc-minify/binding-android-arm64/-/binding-android-arm64-0.95.0.tgz", @@ -5270,7 +5463,6 @@ "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", "devOptional": true, "hasInstallScript": true, - "peer": true, "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -6304,6 +6496,23 @@ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", "dev": true }, + "node_modules/@shuding/opentype.js": { + "version": "1.4.0-beta.0", + "resolved": "https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz", + "integrity": "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fflate": "^0.7.3", + "string.prototype.codepointat": "^0.2.1" + }, + "bin": { + "ot": "bin/ot" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -6643,6 +6852,7 @@ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -6654,6 +6864,7 @@ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -6735,7 +6946,6 @@ "version": "22.13.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.11.tgz", "integrity": "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==", - "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -6850,7 +7060,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.27.0.tgz", "integrity": "sha512-XGwIabPallYipmcOk45DpsBSgLC64A0yvdAkrwEzwZ2viqGqRUJ8eEYoPz0CWnutgAFbNMPdsGGvzjSmcWVlEA==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.27.0", "@typescript-eslint/types": "8.27.0", @@ -8179,7 +8388,6 @@ "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/parser": "^7.28.4", "@vue/shared": "3.5.22", @@ -8205,7 +8413,6 @@ "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/parser": "^7.28.4", "@vue/compiler-core": "3.5.22", @@ -8548,6 +8755,7 @@ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" @@ -8558,21 +8766,24 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", @@ -8580,6 +8791,7 @@ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", "@webassemblyjs/helper-api-error": "1.13.2", @@ -8591,7 +8803,8 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", @@ -8599,6 +8812,7 @@ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -8612,6 +8826,7 @@ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -8622,6 +8837,7 @@ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -8631,7 +8847,8 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", @@ -8639,6 +8856,7 @@ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -8656,6 +8874,7 @@ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-wasm-bytecode": "1.13.2", @@ -8670,6 +8889,7 @@ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-buffer": "1.14.1", @@ -8683,6 +8903,7 @@ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@webassemblyjs/helper-api-error": "1.13.2", @@ -8698,6 +8919,7 @@ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" @@ -8757,14 +8979,16 @@ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/abbrev": { "version": "3.0.1", @@ -8789,12 +9013,52 @@ "node": ">=6.5" } }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -8818,6 +9082,7 @@ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10.13.0" }, @@ -8896,6 +9161,7 @@ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ajv": "^8.0.0" }, @@ -8914,6 +9180,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -8930,14 +9197,14 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/algoliasearch": { "version": "5.21.0", "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.21.0.tgz", "integrity": "sha512-hexLq2lSO1K5SW9j21Ubc+q9Ptx7dyRTY7se19U8lhIlVMLCNXWCyQ6C22p9ez8ccX0v7QVmwkl2l1CnuGoO2Q==", "dev": true, - "peer": true, "dependencies": { "@algolia/client-abtesting": "5.21.0", "@algolia/client-analytics": "5.21.0", @@ -9261,6 +9528,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/automd": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/automd/-/automd-0.4.2.tgz", + "integrity": "sha512-9Gey0OG4gu2IzoLbwRj2fqyntJPbEFox/5KdOgg0zflkzq5lyOapWE324xYOvVdk9hgyjiMvDcT6XUPAIJhmag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@parcel/watcher": "^2.5.1", + "c12": "^3.3.0", + "citty": "^0.1.6", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "didyoumean2": "^7.0.4", + "magic-string": "^0.30.19", + "mdbox": "^0.1.1", + "mlly": "^1.8.0", + "ofetch": "^1.4.1", + "pathe": "^2.0.3", + "perfect-debounce": "^2.0.0", + "pkg-types": "^2.3.0", + "scule": "^1.3.0", + "tinyglobby": "^0.2.15", + "untyped": "^2.0.0" + }, + "bin": { + "automd": "dist/cli.mjs" + } + }, + "node_modules/automd/node_modules/perfect-debounce": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", + "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", + "dev": true, + "license": "MIT" + }, "node_modules/autoprefixer": { "version": "10.4.21", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", @@ -9443,6 +9746,48 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "node_modules/body-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", + "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -9488,7 +9833,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001735", "electron-to-chromium": "^1.5.204", @@ -9602,6 +9946,16 @@ "node": ">=10.16.0" } }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/c12": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/c12/-/c12-3.3.1.tgz", @@ -9735,6 +10089,16 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -9919,7 +10283,6 @@ "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", "dev": true, - "peer": true, "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", @@ -9971,6 +10334,7 @@ "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6.0" } @@ -10299,6 +10663,30 @@ "upper-case": "^2.0.2" } }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -10320,6 +10708,16 @@ "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", "dev": true }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, "node_modules/copy-anything": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", @@ -10354,6 +10752,20 @@ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", "dev": true }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cose-base": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", @@ -10486,6 +10898,30 @@ "uncrypto": "^0.1.3" } }, + "node_modules/css-background-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz", + "integrity": "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-box-shadow": { + "version": "1.0.0-3", + "resolved": "https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz", + "integrity": "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==", + "dev": true, + "license": "MIT" + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.0.tgz", @@ -10499,6 +10935,16 @@ "postcss": "^8.0.9" } }, + "node_modules/css-gradient-parser": { + "version": "0.0.17", + "resolved": "https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.17.tgz", + "integrity": "sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/css-select": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", @@ -10516,6 +10962,18 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", @@ -10960,7 +11418,6 @@ "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.31.1.tgz", "integrity": "sha512-Hx5Mtb1+hnmAKaZZ/7zL1Y5HTFYOjdDswZy/jD+1WINRU8KVi1B7+vlHdsTwY+VCFucTreoyu1RDzQJ9u0d2Hw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10" } @@ -11376,7 +11833,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -11755,6 +12211,21 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, + "node_modules/didyoumean2": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/didyoumean2/-/didyoumean2-7.0.4.tgz", + "integrity": "sha512-+yW4SNY7W2DOWe2Jx5H4c2qMTFbLGM6wIyoDPkAPy66X+sD1KfYjBPAIWPVsYqMxelflaMQCloZDudELIPhLqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.24.8", + "fastest-levenshtein": "^1.0.16", + "lodash.deburr": "^4.1.0" + }, + "engines": { + "node": "^18.12.0 || >=20.9.0" + } + }, "node_modules/diff": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", @@ -12017,6 +12488,7 @@ "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -12030,7 +12502,6 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", "devOptional": true, - "peer": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -12131,7 +12602,6 @@ "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -12199,7 +12669,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -12275,7 +12744,6 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz", "integrity": "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==", "dev": true, - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -12819,6 +13287,29 @@ "bare-events": "^2.7.0" } }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -12853,6 +13344,103 @@ "node": ">=4" } }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.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" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/exsolve": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", @@ -13049,6 +13637,16 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", @@ -13132,6 +13730,13 @@ "node": "^12.20 || >= 14.13" } }, + "node_modules/fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "dev": true, + "license": "MIT" + }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -13184,6 +13789,28 @@ "node": ">=8" } }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/find-up": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", @@ -13249,7 +13876,6 @@ "integrity": "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tabbable": "^6.2.0" } @@ -13305,6 +13931,16 @@ "node": ">=12.20.0" } }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fraction.js": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", @@ -13370,7 +14006,6 @@ "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz", "integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==", "dev": true, - "peer": true, "engines": { "node": ">=10" } @@ -13557,7 +14192,8 @@ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true, - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "peer": true }, "node_modules/global-directory": { "version": "4.0.1", @@ -13666,7 +14302,6 @@ "version": "16.10.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.10.0.tgz", "integrity": "sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==", - "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -13913,6 +14548,19 @@ "tslib": "^2.0.3" } }, + "node_modules/hex-rgb": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz", + "integrity": "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", @@ -13948,20 +14596,24 @@ } }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/http-proxy-agent": { @@ -14239,6 +14891,16 @@ "url": "https://opencollective.com/ioredis" } }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/iron-webcrypto": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", @@ -14438,6 +15100,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" + }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -14628,6 +15297,7 @@ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -14643,6 +15313,7 @@ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -15003,6 +15674,27 @@ "url": "https://github.com/sponsors/antonk52" } }, + "node_modules/linebreak": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz", + "integrity": "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "base64-js": "0.0.8", + "unicode-trie": "^2.0.0" + } + }, + "node_modules/linebreak/node_modules/base64-js": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", + "integrity": "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -15120,6 +15812,7 @@ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6.11.5" } @@ -15167,6 +15860,13 @@ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", "dev": true }, + "node_modules/lodash.deburr": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", + "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -15451,6 +16151,13 @@ "node": ">= 0.4" } }, + "node_modules/md4w": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/md4w/-/md4w-0.2.7.tgz", + "integrity": "sha512-lFM7vwk3d4MzkV2mija7aPkK6OjKXZDQsH2beX+e2cvccBoqc6RraheMtAO0Wcr/gjj5L+WS5zhb+06AmuGZrg==", + "dev": true, + "license": "MIT" + }, "node_modules/mdast-util-to-hast": { "version": "13.2.0", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", @@ -15472,6 +16179,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdbox": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/mdbox/-/mdbox-0.1.1.tgz", + "integrity": "sha512-jvLISenzbLRPWWamTG3THlhTcMbKWzJQNyTi61AVXhCBOC+gsldNTUfUNH8d3Vay83zGehFw3wZpF3xChzkTIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "md4w": "^0.2.6" + } + }, "node_modules/mdn-data": { "version": "2.12.2", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", @@ -15485,6 +16202,29 @@ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -15975,12 +16715,23 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/nitropack": { "version": "2.12.8", @@ -16485,7 +17236,6 @@ "integrity": "sha512-4qzf2Ymf07dMMj50TZdNZgMqCdzDch8NY3NO2ClucUaIvvsr6wd9+JrDpI1CckSTHwqU37/dIPFpvIQZoeHoYA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@dxup/nuxt": "^0.2.0", "@nuxt/cli": "^3.29.3", @@ -17066,7 +17816,6 @@ "integrity": "sha512-Te8fE/SmiiKWIrwBwxz5Dod87uYvsbcZ9JAL5ylPg1DevyKgTkxCXnPEaewk1Su2qpfNmry5RHoN+NywWFCG+A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@oxc-project/types": "^0.95.0" }, @@ -17246,6 +17995,13 @@ "dev": true, "license": "MIT" }, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "dev": true, + "license": "MIT" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -17266,6 +18022,17 @@ "node": ">=6" } }, + "node_modules/parse-css-color": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz", + "integrity": "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.1.4", + "hex-rgb": "^4.1.0" + } + }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -17449,6 +18216,17 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -17524,6 +18302,16 @@ "node": ">= 6" } }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/pkg-types": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", @@ -17584,7 +18372,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -18507,7 +19294,6 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -18647,6 +19433,20 @@ "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", "dev": true }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", @@ -18756,6 +19556,39 @@ "node": ">= 0.6" } }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/rc9": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", @@ -19202,7 +20035,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -19361,6 +20193,23 @@ "points-on-path": "^0.2.1" } }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/rspack-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/rspack-resolver/-/rspack-resolver-1.2.2.tgz", @@ -19463,6 +20312,39 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/satori": { + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/satori/-/satori-0.18.3.tgz", + "integrity": "sha512-T3DzWNmnrfVmk2gCIlAxLRLbGkfp3K7TyRva+Byyojqu83BNvnMeqVeYRdmUw4TKCsyH4RiQ/KuF/I4yEzgR5A==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@shuding/opentype.js": "1.4.0-beta.0", + "css-background-parser": "^0.1.0", + "css-box-shadow": "1.0.0-3", + "css-gradient-parser": "^0.0.17", + "css-to-react-native": "^3.0.0", + "emoji-regex-xs": "^2.0.1", + "escape-html": "^1.0.3", + "linebreak": "^1.1.0", + "parse-css-color": "^0.2.1", + "postcss-value-parser": "^4.2.0", + "yoga-layout": "^3.2.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/satori/node_modules/emoji-regex-xs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz", + "integrity": "sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -19476,6 +20358,7 @@ "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -19514,6 +20397,7 @@ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -19526,7 +20410,8 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/scslre": { "version": "0.3.0", @@ -20096,9 +20981,9 @@ "license": "MIT" }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "license": "MIT", "engines": { @@ -20172,6 +21057,13 @@ "node": ">=8" } }, + "node_modules/string.prototype.codepointat": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==", + "dev": true, + "license": "MIT" + }, "node_modules/stringify-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", @@ -20660,6 +21552,7 @@ "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -20727,6 +21620,7 @@ "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", @@ -20821,6 +21715,13 @@ "node": ">=16" } }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "dev": true, + "license": "MIT" + }, "node_modules/tiny-invariant": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", @@ -21083,6 +21984,48 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/type-level-regexp": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/type-level-regexp/-/type-level-regexp-0.1.17.tgz", @@ -21094,7 +22037,6 @@ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.1.tgz", "integrity": "sha512-Mn2VPNMaxoe/hlBiLriG4U55oyAa3Xo+8HbtEwV7F5WEOPXqtxzGuMZhJYHaqFJpajeQ6ZDUC2c990NAtTbdgw==", "dev": true, - "peer": true, "dependencies": { "@gerrit0/mini-shiki": "^3.2.1", "lunr": "^2.3.9", @@ -21118,7 +22060,6 @@ "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.6.1.tgz", "integrity": "sha512-SrJv9zkpCWdG1cvtWniFU6M7MkCZuheN2R3fuqDPF+O+PeZ8bzmfj1ju/BJwoPWIKyFJVPhK8Sg6tBrM1y+VoA==", "dev": true, - "peer": true, "engines": { "node": ">= 18" }, @@ -21358,6 +22299,17 @@ "url": "https://github.com/sponsors/harlan-zw" } }, + "node_modules/unicode-trie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz", + "integrity": "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, "node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", @@ -21561,6 +22513,16 @@ } } }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unplugin": { "version": "2.3.10", "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.10.tgz", @@ -21929,6 +22891,16 @@ "spdx-license-ids": "^3.0.0" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -21976,7 +22948,6 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -23602,7 +24573,6 @@ "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.22", "@vue/compiler-sfc": "3.5.22", @@ -23641,7 +24611,6 @@ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.1.1.tgz", "integrity": "sha512-bh2Z/Au5slro9QJ3neFYLanZtb1jH+W2bKqGHXAoYD4vZgNG3KeotL7JpPv5xzY4UXUXJl7TrIsnzECH63kd3Q==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.4.0", "eslint-scope": "^8.2.0", @@ -23687,7 +24656,6 @@ "integrity": "sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vue/devtools-api": "^6.6.4" }, @@ -23710,7 +24678,6 @@ "resolved": "https://registry.npmjs.org/vue-sfc-transformer/-/vue-sfc-transformer-0.1.14.tgz", "integrity": "sha512-WUgc6PKNmS9If5o/bpT+ulaF869iotD+em2l3Mj2kML5YfdxN46vXj/f9zzlaffv66up36BG1PhdP+utIyuqCg==", "dev": true, - "peer": true, "dependencies": { "@babel/parser": "^7.27.0" }, @@ -23729,7 +24696,6 @@ "integrity": "sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@volar/typescript": "2.4.15", "@vue/language-core": "2.2.12" @@ -23796,6 +24762,7 @@ "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -23831,6 +24798,7 @@ "integrity": "sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -23895,6 +24863,7 @@ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -23909,6 +24878,7 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=4.0" } @@ -24012,7 +24982,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -24162,6 +25131,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoga-layout": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", + "integrity": "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==", + "dev": true, + "license": "MIT" + }, "node_modules/youch": { "version": "4.1.0-beta.11", "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.11.tgz", @@ -24202,6 +25178,26 @@ "node": ">= 14" } }, + "node_modules/zod": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", + "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.0.tgz", + "integrity": "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 34579d4..90b96d5 100644 --- a/package.json +++ b/package.json @@ -39,16 +39,16 @@ "license": "MIT", "scripts": { "prepack": "npm run styles:build && nuxt-module-build build && npm run client:build", - "dev": "nuxi dev playground --trace-warnings", - "dev:layers": "nuxi dev playground-layers --trace-warnings", - "debug": "nuxi dev playground --inspect", - "dev:build": "nuxi build playground", + "dev": "PLAYGROUND_MODULE_BUILD=true nuxi dev playground --trace-warnings", + "dev:layers": "PLAYGROUND_MODULE_BUILD=true nuxi dev playground-layers --trace-warnings", + "debug": "PLAYGROUND_MODULE_BUILD=true nuxi dev playground --inspect", + "dev:build": "PLAYGROUND_MODULE_BUILD=true nuxi build playground", "dev:layers:build": "nuxi build playground-layers", "dev:prepare": "PLAYGROUND_MODULE_BUILD=true nuxt-module-build build --stub && PLAYGROUND_MODULE_BUILD=true nuxt-module-build prepare && nuxi prepare playground-layers && nuxi prepare playground", "dev:start": "node ./playground/.output/server/index.mjs", "client:build": "nuxi generate client", "client:dev": "nuxi dev client --port 3300", - "typecheck": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit && cd ../playground-layers && vue-tsc --noEmit", + "typecheck": "vue-tsc --noEmit && vue-tsc --noEmit -p src/runtime/server/mcp && cd playground && vue-tsc --noEmit && cd ../playground-layers && vue-tsc --noEmit", "docs:dev": "vitepress dev docs --port 5000", "docs:build": "vitepress build docs", "docs:serve": "vitepress serve docs --port 5000", @@ -85,6 +85,7 @@ "@nuxt/kit": "^4.2.0", "@nuxt/module-builder": "^1.0.1", "@nuxt/schema": "^4.2.0", + "@nuxtjs/mcp-toolkit": "^0.5.1", "@types/micromatch": "^4.0.9", "cypress": "^13.12.0", "cypress-wait-until": "^3.0.2", @@ -109,6 +110,7 @@ "vitepress": "^1.6.3", "vitepress-plugin-mermaid": "^2.0.17", "vitest": "^1.6.0", - "vue-tsc": "^2.2.12" + "vue-tsc": "^2.2.12", + "zod": "^4.1.13" } } diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 6ccdba2..ba7af20 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -46,6 +46,7 @@ export default defineNuxtConfig({ graphqlMiddlewareModule as any, '@nuxt/devtools', '@nuxt/eslint', + '@nuxtjs/mcp-toolkit', './modules/playground-module', ], graphqlMiddleware, @@ -84,6 +85,15 @@ query queryFromHook { typeCheck: 'build', strict: true, }, + nitro: { + typescript: { + tsConfig: { + include: [ + '../src/runtime/server/mcp' + ] + } + } + }, compatibilityDate: '2024-09-14', diff --git a/src/module.ts b/src/module.ts index 8eb50f9..c9b5d9f 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,5 +1,5 @@ import { fileURLToPath } from 'url' -import { defineNuxtModule } from '@nuxt/kit' +import { defineNuxtModule, installModule } from '@nuxt/kit' import { name, version } from '../package.json' import { defaultOptions } from './build/helpers' import { Collector } from './build/Collector' @@ -138,6 +138,16 @@ export default defineNuxtModule({ await collector.init() }) + nuxt.hook('mcp:definitions:paths', (foo) => { + const mcpPath = helper.resolvers.module.resolve('./runtime/server/mcp') + foo.handlers ||= [] + foo.handlers.push(mcpPath) + }) + + if (process.env.PLAYGROUND_MODULE_BUILD) { + await installModule('@nuxtjs/mcp-toolkit') + } + // ========================================================================= // Dev Mode // ========================================================================= diff --git a/src/runtime/server/mcp/index.ts b/src/runtime/server/mcp/index.ts new file mode 100644 index 0000000..50a8e4d --- /dev/null +++ b/src/runtime/server/mcp/index.ts @@ -0,0 +1,30 @@ +import { z } from 'zod' +import { defineMcpTool, defineMcpHandler } from '#imports' + +const migrationTool = defineMcpTool({ + name: 'migrate-v3-to-v4', + title: 'Migrate v3 to v4', + description: 'Migrate code from version 3 to version 4', + inputSchema: { + code: z.string().describe('The code to migrate'), + }, + handler: async ({ code }) => { + const migrated = code.replace(/v3/g, 'v4') + return { + content: [ + { + type: 'text', + text: migrated, + }, + ], + } + }, +}) + +export default defineMcpHandler({ + name: 'nuxt-graphql-middleware', + version: '1.0.0', + route: '/mcp/nuxt-graphql-middleware', + tools: [migrationTool], + browserRedirect: '/', +}) diff --git a/src/runtime/server/mcp/tsconfig.json b/src/runtime/server/mcp/tsconfig.json new file mode 100644 index 0000000..e431251 --- /dev/null +++ b/src/runtime/server/mcp/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../../../.nuxt/tsconfig.server.json", + "compilerOptions": { + "skipLibCheck": true + }, + "include": ["./**/*"] +} diff --git a/tsconfig.json b/tsconfig.json index 8966906..f8f6970 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "node_modules", "playground", "client", - "playground-layers" + "playground-layers", + "src/runtime/server/mcp" ] } From f27bdbe72bb62ac373d2d04e05bc77aff945ff93 Mon Sep 17 00:00:00 2001 From: Jan Hug Date: Sun, 7 Dec 2025 14:39:24 +0100 Subject: [PATCH 03/44] generate MCP tools --- CLAUDE.md | 34 +- apollo/src/index.ts | 327 ++++++++++++++++++ playground/app/layouts/default.vue | 21 ++ playground/app/pages/content/[slug].vue | 142 ++++++++ playground/app/pages/content/articles.vue | 66 ++++ playground/app/pages/content/blog-posts.vue | 71 ++++ .../pages/content/fragment.article.graphql | 14 + .../pages/content/fragment.blogPost.graphql | 13 + .../content/fragment.contentBase.graphql | 11 + .../app/pages/content/fragment.page.graphql | 13 + playground/app/pages/content/index.vue | 72 ++++ playground/app/pages/content/pages.vue | 68 ++++ .../pages/content/query.allContent.graphql | 18 + .../app/pages/content/query.articles.graphql | 5 + .../app/pages/content/query.blogPosts.graphql | 5 + .../pages/content/query.contentBySlug.graphql | 19 + .../app/pages/content/query.pages.graphql | 5 + .../app/pages/content/query.search.graphql | 34 ++ playground/app/pages/content/search.vue | 145 ++++++++ playground/nuxt.config.ts | 8 +- schema.graphql | 86 +++++ src/build/Collector.ts | 77 +++++ .../dev-handler/getFieldUsage/handler.ts | 158 +++++++++ src/build/dev-handler/getFieldUsage/types.ts | 33 ++ src/build/dev-handler/getFragment/handler.ts | 15 + src/build/dev-handler/getFragment/types.ts | 30 ++ .../dev-handler/getFragmentSource/handler.ts | 15 + .../dev-handler/getFragmentSource/types.ts | 21 ++ .../getFragmentsForType/handler.ts | 9 + .../dev-handler/getFragmentsForType/types.ts | 47 +++ src/build/dev-handler/getOperation/handler.ts | 16 + src/build/dev-handler/getOperation/types.ts | 44 +++ .../dev-handler/getOperationSource/handler.ts | 16 + .../dev-handler/getOperationSource/types.ts | 21 ++ .../dev-handler/getSchemaType/handler.ts | 102 ++++++ src/build/dev-handler/getSchemaType/types.ts | 88 +++++ src/build/dev-handler/getTypeUsage/handler.ts | 99 ++++++ src/build/dev-handler/getTypeUsage/types.ts | 28 ++ .../getTypesImplementingInterface/handler.ts | 37 ++ .../getTypesImplementingInterface/types.ts | 27 ++ .../dev-handler/getUnionMembers/handler.ts | 37 ++ .../dev-handler/getUnionMembers/types.ts | 27 ++ src/build/dev-handler/index.ts | 49 +++ .../dev-handler/listFragments/handler.ts | 8 + src/build/dev-handler/listFragments/types.ts | 24 ++ .../dev-handler/listOperations/handler.ts | 8 + src/build/dev-handler/listOperations/types.ts | 65 ++++ .../dev-handler/listSchemaTypes/handler.ts | 61 ++++ .../dev-handler/listSchemaTypes/types.ts | 31 ++ src/build/dev-handler/mcp-handler.ts | 109 ++++++ .../dev-handler/validateDocument/handler.ts | 56 +++ .../dev-handler/validateDocument/index.ts | 2 + .../dev-handler/validateDocument/types.ts | 39 +++ src/module.ts | 21 +- src/runtime/server/mcp/index.ts | 63 ++-- src/runtime/server/mcp/tools/getFieldUsage.ts | 50 +++ src/runtime/server/mcp/tools/getFragment.ts | 45 +++ .../server/mcp/tools/getFragmentSource.ts | 38 ++ .../server/mcp/tools/getFragmentsForType.ts | 48 +++ src/runtime/server/mcp/tools/getOperation.ts | 50 +++ .../server/mcp/tools/getOperationSource.ts | 40 +++ src/runtime/server/mcp/tools/getSchemaType.ts | 40 +++ src/runtime/server/mcp/tools/getTypeUsage.ts | 44 +++ .../tools/getTypesImplementingInterface.ts | 45 +++ .../server/mcp/tools/getUnionMembers.ts | 42 +++ src/runtime/server/mcp/tools/listFragments.ts | 35 ++ .../server/mcp/tools/listOperations.ts | 39 +++ .../server/mcp/tools/listSchemaTypes.ts | 45 +++ .../server/mcp/tools/validateDocument.ts | 37 ++ src/runtime/server/mcp/utils/index.ts | 34 ++ src/runtime/types.ts | 2 + 71 files changed, 3257 insertions(+), 37 deletions(-) create mode 100644 playground/app/pages/content/[slug].vue create mode 100644 playground/app/pages/content/articles.vue create mode 100644 playground/app/pages/content/blog-posts.vue create mode 100644 playground/app/pages/content/fragment.article.graphql create mode 100644 playground/app/pages/content/fragment.blogPost.graphql create mode 100644 playground/app/pages/content/fragment.contentBase.graphql create mode 100644 playground/app/pages/content/fragment.page.graphql create mode 100644 playground/app/pages/content/index.vue create mode 100644 playground/app/pages/content/pages.vue create mode 100644 playground/app/pages/content/query.allContent.graphql create mode 100644 playground/app/pages/content/query.articles.graphql create mode 100644 playground/app/pages/content/query.blogPosts.graphql create mode 100644 playground/app/pages/content/query.contentBySlug.graphql create mode 100644 playground/app/pages/content/query.pages.graphql create mode 100644 playground/app/pages/content/query.search.graphql create mode 100644 playground/app/pages/content/search.vue create mode 100644 src/build/dev-handler/getFieldUsage/handler.ts create mode 100644 src/build/dev-handler/getFieldUsage/types.ts create mode 100644 src/build/dev-handler/getFragment/handler.ts create mode 100644 src/build/dev-handler/getFragment/types.ts create mode 100644 src/build/dev-handler/getFragmentSource/handler.ts create mode 100644 src/build/dev-handler/getFragmentSource/types.ts create mode 100644 src/build/dev-handler/getFragmentsForType/handler.ts create mode 100644 src/build/dev-handler/getFragmentsForType/types.ts create mode 100644 src/build/dev-handler/getOperation/handler.ts create mode 100644 src/build/dev-handler/getOperation/types.ts create mode 100644 src/build/dev-handler/getOperationSource/handler.ts create mode 100644 src/build/dev-handler/getOperationSource/types.ts create mode 100644 src/build/dev-handler/getSchemaType/handler.ts create mode 100644 src/build/dev-handler/getSchemaType/types.ts create mode 100644 src/build/dev-handler/getTypeUsage/handler.ts create mode 100644 src/build/dev-handler/getTypeUsage/types.ts create mode 100644 src/build/dev-handler/getTypesImplementingInterface/handler.ts create mode 100644 src/build/dev-handler/getTypesImplementingInterface/types.ts create mode 100644 src/build/dev-handler/getUnionMembers/handler.ts create mode 100644 src/build/dev-handler/getUnionMembers/types.ts create mode 100644 src/build/dev-handler/index.ts create mode 100644 src/build/dev-handler/listFragments/handler.ts create mode 100644 src/build/dev-handler/listFragments/types.ts create mode 100644 src/build/dev-handler/listOperations/handler.ts create mode 100644 src/build/dev-handler/listOperations/types.ts create mode 100644 src/build/dev-handler/listSchemaTypes/handler.ts create mode 100644 src/build/dev-handler/listSchemaTypes/types.ts create mode 100644 src/build/dev-handler/mcp-handler.ts create mode 100644 src/build/dev-handler/validateDocument/handler.ts create mode 100644 src/build/dev-handler/validateDocument/index.ts create mode 100644 src/build/dev-handler/validateDocument/types.ts create mode 100644 src/runtime/server/mcp/tools/getFieldUsage.ts create mode 100644 src/runtime/server/mcp/tools/getFragment.ts create mode 100644 src/runtime/server/mcp/tools/getFragmentSource.ts create mode 100644 src/runtime/server/mcp/tools/getFragmentsForType.ts create mode 100644 src/runtime/server/mcp/tools/getOperation.ts create mode 100644 src/runtime/server/mcp/tools/getOperationSource.ts create mode 100644 src/runtime/server/mcp/tools/getSchemaType.ts create mode 100644 src/runtime/server/mcp/tools/getTypeUsage.ts create mode 100644 src/runtime/server/mcp/tools/getTypesImplementingInterface.ts create mode 100644 src/runtime/server/mcp/tools/getUnionMembers.ts create mode 100644 src/runtime/server/mcp/tools/listFragments.ts create mode 100644 src/runtime/server/mcp/tools/listOperations.ts create mode 100644 src/runtime/server/mcp/tools/listSchemaTypes.ts create mode 100644 src/runtime/server/mcp/tools/validateDocument.ts create mode 100644 src/runtime/server/mcp/utils/index.ts diff --git a/CLAUDE.md b/CLAUDE.md index b699a6e..8df5d07 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,27 +1,32 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +This file provides guidance to Claude Code (claude.ai/code) when working with +code in this repository. ## Common Commands ### Development Setup + ```sh npm install # Install dependencies npm run dev:prepare # Generate types (required before development) ``` ### Start Apollo Server (Required for Playground) + ```sh cd apollo && npm install && npm run compile && npm run start ``` ### Development + ```sh npm run dev # Start playground at localhost:3000 npm run dev:layers # Start playground-layers ``` ### Testing + ```sh npm run test # Run Vitest in watch mode npm run test:ci # Run Vitest once @@ -29,6 +34,7 @@ npm run test:coverage # Run with coverage report ``` ### E2E Testing (Cypress) + ```sh npm run dev:build # Build playground first npm run dev:start # Start built playground @@ -37,6 +43,7 @@ npm run cypress:open # Open Cypress UI ``` ### Linting & Formatting + ```sh npm run lint # ESLint check npm run lint:fix # ESLint fix @@ -46,13 +53,16 @@ npm run typecheck # TypeScript check (module + playgrounds) ``` ### Build + ```sh npm run prepack # Full module build (styles + module + client) ``` ## Architecture -This is a Nuxt 3 module that exposes GraphQL queries and mutations as fully-typed server-side API routes. GraphQL requests happen only on the server; no GraphQL documents are included in the client bundle. +This is a Nuxt 3 module that exposes GraphQL queries and mutations as +fully-typed server-side API routes. GraphQL requests happen only on the server; +no GraphQL documents are included in the client bundle. ### Directory Structure @@ -65,8 +75,10 @@ This is a Nuxt 3 module that exposes GraphQL queries and mutations as fully-type - `ModuleContext.ts` - Public API for module hooks - `templates/definitions/` - Code generation templates - `runtime/` - Runtime code (browser + server) - - `composables/` - Client-side composables (`useGraphqlQuery`, `useGraphqlMutation`, etc.) - - `server/api/` - Server handlers for `/api/graphql_middleware/query/:name` and `/api/graphql_middleware/mutation/:name` + - `composables/` - Client-side composables (`useGraphqlQuery`, + `useGraphqlMutation`, etc.) + - `server/api/` - Server handlers for `/api/graphql_middleware/query/:name` + and `/api/graphql_middleware/mutation/:name` - `server/utils/` - Server utilities including `doGraphqlRequest.ts` - `plugins/` - Nuxt plugins (`provideState.ts`, `devMode.ts`) - `helpers/` - Shared helpers (`ClientCache.ts`, `queryEncoding.ts`) @@ -79,15 +91,22 @@ This is a Nuxt 3 module that exposes GraphQL queries and mutations as fully-type ### Key Patterns -**Code Generation Flow**: GraphQL schema is loaded via `SchemaProvider`, documents are collected by `Collector`, then `graphql-typescript-deluxe` generates TypeScript types. Templates in `src/build/templates/definitions/` produce runtime code and type definitions. +**Code Generation Flow**: GraphQL schema is loaded via `SchemaProvider`, +documents are collected by `Collector`, then `graphql-typescript-deluxe` +generates TypeScript types. Templates in `src/build/templates/definitions/` +produce runtime code and type definitions. -**Server Routes**: Each GraphQL operation becomes an API route. Queries use GET (`/api/graphql_middleware/query/:name`), mutations use POST (`/api/graphql_middleware/mutation/:name`). +**Server Routes**: Each GraphQL operation becomes an API route. Queries use GET +(`/api/graphql_middleware/query/:name`), mutations use POST +(`/api/graphql_middleware/mutation/:name`). **Customization Hooks**: + - `nuxt-graphql-middleware:init` - Add documents/files before initialization - `nuxt-graphql-middleware:build` - React to code generation output **Server Options** (defined via `defineGraphqlServerOptions`): + - `graphqlEndpoint()` - Dynamic endpoint resolution - `serverFetchOptions()` - Custom headers/auth - `onServerResponse()` - Transform responses @@ -95,13 +114,16 @@ This is a Nuxt 3 module that exposes GraphQL queries and mutations as fully-type - `doGraphqlRequest()` - Complete request override **Client Options** (defined via `defineGraphqlClientOptions`): + - `buildClientContext()` - Pass dynamic context (language, locale) to server ### Module Aliases + - `#nuxt-graphql-middleware` - Generated module files - `#graphql-operations` - Generated GraphQL operation types ### Testing Notes + - Unit tests are in `test/` and use Vitest - E2E tests are in `cypress/e2e/` and run against the built playground - Tests require running `npm run dev:prepare` first for type generation diff --git a/apollo/src/index.ts b/apollo/src/index.ts index 0206c8b..549b40a 100644 --- a/apollo/src/index.ts +++ b/apollo/src/index.ts @@ -60,11 +60,119 @@ type FormSubmission = { documents: FormSubmissionDocument[] } +// Content types for CMS-style interface demo +type ContentBase = { + id: string + title: string + slug: string + publishedAt: string | null + authorId: number +} + +type Article = ContentBase & { + __typename: 'Article' + excerpt: string + body: string + category: string +} + +type BlogPost = ContentBase & { + __typename: 'BlogPost' + content: string + tags: string[] +} + +type Page = ContentBase & { + __typename: 'Page' + content: string + template: string +} + +type Content = Article | BlogPost | Page + let users = [] let idIncrement = 0 let files: UploadedFile[] = [] let formSubmissions: FormSubmission[] = [] +// Dummy content data +const articles: Article[] = [ + { + __typename: 'Article', + id: 'article-1', + title: 'Understanding GraphQL Interfaces', + slug: 'understanding-graphql-interfaces', + publishedAt: '2024-01-15T10:00:00Z', + authorId: 1, + excerpt: 'Learn how interfaces work in GraphQL schemas.', + body: 'GraphQL interfaces are an abstract type that includes a set of fields that a type must include to implement the interface...', + category: 'Technology', + }, + { + __typename: 'Article', + id: 'article-2', + title: 'Building Modern Web Applications', + slug: 'building-modern-web-applications', + publishedAt: '2024-02-20T14:30:00Z', + authorId: 2, + excerpt: 'A comprehensive guide to modern web development.', + body: 'Modern web applications require a combination of frontend frameworks, backend APIs, and proper architecture...', + category: 'Development', + }, +] + +const blogPosts: BlogPost[] = [ + { + __typename: 'BlogPost', + id: 'blog-1', + title: 'My Journey with Nuxt', + slug: 'my-journey-with-nuxt', + publishedAt: '2024-03-01T09:00:00Z', + authorId: 1, + content: + 'I started using Nuxt about two years ago and it has transformed how I build Vue applications...', + tags: ['nuxt', 'vue', 'javascript'], + }, + { + __typename: 'BlogPost', + id: 'blog-2', + title: 'Tips for Better Code Reviews', + slug: 'tips-for-better-code-reviews', + publishedAt: null, // Draft + authorId: 3, + content: + 'Code reviews are essential for maintaining code quality. Here are my top tips...', + tags: ['best-practices', 'teamwork'], + }, +] + +const pages: Page[] = [ + { + __typename: 'Page', + id: 'page-1', + title: 'About Us', + slug: 'about', + publishedAt: '2023-01-01T00:00:00Z', + authorId: 1, + content: 'We are a team of passionate developers building great software.', + template: 'default', + }, + { + __typename: 'Page', + id: 'page-2', + title: 'Contact', + slug: 'contact', + publishedAt: '2023-01-01T00:00:00Z', + authorId: 2, + content: 'Get in touch with us at contact@example.com', + template: 'contact', + }, +] + +function getAllContent(): Content[] { + return [...articles, ...blogPosts, ...pages] +} + function initState() { users = [...data] idIncrement = users.length @@ -86,6 +194,109 @@ const typeDefs = `#graphql email } + """ + Base interface for all content types in the CMS. + """ + interface Content { + """ + Unique identifier for the content. + """ + id: ID! + + """ + The title of the content. + """ + title: String! + + """ + URL-friendly slug. + """ + slug: String! + + """ + When the content was published. Null if draft. + """ + publishedAt: String + + """ + The author of the content. + """ + author: User + } + + """ + A long-form article with excerpt and category. + """ + type Article implements Content { + id: ID! + title: String! + slug: String! + publishedAt: String + author: User + + """ + Short excerpt for previews. + """ + excerpt: String! + + """ + Full article body. + """ + body: String! + + """ + Article category. + """ + category: String! + } + + """ + A blog post with tags. + """ + type BlogPost implements Content { + id: ID! + title: String! + slug: String! + publishedAt: String + author: User + + """ + The blog post content. + """ + content: String! + + """ + Tags for categorization. + """ + tags: [String!]! + } + + """ + A static page with a template. + """ + type Page implements Content { + id: ID! + title: String! + slug: String! + publishedAt: String + author: User + + """ + The page content. + """ + content: String! + + """ + Template to use for rendering. + """ + template: String! + } + + """ + Union type for search results. + """ + union SearchResult = User | Article | BlogPost | Page + type User { """ The ID of the user. @@ -234,6 +445,36 @@ const typeDefs = `#graphql Returns a random number. """ returnRandomNumber: Int! + + """ + Get all content items (articles, blog posts, pages). + """ + allContent: [Content!]! + + """ + Get all articles. + """ + articles: [Article!]! + + """ + Get all blog posts. + """ + blogPosts: [BlogPost!]! + + """ + Get all pages. + """ + pages: [Page!]! + + """ + Get content by slug. + """ + contentBySlug(slug: String!): Content + + """ + Search across all content types and users. + """ + search(query: String!): [SearchResult!]! } type UploadedFile { @@ -371,7 +612,93 @@ const resolvers = { returnRandomNumber: () => { return Math.round(Math.random() * 100000000) }, + + // Content queries + allContent: () => { + return getAllContent() + }, + articles: () => { + return articles + }, + blogPosts: () => { + return blogPosts + }, + pages: () => { + return pages + }, + contentBySlug: (_: any, args: { slug: string }) => { + return getAllContent().find((c) => c.slug === args.slug) || null + }, + search: (_: any, args: { query: string }) => { + const q = args.query.toLowerCase() + const results: (Content | (typeof users)[0])[] = [] + + // Search in content + for (const content of getAllContent()) { + if ( + content.title.toLowerCase().includes(q) || + content.slug.toLowerCase().includes(q) + ) { + results.push(content) + } + } + + // Search in users + for (const user of users) { + if ( + user.firstName.toLowerCase().includes(q) || + user.lastName.toLowerCase().includes(q) || + user.email.toLowerCase().includes(q) + ) { + results.push(user) + } + } + + return results + }, + }, + + // Interface type resolver + Content: { + __resolveType(obj: Content) { + return obj.__typename + }, + author: (parent: Content) => { + return users.find((u) => u.id === parent.authorId) || null + }, + }, + + // Union type resolver + SearchResult: { + __resolveType(obj: any) { + if (obj.__typename) { + return obj.__typename + } + // Users don't have __typename, but have email + if (obj.email) { + return 'User' + } + return null + }, + }, + + // Type-specific author resolvers + Article: { + author: (parent: Article) => { + return users.find((u) => u.id === parent.authorId) || null + }, + }, + BlogPost: { + author: (parent: BlogPost) => { + return users.find((u) => u.id === parent.authorId) || null + }, }, + Page: { + author: (parent: Page) => { + return users.find((u) => u.id === parent.authorId) || null + }, + }, + User: { friends: () => { return [] diff --git a/playground/app/layouts/default.vue b/playground/app/layouts/default.vue index 839c80f..9b5d598 100644 --- a/playground/app/layouts/default.vue +++ b/playground/app/layouts/default.vue @@ -14,6 +14,27 @@