diff --git a/package.json b/package.json index c327794..bbef414 100644 --- a/package.json +++ b/package.json @@ -98,11 +98,19 @@ "peerDependencies": { "@apollo/server": "^5.0.0", "graphql": "^16.11.0", + "graphql-sse": "^2.6.0", + "graphql-ws": "^6.0.6", "nitro": "^3.0.1-alpha.0" }, "peerDependenciesMeta": { "@apollo/server": { "optional": true + }, + "graphql-sse": { + "optional": true + }, + "graphql-ws": { + "optional": true } }, "dependencies": { @@ -143,6 +151,8 @@ "crossws": "catalog:", "eslint": "catalog:", "graphql": "catalog:", + "graphql-sse": "catalog:", + "graphql-ws": "catalog:", "graphql-yoga": "catalog:", "nitro": "catalog:", "tsdown": "catalog:", diff --git a/playgrounds/apollo/package.json b/playgrounds/apollo/package.json index c455bf8..3ec3038 100644 --- a/playgrounds/apollo/package.json +++ b/playgrounds/apollo/package.json @@ -1,5 +1,5 @@ { - "name": "nitro-graphql-apollo", + "name": "apollo-playground", "private": true, "scripts": { "dev": "nitro dev", diff --git a/playgrounds/nitro/package.json b/playgrounds/nitro/package.json index 9119d91..caebecb 100644 --- a/playgrounds/nitro/package.json +++ b/playgrounds/nitro/package.json @@ -1,5 +1,5 @@ { - "name": "nitro-graphql-example", + "name": "nitro-playground", "private": true, "scripts": { "dev": "nitro dev", diff --git a/playgrounds/vite/package.json b/playgrounds/vite/package.json index 43d0358..a03a18d 100644 --- a/playgrounds/vite/package.json +++ b/playgrounds/vite/package.json @@ -1,5 +1,5 @@ { - "name": "nitro-app", + "name": "vite-playground", "type": "module", "private": true, "scripts": { diff --git a/playgrounds/vite/src/app.ts b/playgrounds/vite/src/app.ts index 78c9a13..1c96de5 100644 --- a/playgrounds/vite/src/app.ts +++ b/playgrounds/vite/src/app.ts @@ -75,7 +75,7 @@ export function setupApp(element: HTMLButtonElement) { graphqlLink.onmouseleave = () => graphqlLink.style.transform = 'scale(1)' const graphqlLogo = document.createElement('img') - graphqlLogo.src = 'https://graphql.org/img/logo.svg' + graphqlLogo.src = 'https://github.com/productdevbook/nitro-graphql/raw/main/.docs/public/logo.svg' graphqlLogo.alt = 'GraphQL' graphqlLogo.style.cssText = 'width: 48px; height: 48px; display: block;' graphqlLink.appendChild(graphqlLogo) @@ -83,7 +83,7 @@ export function setupApp(element: HTMLButtonElement) { logosContainer.append(nitroLink, viteLink, graphqlLink) const mainTitle = document.createElement('h1') - mainTitle.textContent = 'GraphQL Demo' + mainTitle.textContent = 'Nitro GraphQL Demo' mainTitle.style.cssText = styles.mainTitle leftPanel.append(logosContainer, mainTitle) diff --git a/playgrounds/webhook/.gitignore b/playgrounds/webhook/.gitignore new file mode 100644 index 0000000..d547d8a --- /dev/null +++ b/playgrounds/webhook/.gitignore @@ -0,0 +1,8 @@ +node_modules +dist +.data +.nitro +.cache +.output +.env +.env.local diff --git a/playgrounds/webhook/.prettierrc b/playgrounds/webhook/.prettierrc new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/playgrounds/webhook/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/playgrounds/webhook/README.md b/playgrounds/webhook/README.md new file mode 100644 index 0000000..e042f4e --- /dev/null +++ b/playgrounds/webhook/README.md @@ -0,0 +1,125 @@ +# Nitro + Vite + GraphQL + +A modern full-stack starter template combining [Vite](https://vitejs.dev/), [Nitro](https://v3.nitro.build/), and [GraphQL](https://github.com/productdevbook/nitro-graphql). + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/productdevbook/vite-nitro-graphql?file=server%2Fgraphql%2Fuser%2FgetUser.resolver.ts) + +## Features + +- ⚡ïļ **Vite** - Lightning fast frontend build tool +- 🚀 **Nitro** - Universal server framework +- 🔚 **GraphQL** - Type-safe API with [nitro-graphql](https://github.com/productdevbook/nitro-graphql) +- ðŸ“Ķ **TypeScript** - Full type safety +- ðŸŽĻ **Interactive Demo** - Built-in GraphQL playground +- ðŸŠķ **Lightweight** - Tree-shakeable, minimal bundle size +- 🌐 **Universal** - Deploy anywhere Nitro supports +- 🔄 **End-to-End Type Safety** - From GraphQL schema to client +- ðŸ“Ķ **Tiny Bundle** - Optimized by nitro-graphql's tree-shaking capabilities + +## Tech Stack + +- **Frontend**: Vite + TypeScript +- **Backend**: Nitro v3 +- **API**: GraphQL Yoga + nitro-graphql +- **Schema**: Code-first GraphQL with `.graphql` files + +## Getting Started + +### Install dependencies + +```bash +npm install +# or +pnpm install +``` + +### Development + +```bash +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) to see the interactive demo. + +### Build + +```bash +npm run build +``` + +### Preview + +```bash +npm run preview +``` + +## Project Structure + +``` +├── server/ +│ └── graphql/ +│ ├── config.ts # GraphQL configuration +│ ├── schema.ts # Schema definition +│ └── user/ +│ ├── user.graphql # User type schema +│ ├── getUser.resolver.ts +│ ├── createUser.resolver.ts +│ └── userStore.ts # Mock data +├── src/ +│ ├── main.ts # App entry point +│ └── app.ts # Demo UI +└── index.html +``` + +## GraphQL API + +The demo includes a simple User API with: + +### Queries + +```graphql +query GetUser($id: ID!) { + getUser(id: $id) { + id + email + name + createdAt + } +} +``` + +### Mutations + +```graphql +mutation CreateUser($input: CreateUserInput!) { + createUser(input: $input) { + id + email + name + createdAt + } +} +``` + +## Deployment + +This starter supports all Nitro deployment presets. Check the [Nitro deployment documentation](https://v3.nitro.build/deploy) for more details. + +```bash +# Build for production +npm run build + +# Deploy to your favorite platform +# Vercel, Netlify, Cloudflare Workers, AWS, etc. +``` + +## Learn More + +- [Vite Documentation](https://vitejs.dev/) +- [Nitro Documentation](https://v3.nitro.build/) +- [nitro-graphql](https://github.com/productdevbook/nitro-graphql) +- [GraphQL](https://graphql.org/) + +## License + +MIT diff --git a/playgrounds/webhook/graphql.config.ts b/playgrounds/webhook/graphql.config.ts new file mode 100644 index 0000000..87f5703 --- /dev/null +++ b/playgrounds/webhook/graphql.config.ts @@ -0,0 +1,14 @@ +import type { IGraphQLConfig } from 'graphql-config' + +export default { + projects: { + default: { + schema: [ + './.nitro/graphql/schema.graphql', + ], + documents: [ + './graphql/**/*.{graphql,js,ts,jsx,tsx}', + ], + }, + }, +} diff --git a/playgrounds/webhook/index.html b/playgrounds/webhook/index.html new file mode 100644 index 0000000..d34901e --- /dev/null +++ b/playgrounds/webhook/index.html @@ -0,0 +1,18 @@ + + + + + + + Nitro + Vite + GraphQL + + + +
+ + + diff --git a/playgrounds/webhook/package.json b/playgrounds/webhook/package.json new file mode 100644 index 0000000..1d888f4 --- /dev/null +++ b/playgrounds/webhook/package.json @@ -0,0 +1,21 @@ +{ + "name": "webhook-playground", + "type": "module", + "private": true, + "scripts": { + "build": "vite build", + "dev": "vite dev", + "preview": "vite preview" + }, + "dependencies": { + "@vitejs/devtools": "catalog:", + "graphql": "catalog:", + "graphql-ws": "catalog:", + "graphql-yoga": "catalog:", + "nitro-graphql": "link:../.." + }, + "devDependencies": { + "nitro": "catalog:", + "vite": "catalog:" + } +} diff --git a/playgrounds/webhook/public/nitro.svg b/playgrounds/webhook/public/nitro.svg new file mode 100644 index 0000000..cdeec33 --- /dev/null +++ b/playgrounds/webhook/public/nitro.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/playgrounds/webhook/public/vite.svg b/playgrounds/webhook/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/playgrounds/webhook/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playgrounds/webhook/server.ts b/playgrounds/webhook/server.ts new file mode 100644 index 0000000..38e3ef6 --- /dev/null +++ b/playgrounds/webhook/server.ts @@ -0,0 +1,5 @@ +export default { + fetch(req: Request) { + console.log(`[${req.method}] ${req.url}`) + }, +} diff --git a/playgrounds/webhook/server/api/hello.ts b/playgrounds/webhook/server/api/hello.ts new file mode 100644 index 0000000..6046ede --- /dev/null +++ b/playgrounds/webhook/server/api/hello.ts @@ -0,0 +1 @@ +export default () => 'API Works!' diff --git a/playgrounds/webhook/server/graphql/config.ts b/playgrounds/webhook/server/graphql/config.ts new file mode 100644 index 0000000..cdf0292 --- /dev/null +++ b/playgrounds/webhook/server/graphql/config.ts @@ -0,0 +1,16 @@ +// Example GraphQL config file please change it to your needs +// import * as tables from '../drizzle/schema/index' +// import { useDatabase } from '../utils/useDb' +import { defineGraphQLConfig } from 'nitro-graphql/define' + +export default defineGraphQLConfig({ +// graphql-yoga example config +// context: () => { +// return { +// context: { +// useDatabase, +// tables, +// }, +// } +// }, +}) diff --git a/playgrounds/webhook/server/graphql/context.d.ts b/playgrounds/webhook/server/graphql/context.d.ts new file mode 100644 index 0000000..0da95ab --- /dev/null +++ b/playgrounds/webhook/server/graphql/context.d.ts @@ -0,0 +1,18 @@ +// Example context definition - please change it to your needs +// import type { Database } from '../utils/useDb' + +declare module 'nitro/h3' { + interface H3EventContext { + // Add your custom context properties here + // useDatabase: () => Database + // tables: typeof import('../drizzle/schema') + // auth?: { + // user?: { + // id: string + // role: 'admin' | 'user' + // } + // } + } +} + +export {} diff --git a/playgrounds/webhook/server/graphql/schema.ts b/playgrounds/webhook/server/graphql/schema.ts new file mode 100644 index 0000000..a7c4552 --- /dev/null +++ b/playgrounds/webhook/server/graphql/schema.ts @@ -0,0 +1,3 @@ +export default defineSchema({ + +}) diff --git a/playgrounds/webhook/server/graphql/user/createUser.resolver.ts b/playgrounds/webhook/server/graphql/user/createUser.resolver.ts new file mode 100644 index 0000000..94a4fa3 --- /dev/null +++ b/playgrounds/webhook/server/graphql/user/createUser.resolver.ts @@ -0,0 +1,22 @@ +import { defineMutation } from 'nitro-graphql/define' +import { pubsub } from './pubsub' +import { mockUsers } from './userStore' + +export const data = defineMutation({ + createUser: (_parent, args) => { + const newUser = { + id: String(mockUsers.length + 1), + email: args.input.email, + name: args.input.name, + createdAt: new Date().toISOString(), + } + + mockUsers.push(newUser) + + // Publish event for subscription + pubsub.publish('USER_CREATED', newUser) + console.log('[Mutation] User created and published:', newUser.email) + + return newUser + }, +}) diff --git a/playgrounds/webhook/server/graphql/user/getUser.resolver.ts b/playgrounds/webhook/server/graphql/user/getUser.resolver.ts new file mode 100644 index 0000000..64ff66f --- /dev/null +++ b/playgrounds/webhook/server/graphql/user/getUser.resolver.ts @@ -0,0 +1,10 @@ +import { defineQuery } from 'nitro-graphql/define' +import { mockUsers } from './userStore' + +export const data = defineQuery({ + getUser: (_parent, args) => { + console.log(args) + const user = mockUsers.find(u => u.id === args.id) + return user || null + }, +}) diff --git a/playgrounds/webhook/server/graphql/user/pubsub.ts b/playgrounds/webhook/server/graphql/user/pubsub.ts new file mode 100644 index 0000000..5dc3007 --- /dev/null +++ b/playgrounds/webhook/server/graphql/user/pubsub.ts @@ -0,0 +1,74 @@ +import { EventEmitter } from 'node:events' + +// Simple in-memory PubSub implementation +class PubSub { + private emitter: EventEmitter + + constructor() { + this.emitter = new EventEmitter() + } + + publish(trigger: string, payload: any) { + this.emitter.emit(trigger, payload) + } + + subscribe(trigger: string): AsyncIterable { + const emitter = this.emitter + const listeners: Array<(value: any) => void> = [] + let listening = true + + const pullQueue: Array<(result: IteratorResult) => void> = [] + const pushQueue: any[] = [] + + const pushValue = (value: any) => { + if (pullQueue.length) { + pullQueue.shift()!({ value, done: false }) + } + else { + pushQueue.push(value) + } + } + + const pullValue = (): Promise> => { + return new Promise((resolve) => { + if (pushQueue.length) { + resolve({ value: pushQueue.shift()!, done: false }) + } + else { + pullQueue.push(resolve) + } + }) + } + + const handler = (data: any) => pushValue(data) + emitter.on(trigger, handler) + listeners.push(handler) + + return { + next: () => pullValue(), + return: async () => { + if (listening) { + listening = false + for (const listener of listeners) { + emitter.off(trigger, listener) + } + } + return { value: undefined, done: true } + }, + throw: async (error: any) => { + if (listening) { + listening = false + for (const listener of listeners) { + emitter.off(trigger, listener) + } + } + return Promise.reject(error) + }, + [Symbol.asyncIterator]() { + return this + }, + } + } +} + +export const pubsub = new PubSub() diff --git a/playgrounds/webhook/server/graphql/user/user.graphql b/playgrounds/webhook/server/graphql/user/user.graphql new file mode 100644 index 0000000..ce61ab5 --- /dev/null +++ b/playgrounds/webhook/server/graphql/user/user.graphql @@ -0,0 +1,23 @@ +type User { + id: ID! + email: String! + name: String + createdAt: String! +} + +input CreateUserInput { + email: String! + name: String +} + +type Query { + getUser(id: ID!): User +} + +type Mutation { + createUser(input: CreateUserInput!): User! +} + +type Subscription { + userCreated: User! +} \ No newline at end of file diff --git a/playgrounds/webhook/server/graphql/user/userCreated.resolver.ts b/playgrounds/webhook/server/graphql/user/userCreated.resolver.ts new file mode 100644 index 0000000..83df154 --- /dev/null +++ b/playgrounds/webhook/server/graphql/user/userCreated.resolver.ts @@ -0,0 +1,15 @@ +import { defineSubscription } from 'nitro-graphql/define' +import { pubsub } from './pubsub' + +export const userSubscriptions = defineSubscription({ + userCreated: { + subscribe: () => { + console.log('[Subscription] Client subscribed to userCreated') + return pubsub.subscribe('USER_CREATED') + }, + resolve: (payload) => { + console.log('[Subscription] Resolving payload:', payload) + return payload + }, + }, +}) diff --git a/playgrounds/webhook/server/graphql/user/userStore.ts b/playgrounds/webhook/server/graphql/user/userStore.ts new file mode 100644 index 0000000..90e8037 --- /dev/null +++ b/playgrounds/webhook/server/graphql/user/userStore.ts @@ -0,0 +1,20 @@ +// Mock user database - replace with actual database +export const mockUsers: Array<{ + id: string + email: string + name?: string + createdAt: string +}> = [ + { + id: '1', + email: 'user1@example.com', + name: 'John Doe', + createdAt: new Date().toISOString(), + }, + { + id: '2', + email: 'user2@example.com', + name: 'Jane Smith', + createdAt: new Date().toISOString(), + }, +] diff --git a/playgrounds/webhook/src/app.ts b/playgrounds/webhook/src/app.ts new file mode 100644 index 0000000..3d31808 --- /dev/null +++ b/playgrounds/webhook/src/app.ts @@ -0,0 +1,265 @@ +import { createClient } from 'graphql-ws' + +// GraphQL Query Helper +async function graphqlQuery(query: string, variables?: any) { + const res = await fetch('/api/graphql', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query, variables }), + }) + return res.json() +} + +// WebSocket Client for Subscriptions +const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' +const wsUrl = `${wsProtocol}//${window.location.host}/api/graphql/ws` + +const wsClient = createClient({ + url: wsUrl, + lazy: false, // Connect immediately + on: { + connected: () => console.log('[GraphQL WS] Connected'), + closed: () => console.log('[GraphQL WS] Disconnected'), + error: error => console.error('[GraphQL WS] Error:', error), + }, +}) + +console.log('[GraphQL WS] Client created with URL:', wsUrl) + +// Styles +const styles = { + container: 'display: flex; gap: 60px; padding: 40px; font-family: system-ui, -apple-system, sans-serif; min-height: 100vh; align-items: center;', + leftPanel: 'flex: 0 0 200px;', + rightPanel: 'flex: 1; max-width: 900px;', + + mainTitle: 'font-size: 36px; font-weight: 700; color: #222; margin: 0 0 8px 0; line-height: 1.2;', + subTitle: 'font-size: 14px; color: #999; margin: 0; font-weight: 400;', + + examples: 'margin-bottom: 20px;', + exampleTitle: 'font-size: 16px; color: #666; margin: 0 0 15px 0; font-weight: 500;', + + results: 'padding: 24px; background: #1e1e1e; border-radius: 10px; min-height: 200px; color: #e0e0e0; font-size: 14px; overflow-x: auto; line-height: 1.6;', + + buttons: 'display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 24px;', + button: 'padding: 14px 28px; cursor: pointer; color: white; border: none; border-radius: 8px; font-size: 15px; font-weight: 500; transition: all 0.2s; box-shadow: 0 2px 8px rgba(0,0,0,0.1);', +} + +export function setupApp(element: HTMLButtonElement) { + const container = document.createElement('div') + container.style.cssText = styles.container + + // Left Panel + const leftPanel = document.createElement('div') + leftPanel.style.cssText = styles.leftPanel + + // Logos Container + const logosContainer = document.createElement('div') + logosContainer.style.cssText = 'display: flex; gap: 16px; margin-bottom: 16px; align-items: center;' + + // Nitro Logo Link + const nitroLink = document.createElement('a') + nitroLink.href = 'https://v3.nitro.build' + nitroLink.target = '_blank' + nitroLink.style.cssText = 'transition: transform 0.2s;' + nitroLink.onmouseenter = () => nitroLink.style.transform = 'scale(1.1)' + nitroLink.onmouseleave = () => nitroLink.style.transform = 'scale(1)' + + const nitroLogo = document.createElement('img') + nitroLogo.src = '/nitro.svg' + nitroLogo.alt = 'Nitro' + nitroLogo.style.cssText = 'width: 48px; height: 48px; display: block;' + nitroLink.appendChild(nitroLogo) + + // Vite Logo Link + const viteLink = document.createElement('a') + viteLink.href = 'https://vitejs.dev' + viteLink.target = '_blank' + viteLink.style.cssText = 'transition: transform 0.2s;' + viteLink.onmouseenter = () => viteLink.style.transform = 'scale(1.1)' + viteLink.onmouseleave = () => viteLink.style.transform = 'scale(1)' + + const viteLogo = document.createElement('img') + viteLogo.src = '/vite.svg' + viteLogo.alt = 'Vite' + viteLogo.style.cssText = 'width: 48px; height: 48px; display: block;' + viteLink.appendChild(viteLogo) + + // GraphQL Logo Link + const graphqlLink = document.createElement('a') + graphqlLink.href = 'https://github.com/productdevbook/nitro-graphql' + graphqlLink.target = '_blank' + graphqlLink.style.cssText = 'transition: transform 0.2s;' + graphqlLink.onmouseenter = () => graphqlLink.style.transform = 'scale(1.1)' + graphqlLink.onmouseleave = () => graphqlLink.style.transform = 'scale(1)' + + const graphqlLogo = document.createElement('img') + graphqlLogo.src = 'https://github.com/productdevbook/nitro-graphql/raw/main/.docs/public/logo.svg' + graphqlLogo.alt = 'GraphQL' + graphqlLogo.style.cssText = 'width: 48px; height: 48px; display: block;' + graphqlLink.appendChild(graphqlLogo) + + logosContainer.append(nitroLink, viteLink, graphqlLink) + + const mainTitle = document.createElement('h1') + mainTitle.textContent = 'Nitro GraphQL Demo' + mainTitle.style.cssText = styles.mainTitle + + leftPanel.append(logosContainer, mainTitle) + + // Right Panel + const rightPanel = document.createElement('div') + rightPanel.style.cssText = styles.rightPanel + + // Examples Section + const examples = document.createElement('div') + examples.style.cssText = styles.examples + + const exampleTitle = document.createElement('h3') + exampleTitle.textContent = 'Examples' + exampleTitle.style.cssText = styles.exampleTitle + examples.appendChild(exampleTitle) + + // Buttons + const buttonsDiv = document.createElement('div') + buttonsDiv.style.cssText = styles.buttons + + // Results Display + const results = document.createElement('div') + results.style.cssText = styles.results + results.innerHTML = 'Click a button to see results...' + + // Helper Functions + const showResult = (data: any, label: string, color: string) => { + results.innerHTML = ` +
✓ ${label}
+
${JSON.stringify(data, null, 2)}
+ ` + } + + const showError = (error: any) => { + results.innerHTML = ` +
✗ Error
+
${error}
+ ` + } + + const createButton = (text: string, color: string, onClick: () => void) => { + const btn = document.createElement('button') + btn.textContent = text + btn.style.cssText = `${styles.button}; background: ${color};` + btn.onmouseenter = () => btn.style.transform = 'translateY(-2px)' + btn.onmouseleave = () => btn.style.transform = 'translateY(0)' + btn.onclick = onClick + buttonsDiv.appendChild(btn) + } + + // Buttons + createButton('Get User', '#10b981', async () => { + try { + results.innerHTML = 'Loading...' + const data = await graphqlQuery(` + query GetUser($id: ID!) { + getUser(id: $id) { id email name createdAt } + } + `, { id: '1' }) + showResult(data, 'Query Result', '#10b981') + } + catch (error) { + showError(error) + } + }) + + createButton('Create User', '#3b82f6', async () => { + try { + results.innerHTML = 'Creating...' + const randomId = Math.floor(Math.random() * 10000) + const data = await graphqlQuery(` + mutation CreateUser($input: CreateUserInput!) { + createUser(input: $input) { id email name createdAt } + } + `, { + input: { + email: `user${randomId}@example.com`, + name: `Demo User ${randomId}`, + }, + }) + showResult(data, 'Mutation Result', '#3b82f6') + } + catch (error) { + showError(error) + } + }) + + createButton('Get All Users', '#f59e0b', async () => { + try { + results.innerHTML = 'Loading...' + const users = await Promise.all([ + graphqlQuery(`query { getUser(id: "1") { id email name createdAt } }`), + graphqlQuery(`query { getUser(id: "2") { id email name createdAt } }`), + ]) + showResult(users, 'All Users', '#f59e0b') + } + catch (error) { + showError(error) + } + }) + + let subscriptionUnsubscribe: (() => void) | null = null + + createButton('Subscribe to User Created', '#8b5cf6', () => { + if (subscriptionUnsubscribe) { + subscriptionUnsubscribe() + subscriptionUnsubscribe = null + results.innerHTML = '
✗ Unsubscribed from user created events
' + return + } + + results.innerHTML = '
⚡ Subscribed! Waiting for new users...
' + + subscriptionUnsubscribe = wsClient.subscribe( + { + query: ` + subscription { + userCreated { + id + email + name + createdAt + } + } + `, + }, + { + next: (result: any) => { + if (result.data) { + const timestamp = new Date().toLocaleTimeString() + const currentContent = results.innerHTML + results.innerHTML = ` +
⚡ New User Created (${timestamp})
+
${JSON.stringify(result.data.userCreated, null, 2)}
+ ${currentContent.includes('Subscribed!') ? '' : currentContent} + ` + } + }, + error: (error: any) => { + console.error('[Subscription] Error:', error) + results.innerHTML = ` +
✗ Subscription Error
+
${error.message || error}
+ ` + subscriptionUnsubscribe = null + }, + complete: () => { + console.log('[Subscription] Complete') + subscriptionUnsubscribe = null + }, + }, + ) + }) + + // Assemble + examples.appendChild(buttonsDiv) + rightPanel.append(examples, results) + container.append(leftPanel, rightPanel) + element.appendChild(container) +} diff --git a/playgrounds/webhook/src/assets/main.css b/playgrounds/webhook/src/assets/main.css new file mode 100644 index 0000000..32cef36 --- /dev/null +++ b/playgrounds/webhook/src/assets/main.css @@ -0,0 +1,96 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #ff2056; + text-decoration: inherit; +} +a:hover { + color: #ff637e; +} + +body { + margin: 0; + display: flex; + flex-direction: column; + place-items: center; + justify-content: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; + transition: transform 300ms; +} +.logo:hover { + transform: scale(1.1); +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/playgrounds/webhook/src/main.ts b/playgrounds/webhook/src/main.ts new file mode 100644 index 0000000..0962fff --- /dev/null +++ b/playgrounds/webhook/src/main.ts @@ -0,0 +1,3 @@ +import { setupApp } from './app' + +setupApp(document.querySelector('#app')!) diff --git a/playgrounds/webhook/tsconfig.json b/playgrounds/webhook/tsconfig.json new file mode 100644 index 0000000..a5c3c82 --- /dev/null +++ b/playgrounds/webhook/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + // Module resolution + "target": "ESNext", + // JSX + "jsx": "preserve", + "jsxFactory": "h", + "jsxFragmentFactory": "Fragment", + "module": "ESNext", + "moduleResolution": "Bundler", + "paths": { + "#graphql/server": [ + "./node_modules/.nitro/types/nitro-graphql-server.d.ts" + ], + "#graphql/client": [ + "./node_modules/.nitro/types/nitro-graphql-client.d.ts" + ], + "#graphql/schema": [ + "./server/graphql/schema.ts" + ] + }, + "resolveJsonModule": true, + "types": [ + "nitro-graphql" + ], + // Core checks + "strict": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "useUnknownInCatchVariables": true, + "noEmit": true, + "allowSyntheticDefaultImports": true, + // Additional safety + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true + } +} diff --git a/playgrounds/webhook/vite.config.ts b/playgrounds/webhook/vite.config.ts new file mode 100644 index 0000000..0e1ff4a --- /dev/null +++ b/playgrounds/webhook/vite.config.ts @@ -0,0 +1,23 @@ +import graphql from 'nitro-graphql' +import { nitro } from 'nitro/vite' +import { defineConfig } from 'vite' + +export default defineConfig(({ command }) => ({ + plugins: [ + graphql({ + framework: 'graphql-yoga', + paths: { + serverGraphql: 'server/graphql', + }, + subscriptions: { + enabled: true, + protocol: 'graphql-ws', + }, + }), + nitro(), + ], + nitro: { + preset: 'standard', + serverDir: './server', + }, +})) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 227b424..1dfe946 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,6 +15,9 @@ catalogs: '@apollo/subgraph': specifier: ^2.12.1 version: 2.12.1 + '@better-auth/cli': + specifier: ^1.4.5 + version: 1.4.5 '@graphql-codegen/core': specifier: ^5.0.0 version: 5.0.0 @@ -60,15 +63,45 @@ catalogs: '@nuxt/schema': specifier: ^4.2.1 version: 4.2.1 + '@pinia/colada': + specifier: ^0.18.0 + version: 0.18.0 + '@tailwindcss/vite': + specifier: ^4.1.17 + version: 4.1.17 + '@tanstack/react-query': + specifier: ^5.90.12 + version: 5.90.12 '@types/node': specifier: ^24.10.1 version: 24.10.1 + '@types/pg': + specifier: ^8.15.6 + version: 8.15.6 + '@types/react': + specifier: ^19.2.7 + version: 19.2.7 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3 '@vitejs/devtools': specifier: ^0.0.0-alpha.16 version: 0.0.0-alpha.18 + '@vitejs/plugin-react': + specifier: ^5.1.1 + version: 5.1.1 + '@vitejs/plugin-vue': + specifier: ^6.0.2 + version: 6.0.2 '@vitest/ui': specifier: ^4.0.15 version: 4.0.15 + '@vue/tsconfig': + specifier: ^0.8.1 + version: 0.8.1 + better-auth: + specifier: ^1.4.5 + version: 1.4.5 bumpp: specifier: ^10.3.2 version: 10.3.2 @@ -87,6 +120,15 @@ catalogs: defu: specifier: ^6.1.4 version: 6.1.4 + drizzle-kit: + specifier: ^0.31.8 + version: 0.31.8 + drizzle-orm: + specifier: ^0.45.0 + version: 0.45.0 + drizzle-zod: + specifier: ^0.8.3 + version: 0.8.3 eslint: specifier: ^9.39.1 version: 9.39.1 @@ -99,12 +141,24 @@ catalogs: graphql-scalars: specifier: ^1.25.0 version: 1.25.0 + graphql-sse: + specifier: ^2.6.0 + version: 2.6.0 + graphql-ws: + specifier: 6.0.6 + version: 6.0.6 graphql-yoga: specifier: 5.16.2 version: 5.16.2 knitwork: specifier: ^1.3.0 version: 1.3.0 + nitro: + specifier: npm:nitro-nightly@latest + version: 3.0.1-20251211-001255-afcf27ad + ofetch: + specifier: ^1.5.1 + version: 1.5.1 ohash: specifier: ^2.0.11 version: 2.0.11 @@ -114,29 +168,66 @@ catalogs: pathe: specifier: ^2.0.3 version: 2.0.3 + pg: + specifier: ^8.16.3 + version: 8.16.3 + pinia: + specifier: ^3.0.4 + version: 3.0.4 + react: + specifier: ^19.2.1 + version: 19.2.1 + react-dom: + specifier: ^19.2.1 + version: 19.2.1 + react-router-dom: + specifier: ^7.10.1 + version: 7.10.1 + rolldown: + specifier: ^1.0.0-beta.53 + version: 1.0.0-beta.53 + tailwindcss: + specifier: ^4.1.17 + version: 4.1.17 tinyglobby: specifier: ^0.2.15 version: 0.2.15 tsdown: specifier: ^0.17.0 version: 0.17.0 + tsx: + specifier: ^4.21.0 + version: 4.21.0 typescript: specifier: ^5.9.3 version: 5.9.3 + uuid: + specifier: ^13.0.0 + version: 13.0.0 + vite: + specifier: 8.0.0-beta.0 + version: 8.0.0-beta.0 vitepress-plugin-llms: specifier: ^1.9.3 version: 1.9.3 vitest: specifier: ^4.0.15 version: 4.0.15 + vue: + specifier: ^3.5.25 + version: 3.5.25 + vue-router: + specifier: ^4.6.3 + version: 4.6.3 + vue-tsc: + specifier: ^3.1.6 + version: 3.1.6 zod: specifier: ^4.1.13 version: 4.1.13 overrides: nitro-graphql: link:. - nitro: npm:nitro-nightly@latest - vite: 8.0.0-beta.0 importers: @@ -183,7 +274,7 @@ importers: version: 10.0.30(graphql@16.12.0) '@graphql-tools/url-loader': specifier: 'catalog:' - version: 9.0.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0) + version: 9.0.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0) '@graphql-tools/utils': specifier: 'catalog:' version: 10.11.0(graphql@16.12.0) @@ -198,16 +289,13 @@ importers: version: 6.1.4 graphql-config: specifier: 'catalog:' - version: 5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)(typescript@5.9.3) + version: 5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(typescript@5.9.3) graphql-scalars: specifier: 'catalog:' version: 1.25.0(graphql@16.12.0) knitwork: specifier: 'catalog:' version: 1.3.0 - nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@5.0.0)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) ohash: specifier: 'catalog:' version: 2.0.11 @@ -247,16 +335,25 @@ importers: version: 0.6.2 crossws: specifier: 'catalog:' - version: 0.4.1(srvx@0.9.6) + version: 0.4.1(srvx@0.9.8) eslint: specifier: 'catalog:' version: 9.39.1(jiti@2.6.1) graphql: specifier: 'catalog:' version: 16.12.0 + graphql-sse: + specifier: 'catalog:' + version: 2.6.0(graphql@16.12.0) + graphql-ws: + specifier: 'catalog:' + version: 6.0.6(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(ws@8.18.3) graphql-yoga: specifier: 'catalog:' version: 5.16.2(graphql@16.12.0) + nitro: + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@5.0.0)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) tsdown: specifier: 'catalog:' version: 0.17.0(@vitejs/devtools@0.0.0-alpha.18(@pnpm/logger@1001.0.1)(db0@0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)))(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)))(publint@0.3.15)(synckit@0.11.11)(typescript@5.9.3)(vue-tsc@3.1.6(typescript@5.9.3)) @@ -264,244 +361,244 @@ importers: specifier: 'catalog:' version: 5.9.3 vite: - specifier: 8.0.0-beta.0 + specifier: 'catalog:' version: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) vitepress-plugin-llms: specifier: 'catalog:' version: 1.9.3 vitest: specifier: 'catalog:' - version: 4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) examples/better-auth: devDependencies: '@better-auth/cli': - specifier: ^1.4.5 + specifier: 'catalog:' version: 1.4.5(@better-fetch/fetch@1.1.18)(@types/better-sqlite3@7.6.13)(@types/react@19.2.7)(better-call@1.1.4(zod@4.1.13))(jose@6.1.2)(kysely@0.28.8)(nanostores@1.1.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vue@3.5.25(typescript@5.9.3)) '@graphql-tools/utils': - specifier: ^10.11.0 + specifier: 'catalog:' version: 10.11.0(graphql@16.12.0) '@types/pg': - specifier: ^8.15.6 + specifier: 'catalog:' version: 8.15.6 better-auth: - specifier: ^1.4.5 + specifier: 'catalog:' version: 1.4.5(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vue@3.5.25(typescript@5.9.3)) drizzle-kit: - specifier: ^0.31.8 + specifier: 'catalog:' version: 0.31.8 drizzle-orm: - specifier: ^0.45.0 + specifier: 'catalog:' version: 0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0) drizzle-zod: - specifier: ^0.8.3 + specifier: 'catalog:' version: 0.8.3(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(zod@4.1.13) graphql: - specifier: ^16.12.0 + specifier: 'catalog:' version: 16.12.0 graphql-yoga: - specifier: ^5.17.1 - version: 5.17.1(graphql@16.12.0) + specifier: 'catalog:' + version: 5.16.2(graphql@16.12.0) nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) nitro-graphql: specifier: link:../.. version: link:../.. pg: - specifier: ^8.16.3 + specifier: 'catalog:' version: 8.16.3 rolldown: - specifier: ^1.0.0-beta.53 + specifier: 'catalog:' version: 1.0.0-beta.53 tsx: - specifier: ^4.21.0 + specifier: 'catalog:' version: 4.21.0 uuid: - specifier: ^13.0.0 + specifier: 'catalog:' version: 13.0.0 zod: - specifier: ^4.1.13 + specifier: 'catalog:' version: 4.1.13 examples/drizzle-orm: devDependencies: '@types/pg': - specifier: ^8.15.6 + specifier: 'catalog:' version: 8.15.6 drizzle-kit: - specifier: ^0.31.8 + specifier: 'catalog:' version: 0.31.8 drizzle-orm: - specifier: ^0.45.0 + specifier: 'catalog:' version: 0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0) drizzle-zod: - specifier: ^0.8.3 + specifier: 'catalog:' version: 0.8.3(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(zod@4.1.13) graphql: - specifier: ^16.12.0 + specifier: 'catalog:' version: 16.12.0 graphql-yoga: - specifier: ^5.17.1 - version: 5.17.1(graphql@16.12.0) + specifier: 'catalog:' + version: 5.16.2(graphql@16.12.0) nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) nitro-graphql: specifier: link:../.. version: link:../.. pg: - specifier: ^8.16.3 + specifier: 'catalog:' version: 8.16.3 rolldown: - specifier: ^1.0.0-beta.53 + specifier: 'catalog:' version: 1.0.0-beta.53 tsx: - specifier: ^4.21.0 + specifier: 'catalog:' version: 4.21.0 uuid: - specifier: ^13.0.0 + specifier: 'catalog:' version: 13.0.0 zod: - specifier: ^4.1.13 + specifier: 'catalog:' version: 4.1.13 examples/vite: dependencies: graphql: - specifier: ^16.12.0 + specifier: 'catalog:' version: 16.12.0 graphql-yoga: - specifier: ^5.17.1 - version: 5.17.1(graphql@16.12.0) + specifier: 'catalog:' + version: 5.16.2(graphql@16.12.0) nitro-graphql: specifier: link:../.. version: link:../.. rolldown: - specifier: ^1.0.0-beta.53 + specifier: 'catalog:' version: 1.0.0-beta.53 devDependencies: nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) vite: - specifier: 8.0.0-beta.0 + specifier: 'catalog:' version: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) examples/vite-react: dependencies: '@tailwindcss/vite': - specifier: ^4.1.17 + specifier: 'catalog:' version: 4.1.17(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) '@tanstack/react-query': - specifier: ^5.90.12 + specifier: 'catalog:' version: 5.90.12(react@19.2.1) graphql: - specifier: ^16.12.0 + specifier: 'catalog:' version: 16.12.0 graphql-yoga: - specifier: ^5.17.1 - version: 5.17.1(graphql@16.12.0) + specifier: 'catalog:' + version: 5.16.2(graphql@16.12.0) nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) nitro-graphql: specifier: link:../.. version: link:../.. ofetch: - specifier: ^1.5.1 + specifier: 'catalog:' version: 1.5.1 react: - specifier: ^19.2.1 + specifier: 'catalog:' version: 19.2.1 react-dom: - specifier: ^19.2.1 + specifier: 'catalog:' version: 19.2.1(react@19.2.1) react-router-dom: - specifier: ^7.10.1 + specifier: 'catalog:' version: 7.10.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1) tailwindcss: - specifier: ^4.1.17 + specifier: 'catalog:' version: 4.1.17 devDependencies: '@types/node': - specifier: ^24.10.1 + specifier: 'catalog:' version: 24.10.1 '@types/react': - specifier: ^19.2.7 + specifier: 'catalog:' version: 19.2.7 '@types/react-dom': - specifier: ^19.2.3 + specifier: 'catalog:' version: 19.2.3(@types/react@19.2.7) '@vitejs/plugin-react': - specifier: ^5.1.1 + specifier: 'catalog:' version: 5.1.1(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) graphql-config: - specifier: ^5.1.5 - version: 5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)(typescript@5.9.3) + specifier: 'catalog:' + version: 5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(typescript@5.9.3) typescript: - specifier: ^5.9.3 + specifier: 'catalog:' version: 5.9.3 vite: - specifier: 8.0.0-beta.0 + specifier: 'catalog:' version: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) examples/vite-vue: dependencies: '@pinia/colada': - specifier: ^0.18.0 + specifier: 'catalog:' version: 0.18.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) '@tailwindcss/vite': - specifier: ^4.1.17 + specifier: 'catalog:' version: 4.1.17(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) graphql: - specifier: ^16.12.0 + specifier: 'catalog:' version: 16.12.0 graphql-yoga: - specifier: ^5.17.1 - version: 5.17.1(graphql@16.12.0) + specifier: 'catalog:' + version: 5.16.2(graphql@16.12.0) nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) nitro-graphql: specifier: link:../.. version: link:../.. ofetch: - specifier: ^1.5.1 + specifier: 'catalog:' version: 1.5.1 pinia: - specifier: ^3.0.4 + specifier: 'catalog:' version: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) tailwindcss: - specifier: ^4.1.17 + specifier: 'catalog:' version: 4.1.17 vue: - specifier: ^3.5.25 + specifier: 'catalog:' version: 3.5.25(typescript@5.9.3) vue-router: - specifier: ^4.6.3 + specifier: 'catalog:' version: 4.6.3(vue@3.5.25(typescript@5.9.3)) devDependencies: '@types/node': - specifier: ^24.10.1 + specifier: 'catalog:' version: 24.10.1 '@vitejs/plugin-vue': - specifier: ^6.0.2 + specifier: 'catalog:' version: 6.0.2(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) '@vue/tsconfig': - specifier: ^0.8.1 + specifier: 'catalog:' version: 0.8.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) graphql-config: - specifier: ^5.1.5 - version: 5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)(typescript@5.9.3) + specifier: 'catalog:' + version: 5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(typescript@5.9.3) typescript: - specifier: ^5.9.3 + specifier: 'catalog:' version: 5.9.3 vite: - specifier: 8.0.0-beta.0 + specifier: 'catalog:' version: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) vue-tsc: - specifier: ^3.1.6 + specifier: 'catalog:' version: 3.1.6(typescript@5.9.3) playgrounds/apollo: @@ -520,8 +617,8 @@ importers: version: 4.1.13 devDependencies: nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) playgrounds/federation: dependencies: @@ -535,8 +632,8 @@ importers: specifier: 'catalog:' version: 16.12.0 nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) nitro-graphql: specifier: link:../.. version: link:../.. @@ -554,8 +651,8 @@ importers: version: 4.1.13 devDependencies: nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) playgrounds/vite: dependencies: @@ -573,10 +670,35 @@ importers: version: link:../.. devDependencies: nitro: - specifier: npm:nitro-nightly@latest - version: nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) vite: - specifier: 8.0.0-beta.0 + specifier: 'catalog:' + version: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + + playgrounds/webhook: + dependencies: + '@vitejs/devtools': + specifier: 'catalog:' + version: 0.0.0-alpha.18(@pnpm/logger@1001.0.1)(db0@0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)))(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + graphql: + specifier: 'catalog:' + version: 16.12.0 + graphql-ws: + specifier: 'catalog:' + version: 6.0.6(crossws@0.3.5)(graphql@16.12.0)(ws@8.18.3) + graphql-yoga: + specifier: 'catalog:' + version: 5.16.2(graphql@16.12.0) + nitro-graphql: + specifier: link:../.. + version: link:../.. + devDependencies: + nitro: + specifier: 'catalog:' + version: nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + vite: + specifier: 'catalog:' version: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -1835,12 +1957,6 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@graphql-tools/executor@1.5.0': - resolution: {integrity: sha512-3HzAxfexmynEWwRB56t/BT+xYKEYLGPvJudR1jfs+XZX8bpfqujEhqVFoxmkpEE8BbFcKuBNoQyGkTi1eFJ+hA==} - engines: {node: '>=16.0.0'} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@graphql-tools/graphql-file-loader@8.1.8': resolution: {integrity: sha512-dZi9Cw+NWEzJAqzIUON9qjZfjebjcoT4H6jqLkEoAv6kRtTq52m4BLXgFWjMHU7PNLE9OOHB9St7UeZQL+GYrw==} engines: {node: '>=16.0.0'} @@ -2051,91 +2167,91 @@ packages: resolution: {integrity: sha512-kSuma7UztDVyw8eAmN3rKFoaWjNRkJE9+kqwEurpuxG7nCwFPS7sUPSGzovzaofP+xV30tl6wveBEcDRWyQvgA==} engines: {node: ^14.18.0 || >=16.10.0} - '@oxc-minify/binding-android-arm64@0.97.0': - resolution: {integrity: sha512-2bv8ZKm53PKJ7+0o7X813um9lRJ/EYjFyf09x2Q7OKfOLiAcWrFoLWmO5PJcCMpf+V2EFTp9UuapHzocuShBgw==} + '@oxc-minify/binding-android-arm64@0.102.0': + resolution: {integrity: sha512-pknM+ttJTwRr7ezn1v5K+o2P4RRjLAzKI10bjVDPybwWQ544AZW6jxm7/YDgF2yUbWEV9o7cAQPkIUOmCiW8vg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-minify/binding-darwin-arm64@0.97.0': - resolution: {integrity: sha512-NlFViKlJawMD7GTLlSyG1RaYOLzqpM8pEw7oTzR9Si/kPaScgsB6E+F1d3AFPl7fmOG7iIxvhdI+ftlMZmniVA==} + '@oxc-minify/binding-darwin-arm64@0.102.0': + resolution: {integrity: sha512-BDLiH41ZctNND38+GCEL3ZxFn9j7qMZJLrr6SLWMt8xlG4Sl64xTkZ0zeUy4RdVEatKKZdrRIhFZ2e5wPDQT6Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-minify/binding-darwin-x64@0.97.0': - resolution: {integrity: sha512-IVzkLjz/Cv45GV9e3a5cFyRn0k+3b84JKKCLjXNsrZ+4MfRdqtGWMfibz3fq8zzvWBU/oaAoNseyWhl12HACPw==} + '@oxc-minify/binding-darwin-x64@0.102.0': + resolution: {integrity: sha512-AcB8ZZ711w4hTDhMfMHNjT2d+hekTQ2XmNSUBqJdXB+a2bJbE50UCRq/nxXl44zkjaQTit3lcQbFvhk2wwKcpw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-minify/binding-freebsd-x64@0.97.0': - resolution: {integrity: sha512-uMPakX5o7/MuvJ0uvgahDAMBIHFjMQ7ecrOing6zpnhqhJpLH6y2aMbFn9I0IlrCYTWPaEdmskGMUYKi031X4g==} + '@oxc-minify/binding-freebsd-x64@0.102.0': + resolution: {integrity: sha512-UlLEN9mR5QaviYVMWZQsN9DgAH3qyV67XUXDEzSrbVMLsqHsVHhFU8ZIeO0fxWTQW/cgpvldvKp9/+RdrggqWw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-minify/binding-linux-arm-gnueabihf@0.97.0': - resolution: {integrity: sha512-132F111xtBpPQSN0gkWa2fp8bkpCVJzki0HWp+943Sy0c5muAE0OkZM8UYgPbE9VfyinuG2awawiheWk9QFeyA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxc-minify/binding-linux-arm-musleabihf@0.97.0': - resolution: {integrity: sha512-96flfOczSQNr3EzhPRjRdgfF07pXTdcZdKE1xnmqn1X7t0O5czUI3LEf5BTSU3NJohg1lwpdk8fANNLBIqjqjw==} + '@oxc-minify/binding-linux-arm-gnueabihf@0.102.0': + resolution: {integrity: sha512-CWyCwedZrUt47n56/RwHSwKXxVI3p98hB0ntLaBNeH5qjjBujs9uOh4bQ0aAlzUWunT77b3/Y+xcQnmV42HN4A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-minify/binding-linux-arm64-gnu@0.97.0': - resolution: {integrity: sha512-ojC0lP/uZm4yzL+t/Y1iCNkOv3ADe1csHpGP49lG+M8zCyWTNfJZTgBxA9GO/gGoVzBQ0lcytdVbXLx9WtG3NA==} + '@oxc-minify/binding-linux-arm64-gnu@0.102.0': + resolution: {integrity: sha512-W/DCw+Ys8rXj4j38ylJ2l6Kvp6SV+eO5SUWA11imz7yCWntNL001KJyGQ9PJNUFHg0jbxe3yqm4M50v6miWzeA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxc-minify/binding-linux-arm64-musl@0.97.0': - resolution: {integrity: sha512-RU/XPyPoLUZnlu0yKyjhd9RhDtA9br6SfkdDZo+/vKEYZ7H2YQdMrSix1rYQIV9usPN0oBVHN/r0RKclAu2K+Q==} + '@oxc-minify/binding-linux-arm64-musl@0.102.0': + resolution: {integrity: sha512-DyH/t/zSZHuX4Nn239oBteeMC4OP7B13EyXWX18Qg8aJoZ+lZo90WPGOvhP04zII33jJ7di+vrtAUhsX64lp+A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxc-minify/binding-linux-riscv64-gnu@0.97.0': - resolution: {integrity: sha512-YuV2MmzulecouWxVAsTdkHtlLNtBfNG+lbMVgHjQeFgo+bGMD2GcmyVFQ29hsBgemeLXMm7xxn/4/xnQlqKZ5w==} + '@oxc-minify/binding-linux-riscv64-gnu@0.102.0': + resolution: {integrity: sha512-CMvzrmOg+Gs44E7TRK/IgrHYp+wwVJxVV8niUrDR2b3SsrCO3NQz5LI+7bM1qDbWnuu5Cl1aiitoMfjRY61dSg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxc-minify/binding-linux-s390x-gnu@0.97.0': - resolution: {integrity: sha512-C8Z3FWEcLfEdf/OEA6gLYBW45skFeQE3fIr/9eqri8ncDoKQ0ArMSrtIkLC3gyJCWNoZZArLUj1eTGiSS1HJNw==} + '@oxc-minify/binding-linux-s390x-gnu@0.102.0': + resolution: {integrity: sha512-tZWr6j2s0ddm9MTfWTI3myaAArg9GDy4UgvpF00kMQAjLcGUNhEEQbB9Bd9KtCvDQzaan8HQs0GVWUp+DWrymw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxc-minify/binding-linux-x64-gnu@0.97.0': - resolution: {integrity: sha512-4RMxc/CY+5bWdn/5oYjWKji/q2FVQ6kl9LBeGhbAbS/GlH5T1/uhK8qg7HlYt5Sh3K+z6yxBcgZh+0wF7wnbWg==} + '@oxc-minify/binding-linux-x64-gnu@0.102.0': + resolution: {integrity: sha512-0YEKmAIun1bS+Iy5Shx6WOTSj3GuilVuctJjc5/vP8/EMTZ/RI8j0eq0Mu3UFPoT/bMULL3MBXuHuEIXmq7Ddg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxc-minify/binding-linux-x64-musl@0.97.0': - resolution: {integrity: sha512-ABrWgMvZLaZhh4aq5hX9aKR4dlE4erB2ypE1ZonTPHa1/uA5r7d0uyQq6gC2AcZsjXziPhdJVdykvY1/Xo5azg==} + '@oxc-minify/binding-linux-x64-musl@0.102.0': + resolution: {integrity: sha512-Ew4QDpEsXoV+pG5+bJpheEy3GH436GBe6ASPB0X27Hh9cQ2gb1NVZ7cY7xJj68+fizwS/PtT8GHoG3uxyH17Pg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxc-minify/binding-wasm32-wasi@0.97.0': - resolution: {integrity: sha512-I8VNYDzmLTOqEIxisGzeE/3MKTNYK0tuc5bENBPLEWzO3wTti8Ol0+o/2ytJJ+9whXUbHibGIUdBlvZnyDqt2g==} + '@oxc-minify/binding-openharmony-arm64@0.102.0': + resolution: {integrity: sha512-wYPXS8IOu/sXiP3CGHJNPzZo4hfPAwJKevcFH2syvU2zyqUxym7hx6smfcK/mgJBiX7VchwArdGRwrEQKcBSaQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-minify/binding-wasm32-wasi@0.102.0': + resolution: {integrity: sha512-52SepCb9e+8cVisGa9S/F14K8PxW0AnbV1j4KEYi8uwfkUIxeDNKRHVHzPoBXNrr0yxW0EHLn/3i8J7a2YCpWw==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-minify/binding-win32-arm64-msvc@0.97.0': - resolution: {integrity: sha512-hwoy2tQLQUODXoHGIp3eYs67+jxn6bZ0bU4eZPfpkPYQQBaM5Oxrr/GAT/GRRlIilM4JqPgBBq1+lODPYbtiSQ==} + '@oxc-minify/binding-win32-arm64-msvc@0.102.0': + resolution: {integrity: sha512-kLs6H1y6sDBKcIimkNwu5th28SLkyvFpHNxdLtCChda0KIGeIXNSiupy5BqEutY+VlWJivKT1OV3Ev3KC5Euzg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-minify/binding-win32-x64-msvc@0.97.0': - resolution: {integrity: sha512-BxO9cCEN78P/w4HTLSIEoUsTGN4v9Qr90ZbBJ1N4HqNhx8PRr5jVm31w6j/jcWtBEr1DxlRkXFTDsaiyH8MDww==} + '@oxc-minify/binding-win32-x64-msvc@0.102.0': + resolution: {integrity: sha512-XdyJZdSMN8rbBXH10CrFuU+Q9jIP2+MnxHmNzjK4+bldbTI1UxqwjUMS9bKVC5VCaIEZhh8IE8x4Vf8gmCgrKQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2236,91 +2352,91 @@ packages: '@oxc-project/types@0.101.0': resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==} - '@oxc-transform/binding-android-arm64@0.97.0': - resolution: {integrity: sha512-gZgdFI/F5aDdDyLNo2EQBYP6PZ8Q4cWbGdgGKvrHGLr2yKVTIJ8gE3m9mVOCvb2KNS15vmXwtEsOcsac18pg/Q==} + '@oxc-transform/binding-android-arm64@0.102.0': + resolution: {integrity: sha512-JLBT7EiExsGmB6LuBBnm6qTfg0rLSxBU+F7xjqy6UXYpL7zhqelGJL7IAq6Pu5UYFT55zVlXXmgzLOXQfpQjXA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-transform/binding-darwin-arm64@0.97.0': - resolution: {integrity: sha512-6JTUuHmh3IOmUbDj61cYkxemBYmMK9Qa2gwQPz0/k2DNUzXKO7c9VC8LHnPEAdNovQH5OBsskNa63zuo2rPzjQ==} + '@oxc-transform/binding-darwin-arm64@0.102.0': + resolution: {integrity: sha512-xmsBCk/NwE0khy8h6wLEexiS5abCp1ZqJUNHsAovJdGgIW21oGwhiC3VYg1vNLbq+zEXwOHuphVuNEYfBwyNTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-transform/binding-darwin-x64@0.97.0': - resolution: {integrity: sha512-xU3uoBd4sR+9oilAl1OafDeDJljaZ9Jw1JPBnP9D1ZobfEJaxaQlr81VZdzHmu3lTfuUhBTd1ChGU5WFvmrwiw==} + '@oxc-transform/binding-darwin-x64@0.102.0': + resolution: {integrity: sha512-EhBsiq8hSd5BRjlWACB9MxTUiZT2He1s1b3tRP8k3lB8ZTt6sXnDXIWhxRmmM0h//xe6IJ2HuMlbvjXPo/tATg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-transform/binding-freebsd-x64@0.97.0': - resolution: {integrity: sha512-AsYVHk2Aq4AzgxAxkqceGzUsVdfoUDgGX2tQc/O2fNhKSnO5297mW/06AJExNbSxZfP/S85iaeTVGqTGr1v6Gw==} + '@oxc-transform/binding-freebsd-x64@0.102.0': + resolution: {integrity: sha512-eujvuYf0x7BFgKyFecbXUa2JBEXT4Ss6vmyrrhVdN07jaeJRiobaKAmeNXBkanoWL2KQLELJbSBgs1ykWYTkzg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-transform/binding-linux-arm-gnueabihf@0.97.0': - resolution: {integrity: sha512-06prLOa1wQc/vJRsCIUYLkr0YShkl1lvGkTJK3Ygg8RB4SpYUkCZEmCFAdilg8SkI1mLr3rxSvlY8SicH0vLdw==} + '@oxc-transform/binding-linux-arm-gnueabihf@0.102.0': + resolution: {integrity: sha512-2x7Ro356PHBVp1SS/dOsHBSnrfs5MlPYwhdKg35t6qixt2bv1kzEH0tDmn4TNEbdjOirmvOXoCTEWUvh8A4f4Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-transform/binding-linux-arm-musleabihf@0.97.0': - resolution: {integrity: sha512-b7yslA+e6rPI4yMN1H/sVWH2SPRsP1OVfLMm3Von8PMTYl6A6YIB11ujVe2kI2zJJgCwIZpumH/PCgNgnHswdQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxc-transform/binding-linux-arm64-gnu@0.97.0': - resolution: {integrity: sha512-ZPbn5Kf8ha9PZkIomNdcUULuYihdcwmuzd+97OH+fSDd/Ih7SUAZcMWkV390YDhSkn+M1rFhhctNzvyq12D03Q==} + '@oxc-transform/binding-linux-arm64-gnu@0.102.0': + resolution: {integrity: sha512-Rz/RbPvT4QwcHKIQ/cOt6Lwl4c7AhK2b6whZfyL6oJ7Uz8UiVl1BCwk8thedrB5h+FEykmaPHoriW1hmBev60g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxc-transform/binding-linux-arm64-musl@0.97.0': - resolution: {integrity: sha512-8G3QSis4HaGgzQr+9lwrZ21D5xbaZdl7Lr3YflLzRzTXLjTmypHNqBc39ixv7UJXv8U4X7QX2gTwt+eTYVnuOg==} + '@oxc-transform/binding-linux-arm64-musl@0.102.0': + resolution: {integrity: sha512-I08iWABrN7zakn3wuNIBWY3hALQGsDLPQbZT1mXws7tyiQqJNGe49uS0/O50QhX3KXj+mbRGsmjVXLXGJE1CVQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxc-transform/binding-linux-riscv64-gnu@0.97.0': - resolution: {integrity: sha512-VjlOW1L2f9DUC6KH9h/KNjbea3gm0IxGDlWlAJ6H4OOAjeIPMsTdb2GVBFL/bcYL6b+PfYNMS33a9+FDBg+DUQ==} + '@oxc-transform/binding-linux-riscv64-gnu@0.102.0': + resolution: {integrity: sha512-9+SYW1ARAF6Oj/82ayoqKRe8SI7O1qvzs3Y0kijvhIqAaaZWcFRjI5DToyWRAbnzTtHlMcSllZLXNYdmxBjFxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxc-transform/binding-linux-s390x-gnu@0.97.0': - resolution: {integrity: sha512-wMjz3U/Kd66KnyzfhkoCrwExBCsD6SuA4SbiCoVMcKixuSwn7uydeKDdnsG0zm7C/mWuHPoDeDJlBdwwgjBISg==} + '@oxc-transform/binding-linux-s390x-gnu@0.102.0': + resolution: {integrity: sha512-HV9nTyQw0TTKYPu+gBhaJBioomiM9O4LcGXi+s5IylCGG6imP0/U13q/9xJnP267QFmiWWqnnSFcv0QAWCyh8A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxc-transform/binding-linux-x64-gnu@0.97.0': - resolution: {integrity: sha512-vKEgB43XDCVtSXuPNp2+y2LiBLSKIVLnW4ARJKPyRtZFlbovsZavdzgl3mYjARZhygGTkCh+knqHawUL+QtQOg==} + '@oxc-transform/binding-linux-x64-gnu@0.102.0': + resolution: {integrity: sha512-4wcZ08mmdFk8OjsnglyeYGu5PW3TDh87AmcMOi7tZJ3cpJjfzwDfY27KTEUx6G880OpjAiF36OFSPwdKTKgp2g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxc-transform/binding-linux-x64-musl@0.97.0': - resolution: {integrity: sha512-gJq05JEv4wVglOajwQc4sQnPMl1pBVqjFmGj97BEzWAx+lTHKoCt0nqdxN1V4uxHJ8IwQcvyH1v8jWvT9HnZVw==} + '@oxc-transform/binding-linux-x64-musl@0.102.0': + resolution: {integrity: sha512-rUHZSZBw0FUnUgOhL/Rs7xJz9KjH2eFur/0df6Lwq/isgJc/ggtBtFoZ+y4Fb8ON87a3Y2gS2LT7SEctX0XdPQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxc-transform/binding-wasm32-wasi@0.97.0': - resolution: {integrity: sha512-GeQULU0NjplDPDLYHsipapD9JRh9SeX/e4eIfisCbrs7hK31uMOLQwFlRMHQkO5ATKuS/mC4Ic8bOxzn/dQYug==} + '@oxc-transform/binding-openharmony-arm64@0.102.0': + resolution: {integrity: sha512-98y4tccTQ/pA+r2KA/MEJIZ7J8TNTJ4aCT4rX8kWK4pGOko2YsfY3Ru9DVHlLDwmVj7wP8Z4JNxdBrAXRvK+0g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-transform/binding-wasm32-wasi@0.102.0': + resolution: {integrity: sha512-M6myOXxHty3L2TJEB1NlJPtQm0c0LmivAxcGv/+DSDadOoB/UnOUbjM8W2Utlh5IYS9ARSOjqHtBiPYLWJ15XA==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-transform/binding-win32-arm64-msvc@0.97.0': - resolution: {integrity: sha512-fSgn7Zub8gka2df22FKS6XRCCeuEgY/0HvfP3zMYaPkEKshSLxyb5Oz2epy+kfsjYDjtObW9sabtOhbb25JK4A==} + '@oxc-transform/binding-win32-arm64-msvc@0.102.0': + resolution: {integrity: sha512-jzaA1lLiMXiJs4r7E0BHRxTPiwAkpoCfSNRr8npK/SqL4UQE4cSz3WDTX5wJWRrN2U+xqsDGefeYzH4reI8sgw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-transform/binding-win32-x64-msvc@0.97.0': - resolution: {integrity: sha512-3TcX7Osyz1BQEe89VzGb0FxEeQUy24VLSBV9yEtsNTBHJqb/kWcxAo7BQTsrE3asCOaAqtME+gvsMtd2HXQRAA==} + '@oxc-transform/binding-win32-x64-msvc@0.102.0': + resolution: {integrity: sha512-eYOm6mch+1cP9qlNkMdorfBFY8aEOxY/isqrreLmEWqF/hyXA0SbLKDigTbvh3JFKny/gXlHoCKckqfua4cwtg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2537,6 +2653,116 @@ packages: '@rolldown/pluginutils@1.0.0-beta.53': resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} + cpu: [x64] + os: [win32] + '@sindresorhus/base62@1.0.0': resolution: {integrity: sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==} engines: {node: '>=18'} @@ -2638,7 +2864,7 @@ packages: '@tailwindcss/vite@4.1.17': resolution: {integrity: sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA==} peerDependencies: - vite: 8.0.0-beta.0 + vite: ^5.2.0 || ^6 || ^7 '@tanstack/query-core@5.90.12': resolution: {integrity: sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==} @@ -2781,7 +3007,7 @@ packages: '@vitejs/devtools-kit@0.0.0-alpha.18': resolution: {integrity: sha512-ddo3NiGDCgo+sjqfARUhn1H7sj2AmQoId+dEu0nzewEpwlMqNwKeRbO7NRCexI26ljwzUuKxVNm4B7wPChcxmg==} peerDependencies: - vite: 8.0.0-beta.0 + vite: '*' '@vitejs/devtools-rpc@0.0.0-alpha.18': resolution: {integrity: sha512-sbjJED7iprX9qrXFLXvvMZDV4L1QvViik7b6tO/ssOLsmvjUlha+UcTxbhdewCYjNUS3K9jwzwx3Ad2jmZ1YrQ==} @@ -2798,19 +3024,19 @@ packages: resolution: {integrity: sha512-H7eRBVmrj6p9URe0w17RYuPlGl4v4FVTe77P1BfaJS6z7RxPpt6bkBrbM6AUSSzMtV0LgFS0XtgM8HyYbQjzZA==} hasBin: true peerDependencies: - vite: 8.0.0-beta.0 + vite: '*' '@vitejs/plugin-react@5.1.1': resolution: {integrity: sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: 8.0.0-beta.0 + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 '@vitejs/plugin-vue@6.0.2': resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: 8.0.0-beta.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.2.25 '@vitest/eslint-plugin@1.5.1': @@ -2833,7 +3059,7 @@ packages: resolution: {integrity: sha512-CZ28GLfOEIFkvCFngN8Sfx5h+Se0zN+h4B7yOsPVCcgtiO7t5jt9xQh2E1UkFep+eb9fjyMfuC5gBypwb07fvQ==} peerDependencies: msw: ^2.4.9 - vite: 8.0.0-beta.0 + vite: ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true @@ -4217,6 +4443,12 @@ packages: peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + graphql-sse@2.6.0: + resolution: {integrity: sha512-BXT5Rjv9UFunjQsmN9WWEIq+TFNhgYibgwo1xkXLxzguQVyOd6paJ4v5DlL9K5QplS0w74bhF+aUiqaGXZBaug==} + engines: {node: '>=12'} + peerDependencies: + graphql: '>=0.11 <=16' + graphql-tag@2.12.6: resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} engines: {node: '>=10'} @@ -4248,12 +4480,6 @@ packages: peerDependencies: graphql: ^15.2.0 || ^16.0.0 - graphql-yoga@5.17.1: - resolution: {integrity: sha512-Izb2uVWfdoWm+tF4bi39KE6F4uml3r700/EwULPZYOciY8inmy4hw+98c6agy3C+xceXvTkP7Li6mY/EI8XliA==} - engines: {node: '>=18.0.0'} - peerDependencies: - graphql: ^15.2.0 || ^16.0.0 - graphql@16.12.0: resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} @@ -4265,8 +4491,8 @@ packages: h3@1.15.4: resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} - h3@2.0.1-rc.5: - resolution: {integrity: sha512-qkohAzCab0nLzXNm78tBjZDvtKMTmtygS8BJLT3VPczAQofdqlFXDPkXdLMJN4r05+xqneG8snZJ0HgkERCZTg==} + h3@2.0.1-rc.6: + resolution: {integrity: sha512-kKLFVFNJlDVTbQjakz1ZTFSHB9+oi9+Khf0v7xQsUKU3iOqu2qmrFzTD56YsDvvj2nBgqVDphGRXB2VRursw4w==} engines: {node: '>=20.11.1'} peerDependencies: crossws: ^0.4.1 @@ -4946,19 +5172,19 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - nf3@0.1.12: - resolution: {integrity: sha512-qbMXT7RTGh74MYWPeqTIED8nDW70NXOULVHpdWcdZ7IVHVnAsMV9fNugSNnvooipDc1FMOzpis7T9nXJEbJhvQ==} - - nitro-nightly@3.0.1-20251118-175529-0316c6c6: - resolution: {integrity: sha512-dJpcGCuzBWU0wxJq7QtLa5fm/Wv+829UWK/lG9S5tYmATW8DckuOxuZzZIFbG7tAfW+ws/+xlDFOxrBRwOTXvg==} + nitro-nightly@3.0.1-20251211-001255-afcf27ad: + resolution: {integrity: sha512-hbQ2gkeykiKuZ8M0aNENFGXM/eLW7PWB4imVj2r5H1E3iXpyRxIC9I92NE9Ir29nCx2GT4mk8R7qSCV/0a/2Hw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: + nf3: '>=0.2' rolldown: '*' rollup: ^4 - vite: 8.0.0-beta.0 + vite: ^7 xml2js: ^0.6.2 peerDependenciesMeta: + nf3: + optional: true rolldown: optional: true rollup: @@ -5066,16 +5292,16 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - oxc-minify@0.97.0: - resolution: {integrity: sha512-QvZwjfhN/YH01EqMGJT0EUTd8QORT5gPlhxLBpOl7B83jDEq8hYVylYbvTUGJRXri0roqUvuuIg6BEDERPhycA==} + oxc-minify@0.102.0: + resolution: {integrity: sha512-FphAHDyTCNepQbiQTSyWFMbNc9zdUmj1WBsoLwvZhWm7rEe/IeIKYKRhy75lWOjwFsi5/i4Qucq43hgs3n2Exw==} engines: {node: ^20.19.0 || >=22.12.0} oxc-parser@0.101.0: resolution: {integrity: sha512-Njg0KoSisH57AWzKTImV0JpjUBu0riCwbMTnnSH8H/deHpJaVpcbmwsiKkSd7ViX6lxaXiOiBVZH2quWPUFtUg==} engines: {node: ^20.19.0 || >=22.12.0} - oxc-transform@0.97.0: - resolution: {integrity: sha512-aL0ghVqJClYvHlnEkihLvjDg4CBU+Z6tdEBDlGRLVJR4U2S8a8LijLbdJD/dmkhgBA9f3ZSxxYHjCjFViFCJEw==} + oxc-transform@0.102.0: + resolution: {integrity: sha512-MR5ohiBS6/kvxRpmUZ3LIDTTJBEC4xLAEZXfYr7vrA0eP7WHewQaNQPFDgT4Bee89TdmVQ5ZKrifGwxLjSyHHw==} engines: {node: ^20.19.0 || >=22.12.0} p-limit@2.3.0: @@ -5488,6 +5714,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + rou3@0.7.10: resolution: {integrity: sha512-aoFj6f7MJZ5muJ+Of79nrhs9N3oLGqi2VEMe94Zbkjb6Wupha46EuoYgpWSOZlXww3bbd8ojgXTAA2mzimX5Ww==} @@ -5647,8 +5878,8 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - srvx@0.9.6: - resolution: {integrity: sha512-5L4rT6qQqqb+xcoDoklUgCNdmzqJ6vbcDRwPVGRXewF55IJH0pqh0lQlrJ266ZWTKJ4mfeioqHQJeAYesS+RrQ==} + srvx@0.9.8: + resolution: {integrity: sha512-RZaxTKJEE/14HYn8COLuUOJAt0U55N9l1Xf6jj+T0GoA01EUH1Xz5JtSUOI+EHn+AEgPCVn7gk6jHJffrr06fQ==} engines: {node: '>=20.16.0'} hasBin: true @@ -6127,6 +6358,46 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite@7.2.7: + resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vite@8.0.0-beta.0: resolution: {integrity: sha512-bXHWmtg5hUxn/MB5zJ8qhBLphnsNmO1EYOFmBO/fVCBJekTdWDuqJ/GmUMLgrC0QUCCrxhw3JLgteWdiyqaVSQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -7701,13 +7972,13 @@ snapshots: '@graphql-tools/utils': 10.11.0(graphql@16.12.0) graphql: 16.12.0 - '@graphql-tools/executor-graphql-ws@2.0.7(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)': + '@graphql-tools/executor-graphql-ws@2.0.7(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)': dependencies: '@graphql-tools/executor-common': 0.0.6(graphql@16.12.0) '@graphql-tools/utils': 10.11.0(graphql@16.12.0) '@whatwg-node/disposablestack': 0.0.6 graphql: 16.12.0 - graphql-ws: 6.0.6(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)(ws@8.18.3) + graphql-ws: 6.0.6(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(ws@8.18.3) isomorphic-ws: 5.0.0(ws@8.18.3) tslib: 2.8.1 ws: 8.18.3 @@ -7718,13 +7989,13 @@ snapshots: - uWebSockets.js - utf-8-validate - '@graphql-tools/executor-graphql-ws@3.1.3(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)': + '@graphql-tools/executor-graphql-ws@3.1.3(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)': dependencies: '@graphql-tools/executor-common': 1.0.5(graphql@16.12.0) '@graphql-tools/utils': 10.11.0(graphql@16.12.0) '@whatwg-node/disposablestack': 0.0.6 graphql: 16.12.0 - graphql-ws: 6.0.6(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)(ws@8.18.3) + graphql-ws: 6.0.6(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(ws@8.18.3) isows: 1.0.7(ws@8.18.3) tslib: 2.8.1 ws: 8.18.3 @@ -7799,16 +8070,6 @@ snapshots: graphql: 16.12.0 tslib: 2.8.1 - '@graphql-tools/executor@1.5.0(graphql@16.12.0)': - dependencies: - '@graphql-tools/utils': 10.11.0(graphql@16.12.0) - '@graphql-typed-document-node/core': 3.2.0(graphql@16.12.0) - '@repeaterjs/repeater': 3.0.6 - '@whatwg-node/disposablestack': 0.0.6 - '@whatwg-node/promise-helpers': 1.3.2 - graphql: 16.12.0 - tslib: 2.8.1 - '@graphql-tools/graphql-file-loader@8.1.8(graphql@16.12.0)': dependencies: '@graphql-tools/import': 7.1.8(graphql@16.12.0) @@ -7908,9 +8169,9 @@ snapshots: graphql: 16.12.0 tslib: 2.8.1 - '@graphql-tools/url-loader@8.0.33(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)': + '@graphql-tools/url-loader@8.0.33(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)': dependencies: - '@graphql-tools/executor-graphql-ws': 2.0.7(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0) + '@graphql-tools/executor-graphql-ws': 2.0.7(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0) '@graphql-tools/executor-http': 1.3.3(@types/node@24.10.1)(graphql@16.12.0) '@graphql-tools/executor-legacy-ws': 1.1.23(graphql@16.12.0) '@graphql-tools/utils': 10.11.0(graphql@16.12.0) @@ -7931,9 +8192,9 @@ snapshots: - uWebSockets.js - utf-8-validate - '@graphql-tools/url-loader@9.0.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)': + '@graphql-tools/url-loader@9.0.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)': dependencies: - '@graphql-tools/executor-graphql-ws': 3.1.3(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0) + '@graphql-tools/executor-graphql-ws': 3.1.3(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0) '@graphql-tools/executor-http': 3.0.7(@types/node@24.10.1)(graphql@16.12.0) '@graphql-tools/executor-legacy-ws': 1.1.24(graphql@16.12.0) '@graphql-tools/utils': 10.11.0(graphql@16.12.0) @@ -8112,51 +8373,51 @@ snapshots: pkg-types: 2.3.0 std-env: 3.10.0 - '@oxc-minify/binding-android-arm64@0.97.0': + '@oxc-minify/binding-android-arm64@0.102.0': optional: true - '@oxc-minify/binding-darwin-arm64@0.97.0': + '@oxc-minify/binding-darwin-arm64@0.102.0': optional: true - '@oxc-minify/binding-darwin-x64@0.97.0': + '@oxc-minify/binding-darwin-x64@0.102.0': optional: true - '@oxc-minify/binding-freebsd-x64@0.97.0': + '@oxc-minify/binding-freebsd-x64@0.102.0': optional: true - '@oxc-minify/binding-linux-arm-gnueabihf@0.97.0': + '@oxc-minify/binding-linux-arm-gnueabihf@0.102.0': optional: true - '@oxc-minify/binding-linux-arm-musleabihf@0.97.0': + '@oxc-minify/binding-linux-arm64-gnu@0.102.0': optional: true - '@oxc-minify/binding-linux-arm64-gnu@0.97.0': + '@oxc-minify/binding-linux-arm64-musl@0.102.0': optional: true - '@oxc-minify/binding-linux-arm64-musl@0.97.0': + '@oxc-minify/binding-linux-riscv64-gnu@0.102.0': optional: true - '@oxc-minify/binding-linux-riscv64-gnu@0.97.0': + '@oxc-minify/binding-linux-s390x-gnu@0.102.0': optional: true - '@oxc-minify/binding-linux-s390x-gnu@0.97.0': + '@oxc-minify/binding-linux-x64-gnu@0.102.0': optional: true - '@oxc-minify/binding-linux-x64-gnu@0.97.0': + '@oxc-minify/binding-linux-x64-musl@0.102.0': optional: true - '@oxc-minify/binding-linux-x64-musl@0.97.0': + '@oxc-minify/binding-openharmony-arm64@0.102.0': optional: true - '@oxc-minify/binding-wasm32-wasi@0.97.0': + '@oxc-minify/binding-wasm32-wasi@0.102.0': dependencies: - '@napi-rs/wasm-runtime': 1.0.7 + '@napi-rs/wasm-runtime': 1.1.0 optional: true - '@oxc-minify/binding-win32-arm64-msvc@0.97.0': + '@oxc-minify/binding-win32-arm64-msvc@0.102.0': optional: true - '@oxc-minify/binding-win32-x64-msvc@0.97.0': + '@oxc-minify/binding-win32-x64-msvc@0.102.0': optional: true '@oxc-parser/binding-android-arm64@0.101.0': @@ -8210,51 +8471,51 @@ snapshots: '@oxc-project/types@0.101.0': {} - '@oxc-transform/binding-android-arm64@0.97.0': + '@oxc-transform/binding-android-arm64@0.102.0': optional: true - '@oxc-transform/binding-darwin-arm64@0.97.0': + '@oxc-transform/binding-darwin-arm64@0.102.0': optional: true - '@oxc-transform/binding-darwin-x64@0.97.0': + '@oxc-transform/binding-darwin-x64@0.102.0': optional: true - '@oxc-transform/binding-freebsd-x64@0.97.0': + '@oxc-transform/binding-freebsd-x64@0.102.0': optional: true - '@oxc-transform/binding-linux-arm-gnueabihf@0.97.0': + '@oxc-transform/binding-linux-arm-gnueabihf@0.102.0': optional: true - '@oxc-transform/binding-linux-arm-musleabihf@0.97.0': + '@oxc-transform/binding-linux-arm64-gnu@0.102.0': optional: true - '@oxc-transform/binding-linux-arm64-gnu@0.97.0': + '@oxc-transform/binding-linux-arm64-musl@0.102.0': optional: true - '@oxc-transform/binding-linux-arm64-musl@0.97.0': + '@oxc-transform/binding-linux-riscv64-gnu@0.102.0': optional: true - '@oxc-transform/binding-linux-riscv64-gnu@0.97.0': + '@oxc-transform/binding-linux-s390x-gnu@0.102.0': optional: true - '@oxc-transform/binding-linux-s390x-gnu@0.97.0': + '@oxc-transform/binding-linux-x64-gnu@0.102.0': optional: true - '@oxc-transform/binding-linux-x64-gnu@0.97.0': + '@oxc-transform/binding-linux-x64-musl@0.102.0': optional: true - '@oxc-transform/binding-linux-x64-musl@0.97.0': + '@oxc-transform/binding-openharmony-arm64@0.102.0': optional: true - '@oxc-transform/binding-wasm32-wasi@0.97.0': + '@oxc-transform/binding-wasm32-wasi@0.102.0': dependencies: - '@napi-rs/wasm-runtime': 1.0.7 + '@napi-rs/wasm-runtime': 1.1.0 optional: true - '@oxc-transform/binding-win32-arm64-msvc@0.97.0': + '@oxc-transform/binding-win32-arm64-msvc@0.102.0': optional: true - '@oxc-transform/binding-win32-x64-msvc@0.97.0': + '@oxc-transform/binding-win32-x64-msvc@0.102.0': optional: true '@pinia/colada@0.18.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))': @@ -8430,6 +8691,72 @@ snapshots: '@rolldown/pluginutils@1.0.0-beta.53': {} + '@rollup/rollup-android-arm-eabi@4.53.3': + optional: true + + '@rollup/rollup-android-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.3': + optional: true + + '@rollup/rollup-darwin-x64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.3': + optional: true + '@sindresorhus/base62@1.0.0': {} '@standard-schema/spec@1.0.0': {} @@ -8841,7 +9168,7 @@ snapshots: eslint: 9.39.1(jiti@2.6.1) optionalDependencies: typescript: 5.9.3 - vitest: 4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -8854,13 +9181,13 @@ snapshots: chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.15(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.15(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.15 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@4.0.15': dependencies: @@ -8888,7 +9215,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vitest: 4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) '@vitest/utils@4.0.15': dependencies: @@ -9513,9 +9840,9 @@ snapshots: dependencies: uncrypto: 0.1.3 - crossws@0.4.1(srvx@0.9.6): + crossws@0.4.1(srvx@0.9.8): optionalDependencies: - srvx: 0.9.6 + srvx: 0.9.8 cssesc@3.0.0: {} @@ -10278,13 +10605,13 @@ snapshots: graphemer@1.4.0: {} - graphql-config@5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)(typescript@5.9.3): + graphql-config@5.1.5(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(typescript@5.9.3): dependencies: '@graphql-tools/graphql-file-loader': 8.1.8(graphql@16.12.0) '@graphql-tools/json-file-loader': 8.0.24(graphql@16.12.0) '@graphql-tools/load': 8.1.7(graphql@16.12.0) '@graphql-tools/merge': 9.1.6(graphql@16.12.0) - '@graphql-tools/url-loader': 8.0.33(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0) + '@graphql-tools/url-loader': 8.0.33(@types/node@24.10.1)(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0) '@graphql-tools/utils': 10.11.0(graphql@16.12.0) cosmiconfig: 8.3.6(typescript@5.9.3) graphql: 16.12.0 @@ -10307,39 +10634,34 @@ snapshots: graphql: 16.12.0 tslib: 2.8.1 + graphql-sse@2.6.0(graphql@16.12.0): + dependencies: + graphql: 16.12.0 + graphql-tag@2.12.6(graphql@16.12.0): dependencies: graphql: 16.12.0 tslib: 2.8.1 - graphql-ws@6.0.6(crossws@0.4.1(srvx@0.9.6))(graphql@16.12.0)(ws@8.18.3): + graphql-ws@6.0.6(crossws@0.3.5)(graphql@16.12.0)(ws@8.18.3): dependencies: graphql: 16.12.0 optionalDependencies: - crossws: 0.4.1(srvx@0.9.6) + crossws: 0.3.5 ws: 8.18.3 - graphql-yoga@5.16.2(graphql@16.12.0): + graphql-ws@6.0.6(crossws@0.4.1(srvx@0.9.8))(graphql@16.12.0)(ws@8.18.3): dependencies: - '@envelop/core': 5.4.0 - '@envelop/instrumentation': 1.0.0 - '@graphql-tools/executor': 1.4.13(graphql@16.12.0) - '@graphql-tools/schema': 10.0.30(graphql@16.12.0) - '@graphql-tools/utils': 10.11.0(graphql@16.12.0) - '@graphql-yoga/logger': 2.0.1 - '@graphql-yoga/subscription': 5.0.5 - '@whatwg-node/fetch': 0.10.13 - '@whatwg-node/promise-helpers': 1.3.2 - '@whatwg-node/server': 0.10.17 graphql: 16.12.0 - lru-cache: 10.4.3 - tslib: 2.8.1 + optionalDependencies: + crossws: 0.4.1(srvx@0.9.8) + ws: 8.18.3 - graphql-yoga@5.17.1(graphql@16.12.0): + graphql-yoga@5.16.2(graphql@16.12.0): dependencies: '@envelop/core': 5.4.0 '@envelop/instrumentation': 1.0.0 - '@graphql-tools/executor': 1.5.0(graphql@16.12.0) + '@graphql-tools/executor': 1.4.13(graphql@16.12.0) '@graphql-tools/schema': 10.0.30(graphql@16.12.0) '@graphql-tools/utils': 10.11.0(graphql@16.12.0) '@graphql-yoga/logger': 2.0.1 @@ -10372,12 +10694,12 @@ snapshots: ufo: 1.6.1 uncrypto: 0.1.3 - h3@2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)): + h3@2.0.1-rc.6(crossws@0.4.1(srvx@0.9.8)): dependencies: rou3: 0.7.10 - srvx: 0.9.6 + srvx: 0.9.8 optionalDependencies: - crossws: 0.4.1(srvx@0.9.6) + crossws: 0.4.1(srvx@0.9.8) has-flag@4.0.0: {} @@ -11114,26 +11436,72 @@ snapshots: negotiator@1.0.0: {} - nf3@0.1.12: {} + nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + consola: 3.4.2 + crossws: 0.4.1(srvx@0.9.8) + db0: 0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)) + h3: 2.0.1-rc.6(crossws@0.4.1(srvx@0.9.8)) + jiti: 2.6.1 + ofetch: 2.0.0-alpha.3 + ohash: 2.0.11 + oxc-minify: 0.102.0 + oxc-transform: 0.102.0 + srvx: 0.9.8 + undici: 7.16.0 + unenv: 2.0.0-rc.24 + unstorage: 2.0.0-alpha.4(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)))(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) + optionalDependencies: + rolldown: 1.0.0-beta.53 + rollup: 4.53.3 + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - chokidar + - drizzle-orm + - idb-keyval + - ioredis + - lru-cache + - mongodb + - mysql2 + - sqlite3 + - uploadthing - nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)): + nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@4.0.3)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)): dependencies: consola: 3.4.2 - crossws: 0.4.1(srvx@0.9.6) + crossws: 0.4.1(srvx@0.9.8) db0: 0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)) - h3: 2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)) + h3: 2.0.1-rc.6(crossws@0.4.1(srvx@0.9.8)) jiti: 2.6.1 - nf3: 0.1.12 ofetch: 2.0.0-alpha.3 ohash: 2.0.11 - oxc-minify: 0.97.0 - oxc-transform: 0.97.0 - srvx: 0.9.6 + oxc-minify: 0.102.0 + oxc-transform: 0.102.0 + srvx: 0.9.8 undici: 7.16.0 unenv: 2.0.0-rc.24 unstorage: 2.0.0-alpha.4(chokidar@4.0.3)(db0@0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)))(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) optionalDependencies: rolldown: 1.0.0-beta.53 + rollup: 4.53.3 vite: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@azure/app-configuration' @@ -11164,24 +11532,24 @@ snapshots: - sqlite3 - uploadthing - nitro-nightly@3.0.1-20251118-175529-0316c6c6(better-sqlite3@12.4.1)(chokidar@5.0.0)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)): + nitro-nightly@3.0.1-20251211-001255-afcf27ad(better-sqlite3@12.4.1)(chokidar@5.0.0)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0))(lru-cache@11.2.2)(rolldown@1.0.0-beta.53)(rollup@4.53.3)(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)): dependencies: consola: 3.4.2 - crossws: 0.4.1(srvx@0.9.6) + crossws: 0.4.1(srvx@0.9.8) db0: 0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)) - h3: 2.0.1-rc.5(crossws@0.4.1(srvx@0.9.6)) + h3: 2.0.1-rc.6(crossws@0.4.1(srvx@0.9.8)) jiti: 2.6.1 - nf3: 0.1.12 ofetch: 2.0.0-alpha.3 ohash: 2.0.11 - oxc-minify: 0.97.0 - oxc-transform: 0.97.0 - srvx: 0.9.6 + oxc-minify: 0.102.0 + oxc-transform: 0.102.0 + srvx: 0.9.8 undici: 7.16.0 unenv: 2.0.0-rc.24 unstorage: 2.0.0-alpha.4(chokidar@5.0.0)(db0@0.3.4(better-sqlite3@12.4.1)(drizzle-orm@0.45.0(@prisma/client@5.22.0(prisma@5.22.0))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(kysely@0.28.8)(pg@8.16.3)(prisma@5.22.0)))(lru-cache@11.2.2)(ofetch@2.0.0-alpha.3) optionalDependencies: rolldown: 1.0.0-beta.53 + rollup: 4.53.3 vite: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@azure/app-configuration' @@ -11312,23 +11680,23 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - oxc-minify@0.97.0: + oxc-minify@0.102.0: optionalDependencies: - '@oxc-minify/binding-android-arm64': 0.97.0 - '@oxc-minify/binding-darwin-arm64': 0.97.0 - '@oxc-minify/binding-darwin-x64': 0.97.0 - '@oxc-minify/binding-freebsd-x64': 0.97.0 - '@oxc-minify/binding-linux-arm-gnueabihf': 0.97.0 - '@oxc-minify/binding-linux-arm-musleabihf': 0.97.0 - '@oxc-minify/binding-linux-arm64-gnu': 0.97.0 - '@oxc-minify/binding-linux-arm64-musl': 0.97.0 - '@oxc-minify/binding-linux-riscv64-gnu': 0.97.0 - '@oxc-minify/binding-linux-s390x-gnu': 0.97.0 - '@oxc-minify/binding-linux-x64-gnu': 0.97.0 - '@oxc-minify/binding-linux-x64-musl': 0.97.0 - '@oxc-minify/binding-wasm32-wasi': 0.97.0 - '@oxc-minify/binding-win32-arm64-msvc': 0.97.0 - '@oxc-minify/binding-win32-x64-msvc': 0.97.0 + '@oxc-minify/binding-android-arm64': 0.102.0 + '@oxc-minify/binding-darwin-arm64': 0.102.0 + '@oxc-minify/binding-darwin-x64': 0.102.0 + '@oxc-minify/binding-freebsd-x64': 0.102.0 + '@oxc-minify/binding-linux-arm-gnueabihf': 0.102.0 + '@oxc-minify/binding-linux-arm64-gnu': 0.102.0 + '@oxc-minify/binding-linux-arm64-musl': 0.102.0 + '@oxc-minify/binding-linux-riscv64-gnu': 0.102.0 + '@oxc-minify/binding-linux-s390x-gnu': 0.102.0 + '@oxc-minify/binding-linux-x64-gnu': 0.102.0 + '@oxc-minify/binding-linux-x64-musl': 0.102.0 + '@oxc-minify/binding-openharmony-arm64': 0.102.0 + '@oxc-minify/binding-wasm32-wasi': 0.102.0 + '@oxc-minify/binding-win32-arm64-msvc': 0.102.0 + '@oxc-minify/binding-win32-x64-msvc': 0.102.0 oxc-parser@0.101.0: dependencies: @@ -11350,23 +11718,23 @@ snapshots: '@oxc-parser/binding-win32-arm64-msvc': 0.101.0 '@oxc-parser/binding-win32-x64-msvc': 0.101.0 - oxc-transform@0.97.0: + oxc-transform@0.102.0: optionalDependencies: - '@oxc-transform/binding-android-arm64': 0.97.0 - '@oxc-transform/binding-darwin-arm64': 0.97.0 - '@oxc-transform/binding-darwin-x64': 0.97.0 - '@oxc-transform/binding-freebsd-x64': 0.97.0 - '@oxc-transform/binding-linux-arm-gnueabihf': 0.97.0 - '@oxc-transform/binding-linux-arm-musleabihf': 0.97.0 - '@oxc-transform/binding-linux-arm64-gnu': 0.97.0 - '@oxc-transform/binding-linux-arm64-musl': 0.97.0 - '@oxc-transform/binding-linux-riscv64-gnu': 0.97.0 - '@oxc-transform/binding-linux-s390x-gnu': 0.97.0 - '@oxc-transform/binding-linux-x64-gnu': 0.97.0 - '@oxc-transform/binding-linux-x64-musl': 0.97.0 - '@oxc-transform/binding-wasm32-wasi': 0.97.0 - '@oxc-transform/binding-win32-arm64-msvc': 0.97.0 - '@oxc-transform/binding-win32-x64-msvc': 0.97.0 + '@oxc-transform/binding-android-arm64': 0.102.0 + '@oxc-transform/binding-darwin-arm64': 0.102.0 + '@oxc-transform/binding-darwin-x64': 0.102.0 + '@oxc-transform/binding-freebsd-x64': 0.102.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.102.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.102.0 + '@oxc-transform/binding-linux-arm64-musl': 0.102.0 + '@oxc-transform/binding-linux-riscv64-gnu': 0.102.0 + '@oxc-transform/binding-linux-s390x-gnu': 0.102.0 + '@oxc-transform/binding-linux-x64-gnu': 0.102.0 + '@oxc-transform/binding-linux-x64-musl': 0.102.0 + '@oxc-transform/binding-openharmony-arm64': 0.102.0 + '@oxc-transform/binding-wasm32-wasi': 0.102.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.102.0 + '@oxc-transform/binding-win32-x64-msvc': 0.102.0 p-limit@2.3.0: dependencies: @@ -11783,6 +12151,34 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.53 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.53 + rollup@4.53.3: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 + fsevents: 2.3.3 + rou3@0.7.10: {} run-applescript@7.1.0: {} @@ -11940,7 +12336,7 @@ snapshots: sprintf-js@1.0.3: {} - srvx@0.9.6: {} + srvx@0.9.8: {} stackback@0.0.2: {} @@ -12308,6 +12704,22 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.3 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 24.10.1 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.30.2 + tsx: 4.21.0 + yaml: 2.8.2 + vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@oxc-project/runtime': 0.101.0 @@ -12344,10 +12756,10 @@ snapshots: transitivePeerDependencies: - supports-color - vitest@4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.15(@types/node@24.10.1)(@vitest/ui@4.0.15)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.15 - '@vitest/mocker': 4.0.15(vite@8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.15(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.15 '@vitest/runner': 4.0.15 '@vitest/snapshot': 4.0.15 @@ -12364,15 +12776,15 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 8.0.0-beta.0(@types/node@24.10.1)(esbuild@0.25.12)(jiti@2.6.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.10.1 '@vitest/ui': 4.0.15(vitest@4.0.15) transitivePeerDependencies: - - esbuild - jiti - less + - lightningcss - msw - sass - sass-embedded diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 39c59b3..187aaaf 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,7 @@ cleanupUnusedCatalogs: true ignoreWorkspaceRootCheck: true shellEmulator: true + trustPolicy: no-downgrade packages: @@ -60,6 +61,8 @@ catalog: graphql: 16.12.0 graphql-config: ^5.1.5 graphql-scalars: ^1.25.0 + graphql-sse: ^2.6.0 + graphql-ws: 6.0.6 graphql-yoga: 5.16.2 knitwork: ^1.3.0 nitro: npm:nitro-nightly@latest diff --git a/src/codegen/client-types.ts b/src/codegen/client-types.ts index 8ee52a9..ce37a71 100644 --- a/src/codegen/client-types.ts +++ b/src/codegen/client-types.ts @@ -13,7 +13,7 @@ import { FILE_INDEX_TS, LOG_TAG, SERVICE_DEFAULT } from '../constants' import { generateClientTypes as generateClientTypesUtil, loadGraphQLDocuments } from '../utils/client-codegen' import { loadFederationSupport } from '../utils/federation' import { writeFileIfNotExists } from '../utils/file-generator' -import { generateOfetchTemplate } from '../utils/ofetch-templates' +import { generateOfetchTemplate, generateWebSocketTemplate } from '../utils/ofetch-templates' import { getClientUtilsConfig, getDefaultPaths, @@ -153,6 +153,12 @@ export async function generateMainClientTypes( // Generate ofetch client for all frameworks (only if it doesn't exist) generateNuxtOfetchClient(nitro, nitro.graphql.clientDir, SERVICE_DEFAULT) + // Generate WebSocket client if subscriptions are enabled + if (nitro.options.graphql?.subscriptions?.enabled) { + const wsEndpoint = nitro.options.runtimeConfig?.graphql?.endpoint?.ws || '/api/graphql/ws' + generateWebSocketClient(nitro, SERVICE_DEFAULT, wsEndpoint) + } + // Generate index file if there are external services const externalServices = nitro.options.graphql?.externalServices || [] if (externalServices.length > 0) { @@ -263,3 +269,54 @@ function generateNuxtOfetchClient( writeFileIfNotExists(ofetchPath, ofetchContent, `${serviceName} ofetch.ts`) } + +/** + * Generate WebSocket client wrapper for GraphQL subscriptions + */ +function generateWebSocketClient( + nitro: Nitro, + serviceName: string = SERVICE_DEFAULT, + wsEndpoint: string, +): void { + // Check if client utils generation is enabled + if (!shouldGenerateClientUtils(nitro)) { + return + } + + const placeholders = { + ...getDefaultPaths(nitro), + serviceName, + } + const clientUtilsConfig = getClientUtilsConfig(nitro) + + // Resolve ws-client.ts path + const wsClientPath = resolveFilePath( + clientUtilsConfig.wsClient, + clientUtilsConfig.enabled, + true, + '{clientGraphql}/{serviceName}/ws-client.ts', + placeholders, + ) + + if (!wsClientPath) { + return + } + + // Create service directory if it doesn't exist + const serviceDir = dirname(wsClientPath) + if (!existsSync(serviceDir)) { + mkdirSync(serviceDir, { recursive: true }) + } + + if (existsSync(wsClientPath)) { + return // Don't overwrite existing files + } + + const wsClientContent = generateWebSocketTemplate({ + serviceName, + wsEndpoint, + isExternal: false, + }) + + writeFileIfNotExists(wsClientPath, wsClientContent, `${serviceName} ws-client.ts`) +} diff --git a/src/codegen/external-types.ts b/src/codegen/external-types.ts index 825f088..71ba979 100644 --- a/src/codegen/external-types.ts +++ b/src/codegen/external-types.ts @@ -15,7 +15,7 @@ import { loadGraphQLDocuments, } from '../utils/client-codegen' import { writeFileIfNotExists } from '../utils/file-generator' -import { generateOfetchTemplate } from '../utils/ofetch-templates' +import { generateOfetchTemplate, generateWebSocketTemplate } from '../utils/ofetch-templates' import { getClientUtilsConfig, getDefaultPaths, @@ -123,6 +123,14 @@ export async function generateExternalServicesTypes( // Generate ofetch client for all frameworks generateExternalOfetchClient(nitro, service, service.endpoint) + // Generate WebSocket client if wsEndpoint is provided + if (service.wsEndpoint) { + generateExternalWebSocketClient(nitro, service, service.wsEndpoint) + if (!options.silent) { + consola.success(`[graphql:${service.name}] WebSocket client generated`) + } + } + if (!options.silent) { consola.success(`[graphql:${service.name}] External service types generated successfully`) } @@ -186,3 +194,55 @@ function generateExternalOfetchClient( writeFileIfNotExists(ofetchPath, ofetchContent, `${serviceName} external ofetch.ts`) } } + +/** + * Generate WebSocket client for external service + */ +function generateExternalWebSocketClient( + nitro: Nitro, + service: ExternalGraphQLService, + wsEndpoint: string, +): void { + // Check if client utils generation is enabled + if (!shouldGenerateClientUtils(nitro)) { + return + } + + const serviceName = service.name + const placeholders = { + ...getDefaultPaths(nitro), + serviceName, + } + const clientUtilsConfig = getClientUtilsConfig(nitro) + + // Resolve ws-client.ts path with service-specific override + // Priority: service.paths.wsClient > global clientUtils.wsClient > default + const wsClientPath = resolveFilePath( + service.paths?.wsClient ?? clientUtilsConfig.wsClient, + clientUtilsConfig.enabled, + true, + '{clientGraphql}/{serviceName}/ws-client.ts', + placeholders, + ) + + if (!wsClientPath) { + return + } + + // Create service directory if it doesn't exist + const serviceDir = dirname(wsClientPath) + if (!existsSync(serviceDir)) { + mkdirSync(serviceDir, { recursive: true }) + } + + // Only create ws-client file if it doesn't exist + if (!existsSync(wsClientPath)) { + const wsClientContent = generateWebSocketTemplate({ + serviceName, + wsEndpoint, + isExternal: true, + }) + + writeFileIfNotExists(wsClientPath, wsClientContent, `${serviceName} external ws-client.ts`) + } +} diff --git a/src/routes/apollo-server-ws.ts b/src/routes/apollo-server-ws.ts new file mode 100644 index 0000000..f9c8903 --- /dev/null +++ b/src/routes/apollo-server-ws.ts @@ -0,0 +1,118 @@ +import type { BaseContext } from '@apollo/server' +import type { Peer } from 'crossws' +import type { GraphQLSchema } from 'graphql' +import type { GraphQLWSMessage } from '../utils/ws-protocol' +import { importedConfig } from '#nitro-graphql/graphql-config' +import { ApolloServer } from '@apollo/server' +import defu from 'defu' +import { defineWebSocketHandler } from 'h3' +import { + cleanupSubscriptions, + devLog, + + handleComplete, + handleConnectionInit, + handlePing, + handleSubscribe, + sendMessage, +} from '../utils/ws-protocol' +import { createMergedSchema } from '../utils/ws-schema' + +let schema: GraphQLSchema +let apolloServer: ApolloServer | null = null + +async function getSchema() { + if (!schema) { + schema = await createMergedSchema() + + // Create Apollo Server instance for validation/plugins + if (!apolloServer) { + apolloServer = new ApolloServer(defu({ + schema, + introspection: true, + }, importedConfig)) + await apolloServer.start() + } + } + return schema +} + +// Store active subscriptions per peer +const peerSubscriptions = new WeakMap>>() + +export default defineWebSocketHandler({ + upgrade(request) { + // Handle WebSocket protocol negotiation + const protocols = request.headers.get('sec-websocket-protocol') + if (protocols?.includes('graphql-transport-ws')) { + return { + headers: { + 'Sec-WebSocket-Protocol': 'graphql-transport-ws', + }, + } + } + }, + + async open(peer) { + devLog('[Apollo WS] Client connected') + peerSubscriptions.set(peer, new Map()) + }, + + async message(peer, message) { + try { + const data = message.text() + const msg: GraphQLWSMessage = JSON.parse(data) + + const schema = await getSchema() + const subscriptions = peerSubscriptions.get(peer) + + if (!subscriptions) { + console.error('[Apollo WS] No subscriptions map found for peer') + return + } + + switch (msg.type) { + case 'connection_init': + handleConnectionInit(peer) + break + + case 'ping': + handlePing(peer) + break + + case 'subscribe': + await handleSubscribe(peer, msg, schema, subscriptions) + break + + case 'complete': + await handleComplete(msg, subscriptions) + break + + default: + devLog('[Apollo WS] Unknown message type:', msg.type) + } + } + catch (error) { + console.error('[Apollo WS] Message handling error:', error) + sendMessage(peer, { + type: 'error', + payload: [{ message: 'Invalid message format' }], + }) + } + }, + + async close(peer, details) { + devLog('[Apollo WS] Client disconnected:', details) + + // Clean up all subscriptions for this peer + const subscriptions = peerSubscriptions.get(peer) + if (subscriptions) { + await cleanupSubscriptions(subscriptions) + } + peerSubscriptions.delete(peer) + }, + + async error(peer, error) { + console.error('[Apollo WS] WebSocket error:', error) + }, +}) diff --git a/src/routes/graphql-yoga-ws.ts b/src/routes/graphql-yoga-ws.ts new file mode 100644 index 0000000..db47818 --- /dev/null +++ b/src/routes/graphql-yoga-ws.ts @@ -0,0 +1,118 @@ +import type { Peer } from 'crossws' +import type { GraphQLSchema } from 'graphql' +import type { YogaServerInstance } from 'graphql-yoga' +import type { GraphQLWSMessage } from '../utils/ws-protocol' +import { importedConfig } from '#nitro-graphql/graphql-config' +import defu from 'defu' +import { createYoga } from 'graphql-yoga' +import { defineWebSocketHandler } from 'h3' +import { + cleanupSubscriptions, + devLog, + + handleComplete, + handleConnectionInit, + handlePing, + handleSubscribe, + sendMessage, +} from '../utils/ws-protocol' +import { createMergedSchema } from '../utils/ws-schema' + +let schema: GraphQLSchema +let yoga: YogaServerInstance + +async function getSchema() { + if (!schema) { + schema = await createMergedSchema() + + // Create Yoga instance for validation/plugins + if (!yoga) { + yoga = createYoga(defu({ + schema, + graphqlEndpoint: '/api/graphql', + landingPage: false, + }, importedConfig)) + } + } + return schema +} + +// Store active subscriptions per peer +const peerSubscriptions = new WeakMap>>() + +export default defineWebSocketHandler({ + upgrade(request) { + // Handle WebSocket protocol negotiation + const protocols = request.headers.get('sec-websocket-protocol') + if (protocols?.includes('graphql-transport-ws')) { + return { + headers: { + 'Sec-WebSocket-Protocol': 'graphql-transport-ws', + }, + } + } + }, + + async open(peer) { + devLog('[GraphQL WS] Client connected') + peerSubscriptions.set(peer, new Map()) + }, + + async message(peer, message) { + try { + const data = message.text() + const msg: GraphQLWSMessage = JSON.parse(data) + + const schema = await getSchema() + const subscriptions = peerSubscriptions.get(peer) + + if (!subscriptions) { + console.error('[GraphQL WS] No subscriptions map found for peer') + return + } + + switch (msg.type) { + case 'connection_init': + handleConnectionInit(peer) + break + + case 'ping': + handlePing(peer) + break + + case 'subscribe': + await handleSubscribe(peer, msg, schema, subscriptions) + break + + case 'complete': + await handleComplete(msg, subscriptions) + break + + default: + devLog('[GraphQL WS] Unknown message type:', msg.type) + } + } + catch (error) { + console.error('[GraphQL WS] Message handling error:', error) + sendMessage(peer, { + type: 'error', + payload: [{ message: 'Invalid message format' }], + }) + } + }, + + async close(peer, details) { + devLog('[GraphQL WS] Client disconnected:', details) + + // Clean up all subscriptions for this peer + const subscriptions = peerSubscriptions.get(peer) + if (subscriptions) { + await cleanupSubscriptions(subscriptions) + } + peerSubscriptions.delete(peer) + }, + + async error(peer, error) { + console.error('[GraphQL WS] WebSocket error:', error) + }, +}) diff --git a/src/setup.ts b/src/setup.ts index 60657b2..4bbc2d3 100644 --- a/src/setup.ts +++ b/src/setup.ts @@ -138,6 +138,13 @@ function validateConfiguration(nitro: Nitro): void { if (nitro.options.graphql?.federation?.enabled) { logger.info(`Apollo Federation enabled for service: ${nitro.options.graphql.federation.serviceName || 'unnamed'}`) } + + // Enable WebSocket feature if subscriptions are enabled + if (nitro.options.graphql?.subscriptions?.enabled) { + nitro.options.features ||= { runtimeHooks: false, websocket: false } + nitro.options.features.websocket = true + logger.info('WebSocket subscriptions enabled') + } } /** @@ -300,6 +307,15 @@ function registerRouteHandlers(nitro: Nitro): void { method, }) } + + // Register WebSocket handler if subscriptions are enabled + if (nitro.options.graphql?.subscriptions?.enabled) { + nitro.options.handlers.push({ + route: nitro.options.runtimeConfig.graphql?.endpoint?.ws || '/api/graphql/ws', + handler: join(runtime, 'graphql-yoga-ws'), + }) + consola.info(`[nitro-graphql] GraphQL Yoga WebSocket endpoint: ${nitro.options.runtimeConfig.graphql?.endpoint?.ws || '/api/graphql/ws'}`) + } } if (framework === 'apollo-server') { @@ -310,6 +326,15 @@ function registerRouteHandlers(nitro: Nitro): void { method, }) } + + // Register WebSocket handler if subscriptions are enabled + if (nitro.options.graphql?.subscriptions?.enabled) { + nitro.options.handlers.push({ + route: nitro.options.runtimeConfig.graphql?.endpoint?.ws || '/api/graphql/ws', + handler: join(runtime, 'apollo-server-ws'), + }) + consola.info(`[nitro-graphql] Apollo Server WebSocket endpoint: ${nitro.options.runtimeConfig.graphql?.endpoint?.ws || '/api/graphql/ws'}`) + } } // Health check endpoint diff --git a/src/types/index.ts b/src/types/index.ts index bef7bb3..bf9fc7f 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -79,6 +79,8 @@ export interface ExternalServicePaths { types?: FileGenerationConfig /** ofetch client wrapper path (overrides global clientUtils.ofetch config) */ ofetch?: FileGenerationConfig + /** WebSocket client wrapper path (overrides global clientUtils.wsClient config) */ + wsClient?: FileGenerationConfig } export interface ExternalGraphQLService { @@ -88,6 +90,8 @@ export interface ExternalGraphQLService { schema: string | string[] /** GraphQL endpoint for this service */ endpoint: string + /** Optional WebSocket endpoint for subscriptions */ + wsEndpoint?: string /** Optional headers for schema introspection and client requests */ headers?: Record | (() => Record) /** Optional: specific document patterns for this service */ @@ -162,6 +166,8 @@ export interface ClientUtilsConfig { index?: FileGenerationConfig /** app/graphql/{serviceName}/ofetch.ts - ofetch client wrapper */ ofetch?: FileGenerationConfig + /** app/graphql/{serviceName}/ws-client.ts - WebSocket client wrapper */ + wsClient?: FileGenerationConfig } /** @@ -207,13 +213,28 @@ export interface PathsConfig { typesDir?: string } +/** + * WebSocket/Subscription configuration + */ +export interface SubscriptionsConfig { + /** Enable WebSocket subscriptions */ + enabled?: boolean + /** WebSocket endpoint path (relative to graphql endpoint) */ + endpoint?: string + /** GraphQL subscription protocol */ + protocol?: 'graphql-ws' +} + export interface NitroGraphQLOptions { framework?: 'graphql-yoga' | 'apollo-server' endpoint?: { graphql?: string + ws?: string healthCheck?: string } playground?: boolean + /** WebSocket subscriptions configuration */ + subscriptions?: SubscriptionsConfig typedefs?: string[] resolvers?: Array> loader?: { diff --git a/src/utils/ofetch-templates.ts b/src/utils/ofetch-templates.ts index 479bbf3..568fd3b 100644 --- a/src/utils/ofetch-templates.ts +++ b/src/utils/ofetch-templates.ts @@ -153,3 +153,134 @@ export function create${capitalizedName}GraphQLClient(endpoint: string = '${endp export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedName}GraphQLClient())` } + +export interface WebSocketTemplateOptions { + /** Service name (e.g., 'default', 'github') */ + serviceName: string + /** WebSocket endpoint URL */ + wsEndpoint: string + /** Whether this is an external service */ + isExternal?: boolean +} + +/** + * Generate WebSocket client template for GraphQL subscriptions + */ +export function generateWebSocketTemplate(options: WebSocketTemplateOptions): string { + const { serviceName, wsEndpoint, isExternal = false } = options + const capitalizedName = capitalize(serviceName) + const serviceDescription = isExternal ? `${serviceName} external service` : (serviceName === 'default' ? 'the main GraphQL service' : serviceName) + const serviceLogName = isExternal ? serviceName : (serviceName === 'default' ? 'main service' : serviceName) + + return `// This file is auto-generated once by nitro-graphql for quick start +// You can modify this file according to your needs +import { createClient } from 'graphql-ws' + +export interface WebSocketClientConfig { + url?: string + headers?: Record | (() => Record) + retryAttempts?: number + retryWait?: number | ((retries: number) => number) + onConnected?: () => void + onDisconnected?: () => void + onError?: (error: Error) => void +} + +/** + * Create a GraphQL WebSocket client for ${serviceDescription} + * Uses graphql-ws protocol for subscriptions + */ +export function create${capitalizedName}WebSocketClient(config: WebSocketClientConfig = {}) { + const { + url = typeof window !== 'undefined' + ? \`\${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}/\${window.location.host}${wsEndpoint}\` + : '${wsEndpoint}', + headers, + retryAttempts = 5, + retryWait, + onConnected, + onDisconnected, + onError, + } = config + + const client = createClient({ + url, + connectionParams: () => { + const resolvedHeaders = typeof headers === 'function' ? headers() : headers + return resolvedHeaders || {} + }, + retryAttempts, + retryWait, + on: { + connected: () => { + console.log('[GraphQL WS] Connected to ${serviceLogName}') + onConnected?.() + }, + closed: () => { + console.log('[GraphQL WS] Disconnected from ${serviceLogName}') + onDisconnected?.() + }, + error: (error) => { + console.error('[GraphQL WS] Error:', error) + onError?.(error as Error) + }, + }, + }) + + return client +} + +/** + * Helper to execute a GraphQL subscription + * + * @example + * const unsubscribe = executeSubscription(client, { + * query: \`subscription { messageSent { id text } }\`, + * onData: (data) => console.log('Message:', data.messageSent), + * onError: (error) => console.error('Error:', error) + * }) + */ +export function executeSubscription( + client: ReturnType, + options: { + query: string + variables?: Record + operationName?: string + onData: (data: T) => void + onError?: (error: Error) => void + onComplete?: () => void + }, +) { + const { query, variables, operationName, onData, onError, onComplete } = options + + const unsubscribe = client.subscribe( + { + query, + variables, + operationName, + }, + { + next: (result) => { + if (result.errors) { + onError?.(new Error(result.errors.map(e => e.message).join(', '))) + } + else if (result.data) { + onData(result.data as T) + } + }, + error: (error) => { + onError?.(error instanceof Error ? error : new Error(String(error))) + }, + complete: () => { + onComplete?.() + }, + }, + ) + + return unsubscribe +} + +// Export a default client instance for ${serviceLogName} +export const $wsClient = create${capitalizedName}WebSocketClient() +` +} diff --git a/src/utils/ws-protocol.ts b/src/utils/ws-protocol.ts new file mode 100644 index 0000000..01bc2a4 --- /dev/null +++ b/src/utils/ws-protocol.ts @@ -0,0 +1,159 @@ +import type { Peer } from 'crossws' +import type { GraphQLSchema } from 'graphql' +import { parse, subscribe, validate } from 'graphql' + +// Development-only logging +const isDev = process.env.NODE_ENV === 'development' + +export function devLog(message: string, ...args: any[]) { + if (isDev) + // eslint-disable-next-line no-console + console.log(message, ...args) +} + +// GraphQL-WS protocol message types +export interface GraphQLWSMessage { + id?: string + type: string + payload?: any +} + +// Efficient message sending +export function sendMessage(peer: Peer, message: Record) { + peer.send(JSON.stringify(message)) +} + +export function sendErrorMessage(peer: Peer, id: string | undefined, errors: Array<{ message: string, locations?: any, path?: any }>) { + sendMessage(peer, { + id, + type: 'error', + payload: errors, + }) +} + +export function sendNextMessage(peer: Peer, id: string, payload: any) { + sendMessage(peer, { + id, + type: 'next', + payload, + }) +} + +export function sendCompleteMessage(peer: Peer, id: string) { + sendMessage(peer, { + id, + type: 'complete', + }) +} + +// Connection init handler +export function handleConnectionInit(peer: Peer) { + sendMessage(peer, { type: 'connection_ack' }) +} + +// Ping handler +export function handlePing(peer: Peer) { + sendMessage(peer, { type: 'pong' }) +} + +// Subscribe handler +export async function handleSubscribe( + peer: Peer, + msg: GraphQLWSMessage, + schema: GraphQLSchema, + subscriptions: Map>, +) { + if (!msg.id || !msg.payload) { + sendErrorMessage(peer, msg.id, [{ message: 'Invalid subscribe message' }]) + return + } + + try { + const { query, variables, operationName } = msg.payload + + // Parse and validate the query + const document = typeof query === 'string' ? parse(query) : query + const validationErrors = validate(schema, document) + + if (validationErrors.length > 0) { + sendErrorMessage(peer, msg.id, validationErrors.map(err => ({ + message: err.message, + locations: err.locations, + path: err.path, + }))) + return + } + + // Execute subscription + const result = await subscribe({ + schema, + document, + variableValues: variables, + operationName, + contextValue: {}, + }) + + // Check if it's a subscription result (AsyncIterator) + if (Symbol.asyncIterator in result) { + subscriptions.set(msg.id, result) + + // Process subscription events + ;(async () => { + try { + for await (const value of result) { + sendNextMessage(peer, msg.id!, value) + } + + // Subscription completed + sendCompleteMessage(peer, msg.id!) + subscriptions.delete(msg.id!) + } + catch (error) { + console.error('[GraphQL WS] Subscription error:', error) + sendErrorMessage(peer, msg.id!, [{ message: error instanceof Error ? error.message : 'Subscription error' }]) + subscriptions.delete(msg.id!) + } + })() + } + else { + // It's a regular query/mutation result + sendNextMessage(peer, msg.id, result) + sendCompleteMessage(peer, msg.id) + } + } + catch (error) { + console.error('[GraphQL WS] Operation error:', error) + sendErrorMessage(peer, msg.id!, [{ message: error instanceof Error ? error.message : 'Operation failed' }]) + } +} + +// Complete handler +export async function handleComplete( + msg: GraphQLWSMessage, + subscriptions: Map>, +) { + if (!msg.id) + return + + // Cancel active subscription + const iterator = subscriptions.get(msg.id) + if (iterator && typeof iterator.return === 'function') { + await iterator.return() + } + subscriptions.delete(msg.id) +} + +// Cleanup all subscriptions for a peer +export async function cleanupSubscriptions(subscriptions: Map>) { + for (const [id, iterator] of subscriptions.entries()) { + if (typeof iterator.return === 'function') { + try { + await iterator.return() + } + catch (error) { + console.error(`[GraphQL WS] Error cleaning up subscription ${id}:`, error) + } + } + } + subscriptions.clear() +} diff --git a/src/utils/ws-schema.ts b/src/utils/ws-schema.ts new file mode 100644 index 0000000..4b6ce56 --- /dev/null +++ b/src/utils/ws-schema.ts @@ -0,0 +1,83 @@ +import type { GraphQLSchema } from 'graphql' +import { moduleConfig } from '#nitro-graphql/module-config' +import { directives } from '#nitro-graphql/server-directives' +import { resolvers } from '#nitro-graphql/server-resolvers' +import { schemas } from '#nitro-graphql/server-schemas' +import { mergeResolvers, mergeTypeDefs } from '@graphql-tools/merge' +import { makeExecutableSchema } from '@graphql-tools/schema' +import { parse } from 'graphql' + +// Conditional imports for federation support +let buildSubgraphSchema: any = null + +async function loadFederationSupport() { + if (buildSubgraphSchema !== null) + return buildSubgraphSchema + + try { + const apolloSubgraph = await import('@apollo/subgraph') + buildSubgraphSchema = apolloSubgraph.buildSubgraphSchema + } + catch { + buildSubgraphSchema = false + } + + return buildSubgraphSchema +} + +export async function createMergedSchema(): Promise { + try { + const mergedSchemas = schemas.map(schema => schema.def).join('\n\n') + const typeDefs = mergeTypeDefs([mergedSchemas], { + throwOnConflict: true, + commentDescriptions: true, + sort: true, + }) + const mergedResolvers = mergeResolvers(resolvers.map(r => r.resolver)) + + const federationEnabled = moduleConfig.federation?.enabled + + let schema: GraphQLSchema + + if (federationEnabled) { + const buildSubgraph = await loadFederationSupport() + + if (buildSubgraph) { + const typeDefsDoc = typeof typeDefs === 'string' ? parse(typeDefs) : typeDefs + + schema = buildSubgraph({ + typeDefs: typeDefsDoc, + resolvers: mergedResolvers, + }) + } + else { + console.warn('[GraphQL WS] Federation enabled but @apollo/subgraph not available, falling back to regular schema') + schema = makeExecutableSchema({ + typeDefs, + resolvers: mergedResolvers, + }) + } + } + else { + schema = makeExecutableSchema({ + typeDefs, + resolvers: mergedResolvers, + }) + } + + // Apply directives if any + if (directives && directives.length > 0) { + for (const { directive } of directives) { + if (directive.transformer) { + schema = directive.transformer(schema) + } + } + } + + return schema + } + catch (error) { + console.error('[GraphQL WS] Schema merge error:', error) + throw error + } +}