nitro-graphql 1.7.0-beta.5 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +9 -2
- package/dist/index.mjs +36 -31
- package/dist/rollup.mjs +7 -16
- package/dist/routes/apollo-server-ws.d.mts +9 -3
- package/dist/routes/apollo-server-ws.mjs +38 -1
- package/dist/routes/apollo-server.d.mts +2 -2
- package/dist/routes/apollo-server.mjs +28 -3
- package/dist/routes/debug.d.mts +2 -2
- package/dist/routes/graphql-yoga-ws.d.mts +9 -3
- package/dist/routes/graphql-yoga-ws.mjs +38 -1
- package/dist/routes/graphql-yoga.d.mts +2 -2
- package/dist/routes/graphql-yoga.mjs +17 -6
- package/dist/routes/health.d.mts +2 -2
- package/dist/routes/ws-shutdown.d.mts +11 -0
- package/dist/routes/ws-shutdown.mjs +22 -0
- package/dist/types/index.d.mts +41 -1
- package/dist/utils/client-codegen.mjs +23 -15
- package/dist/utils/type-generation.mjs +0 -7
- package/package.json +12 -16
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from "./types/standard-schema.mjs";
|
|
2
|
-
import { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, SubscriptionsConfig, TypesConfig } from "./types/index.mjs";
|
|
2
|
+
import { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, SecurityConfig, SubscriptionsConfig, TypesConfig } from "./types/index.mjs";
|
|
3
3
|
import * as nitropack0 from "nitropack";
|
|
4
4
|
|
|
5
5
|
//#region src/index.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolve security config with environment-aware defaults
|
|
9
|
+
* In production: introspection off, playground off, errors masked, suggestions disabled
|
|
10
|
+
* In development: introspection on, playground on, errors shown, suggestions enabled
|
|
11
|
+
*/
|
|
12
|
+
declare function resolveSecurityConfig(config?: SecurityConfig): Required<SecurityConfig>;
|
|
6
13
|
declare const _default: nitropack0.NitroModule;
|
|
7
14
|
//#endregion
|
|
8
|
-
export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, StandardSchemaV1, SubscriptionsConfig, TypesConfig, _default as default };
|
|
15
|
+
export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, SecurityConfig, StandardSchemaV1, SubscriptionsConfig, TypesConfig, _default as default, resolveSecurityConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -14,6 +14,20 @@ import { defineNitroModule } from "nitropack/kit";
|
|
|
14
14
|
import { dirname, join, relative, resolve } from "pathe";
|
|
15
15
|
|
|
16
16
|
//#region src/index.ts
|
|
17
|
+
/**
|
|
18
|
+
* Resolve security config with environment-aware defaults
|
|
19
|
+
* In production: introspection off, playground off, errors masked, suggestions disabled
|
|
20
|
+
* In development: introspection on, playground on, errors shown, suggestions enabled
|
|
21
|
+
*/
|
|
22
|
+
function resolveSecurityConfig(config) {
|
|
23
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
24
|
+
return {
|
|
25
|
+
introspection: config?.introspection ?? !isProd,
|
|
26
|
+
playground: config?.playground ?? !isProd,
|
|
27
|
+
maskErrors: config?.maskErrors ?? isProd,
|
|
28
|
+
disableSuggestions: config?.disableSuggestions ?? isProd
|
|
29
|
+
};
|
|
30
|
+
}
|
|
17
31
|
var src_default = defineNitroModule({
|
|
18
32
|
name: "nitro-graphql",
|
|
19
33
|
async setup(nitro) {
|
|
@@ -50,13 +64,15 @@ var src_default = defineNitroModule({
|
|
|
50
64
|
};
|
|
51
65
|
}
|
|
52
66
|
});
|
|
67
|
+
const securityConfig = resolveSecurityConfig(nitro.options.graphql?.security);
|
|
53
68
|
nitro.options.runtimeConfig.graphql = defu(nitro.options.runtimeConfig.graphql || {}, {
|
|
54
69
|
endpoint: {
|
|
55
70
|
graphql: "/api/graphql",
|
|
56
71
|
healthCheck: "/api/graphql/health",
|
|
57
72
|
ws: "/api/graphql/ws"
|
|
58
73
|
},
|
|
59
|
-
playground:
|
|
74
|
+
playground: securityConfig.playground,
|
|
75
|
+
security: securityConfig
|
|
60
76
|
});
|
|
61
77
|
if (nitro.options.graphql?.federation?.enabled) consola.info(`Apollo Federation enabled for service: ${nitro.options.graphql.federation.serviceName || "unnamed"}`);
|
|
62
78
|
const graphqlBuildDir = resolve(nitro.options.buildDir, "graphql");
|
|
@@ -118,42 +134,32 @@ var src_default = defineNitroModule({
|
|
|
118
134
|
const docs = await scanDocs(nitro);
|
|
119
135
|
nitro.scanDocuments = docs;
|
|
120
136
|
if (nitro.options.dev) {
|
|
137
|
+
const runtimeSecurityConfig = nitro.options.runtimeConfig.graphql?.security;
|
|
138
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
121
139
|
consola.box({
|
|
122
140
|
title: "Nitro GraphQL",
|
|
123
141
|
message: [
|
|
124
142
|
`Framework: ${nitro.options.graphql?.framework || "Not configured"}`,
|
|
143
|
+
`Environment: ${isProd ? "production" : "development"}`,
|
|
125
144
|
`Schemas: ${schemas.length}`,
|
|
126
145
|
`Resolvers: ${resolvers.length}`,
|
|
127
146
|
`Directives: ${directives$1.length}`,
|
|
128
147
|
`Documents: ${docs.length}`,
|
|
129
148
|
"",
|
|
149
|
+
"Security:",
|
|
150
|
+
`├─ Introspection: ${runtimeSecurityConfig?.introspection ? "enabled" : "disabled"}`,
|
|
151
|
+
`├─ Playground: ${runtimeSecurityConfig?.playground ? "enabled" : "disabled"}`,
|
|
152
|
+
`├─ Error Masking: ${runtimeSecurityConfig?.maskErrors ? "enabled" : "disabled"}`,
|
|
153
|
+
`└─ Field Suggestions: ${runtimeSecurityConfig?.disableSuggestions ? "disabled" : "enabled"}`,
|
|
154
|
+
"",
|
|
130
155
|
"Debug Dashboard: /_nitro/graphql/debug"
|
|
131
156
|
].join("\n"),
|
|
132
157
|
style: {
|
|
133
|
-
borderColor: "cyan",
|
|
158
|
+
borderColor: isProd ? "yellow" : "cyan",
|
|
134
159
|
borderStyle: "rounded"
|
|
135
160
|
}
|
|
136
161
|
});
|
|
137
|
-
if (resolvers.length
|
|
138
|
-
const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0);
|
|
139
|
-
const typeCount = {
|
|
140
|
-
query: 0,
|
|
141
|
-
mutation: 0,
|
|
142
|
-
resolver: 0,
|
|
143
|
-
type: 0,
|
|
144
|
-
subscription: 0,
|
|
145
|
-
directive: 0
|
|
146
|
-
};
|
|
147
|
-
for (const resolver of resolvers) for (const imp of resolver.imports) if (imp.type in typeCount) typeCount[imp.type]++;
|
|
148
|
-
const breakdown = [];
|
|
149
|
-
if (typeCount.query > 0) breakdown.push(`${typeCount.query} query`);
|
|
150
|
-
if (typeCount.mutation > 0) breakdown.push(`${typeCount.mutation} mutation`);
|
|
151
|
-
if (typeCount.resolver > 0) breakdown.push(`${typeCount.resolver} resolver`);
|
|
152
|
-
if (typeCount.type > 0) breakdown.push(`${typeCount.type} type`);
|
|
153
|
-
if (typeCount.subscription > 0) breakdown.push(`${typeCount.subscription} subscription`);
|
|
154
|
-
if (typeCount.directive > 0) breakdown.push(`${typeCount.directive} directive`);
|
|
155
|
-
if (breakdown.length > 0) consola.success(`[nitro-graphql] ${totalExports} resolver export(s): ${breakdown.join(", ")}`);
|
|
156
|
-
} else consola.warn("[nitro-graphql] No resolvers found. Check /_nitro/graphql/debug for details.");
|
|
162
|
+
if (resolvers.length === 0) consola.warn("[nitro-graphql] No resolvers found. Check /_nitro/graphql/debug for details.");
|
|
157
163
|
}
|
|
158
164
|
});
|
|
159
165
|
await rollupConfig(nitro);
|
|
@@ -196,16 +202,15 @@ var src_default = defineNitroModule({
|
|
|
196
202
|
route: wsEndpoint,
|
|
197
203
|
handler: join(runtime, "apollo-server-ws")
|
|
198
204
|
});
|
|
205
|
+
nitro.options.plugins ??= [];
|
|
206
|
+
nitro.options.plugins.push(join(runtime, "ws-shutdown"));
|
|
199
207
|
consola.info(`[nitro-graphql] WebSocket subscriptions enabled at: ${wsEndpoint}`);
|
|
200
208
|
}
|
|
201
|
-
if (nitro.options.dev) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
});
|
|
207
|
-
consola.info("[nitro-graphql] Debug dashboard available at: /_nitro/graphql/debug");
|
|
208
|
-
}
|
|
209
|
+
if (nitro.options.dev) nitro.options.handlers.push({
|
|
210
|
+
route: "/_nitro/graphql/debug",
|
|
211
|
+
handler: join(runtime, "debug"),
|
|
212
|
+
method: "get"
|
|
213
|
+
});
|
|
209
214
|
if (nitro.options.imports) {
|
|
210
215
|
nitro.options.imports.presets ??= [];
|
|
211
216
|
nitro.options.imports.presets.push({
|
|
@@ -350,4 +355,4 @@ declare module 'h3' {
|
|
|
350
355
|
});
|
|
351
356
|
|
|
352
357
|
//#endregion
|
|
353
|
-
export { src_default as default };
|
|
358
|
+
export { src_default as default, resolveSecurityConfig };
|
package/dist/rollup.mjs
CHANGED
|
@@ -62,15 +62,13 @@ function virtualSchemas(app) {
|
|
|
62
62
|
}
|
|
63
63
|
const importStatements = imports.map((handler) => `import ${getImportId(handler)} from '${handler}';`);
|
|
64
64
|
const schemaArray = imports.map((h) => `{ def: ${getImportId(h)} }`);
|
|
65
|
-
|
|
65
|
+
return `
|
|
66
66
|
${importStatements.join("\n")}
|
|
67
67
|
|
|
68
68
|
export const schemas = [
|
|
69
69
|
${schemaArray.join(",\n")}
|
|
70
70
|
];
|
|
71
71
|
`;
|
|
72
|
-
if (app.options.dev) app.logger.success(`[nitro-graphql] Generated virtual schema module: ${imports.length} schema(s)`);
|
|
73
|
-
return code;
|
|
74
72
|
} catch (error) {
|
|
75
73
|
app.logger.error("[nitro-graphql] Failed to generate virtual schema module:", error);
|
|
76
74
|
return "export const schemas = []";
|
|
@@ -108,7 +106,7 @@ function virtualResolvers(app) {
|
|
|
108
106
|
for (const msg of invalidImports) app.logger.warn(` - ${msg}`);
|
|
109
107
|
}
|
|
110
108
|
const data = imports.map(({ imports: importList }) => importList.map((i) => `{ resolver: ${i.as} }`).join(",\n")).filter(Boolean).join(",\n");
|
|
111
|
-
|
|
109
|
+
return [
|
|
112
110
|
...importsContent,
|
|
113
111
|
"",
|
|
114
112
|
"export const resolvers = [",
|
|
@@ -116,11 +114,6 @@ function virtualResolvers(app) {
|
|
|
116
114
|
"]",
|
|
117
115
|
""
|
|
118
116
|
].join("\n");
|
|
119
|
-
if (app.options.dev) {
|
|
120
|
-
const totalExports = imports.reduce((sum, r) => sum + r.imports.length, 0);
|
|
121
|
-
app.logger.success(`[nitro-graphql] Generated virtual resolver module: ${totalExports} export(s) from ${imports.length} file(s)`);
|
|
122
|
-
}
|
|
123
|
-
return code;
|
|
124
117
|
} catch (error) {
|
|
125
118
|
app.logger.error("[nitro-graphql] Failed to generate virtual resolver module:", error);
|
|
126
119
|
return "export const resolvers = []";
|
|
@@ -155,7 +148,7 @@ function virtualDirectives(app) {
|
|
|
155
148
|
for (const msg of invalidImports) app.logger.warn(` - ${msg}`);
|
|
156
149
|
}
|
|
157
150
|
const data = imports.map(({ imports: importList }) => importList.map((i) => `{ directive: ${i.as} }`).join(",\n")).filter(Boolean).join(",\n");
|
|
158
|
-
|
|
151
|
+
return [
|
|
159
152
|
...importsContent,
|
|
160
153
|
"",
|
|
161
154
|
"export const directives = [",
|
|
@@ -163,11 +156,6 @@ function virtualDirectives(app) {
|
|
|
163
156
|
"]",
|
|
164
157
|
""
|
|
165
158
|
].join("\n");
|
|
166
|
-
if (app.options.dev) {
|
|
167
|
-
const totalExports = imports.reduce((sum, d) => sum + d.imports.length, 0);
|
|
168
|
-
app.logger.success(`[nitro-graphql] Generated virtual directive module: ${totalExports} directive(s) from ${imports.length} file(s)`);
|
|
169
|
-
}
|
|
170
|
-
return code;
|
|
171
159
|
} catch (error) {
|
|
172
160
|
app.logger.error("[nitro-graphql] Failed to generate virtual directive module:", error);
|
|
173
161
|
return "export const directives = []";
|
|
@@ -187,7 +175,10 @@ export { importedConfig }
|
|
|
187
175
|
function virtualModuleConfig(app) {
|
|
188
176
|
app.options.virtual ??= {};
|
|
189
177
|
app.options.virtual["#nitro-internal-virtual/module-config"] = () => {
|
|
190
|
-
const moduleConfig =
|
|
178
|
+
const moduleConfig = {
|
|
179
|
+
...app.options.graphql,
|
|
180
|
+
security: app.options.runtimeConfig.graphql?.security
|
|
181
|
+
};
|
|
191
182
|
return `export const moduleConfig = ${JSON.stringify(moduleConfig, null, 2)};`;
|
|
192
183
|
};
|
|
193
184
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h33 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/apollo-server-ws.d.ts
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Gracefully shutdown all WebSocket connections.
|
|
7
|
+
* Called by the Nitro runtime plugin on server close.
|
|
8
|
+
*/
|
|
9
|
+
declare function shutdownAllConnections(): Promise<void>;
|
|
10
|
+
declare const _default: h33.EventHandler<h33.EventHandlerRequest, never>;
|
|
5
11
|
//#endregion
|
|
6
|
-
export { _default as default };
|
|
12
|
+
export { _default as default, shutdownAllConnections };
|
|
@@ -13,6 +13,34 @@ const isDev = process.env.NODE_ENV === "development";
|
|
|
13
13
|
function devLog(message, ...args) {
|
|
14
14
|
if (isDev) console.log(message, ...args);
|
|
15
15
|
}
|
|
16
|
+
const WS_STATE_KEY = "__nitro_graphql_ws_apollo__";
|
|
17
|
+
function getWsState() {
|
|
18
|
+
if (!globalThis[WS_STATE_KEY]) globalThis[WS_STATE_KEY] = {
|
|
19
|
+
activePeers: /* @__PURE__ */ new Set(),
|
|
20
|
+
cleanupFns: /* @__PURE__ */ new Map()
|
|
21
|
+
};
|
|
22
|
+
return globalThis[WS_STATE_KEY];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Gracefully shutdown all WebSocket connections.
|
|
26
|
+
* Called by the Nitro runtime plugin on server close.
|
|
27
|
+
*/
|
|
28
|
+
async function shutdownAllConnections() {
|
|
29
|
+
const state = getWsState();
|
|
30
|
+
const peers = Array.from(state.activePeers);
|
|
31
|
+
if (peers.length > 0) devLog(`[Apollo WS] Shutting down ${peers.length} connection(s)...`);
|
|
32
|
+
for (const peer of peers) {
|
|
33
|
+
const cleanup = state.cleanupFns.get(peer);
|
|
34
|
+
if (cleanup) try {
|
|
35
|
+
await cleanup();
|
|
36
|
+
} catch {}
|
|
37
|
+
try {
|
|
38
|
+
peer.close(1012, "Service Restart");
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
state.activePeers.clear();
|
|
42
|
+
state.cleanupFns.clear();
|
|
43
|
+
}
|
|
16
44
|
const DEFAULT_MAX_SUBSCRIPTIONS_PER_PEER = 20;
|
|
17
45
|
const DEFAULT_PING_INTERVAL_MS = 15e3;
|
|
18
46
|
const DEFAULT_PONG_TIMEOUT_MS = 5e3;
|
|
@@ -250,6 +278,12 @@ async function getSchema() {
|
|
|
250
278
|
}
|
|
251
279
|
var apollo_server_ws_default = defineWebSocketHandler({
|
|
252
280
|
async open(peer) {
|
|
281
|
+
const state = getWsState();
|
|
282
|
+
state.activePeers.add(peer);
|
|
283
|
+
state.cleanupFns.set(peer, async () => {
|
|
284
|
+
stopKeepAlive(peer);
|
|
285
|
+
await cleanupSubscriptions(peer, true);
|
|
286
|
+
});
|
|
253
287
|
devLog("[Apollo WS] Client connected");
|
|
254
288
|
peer.context.subscriptions = /* @__PURE__ */ new Map();
|
|
255
289
|
},
|
|
@@ -285,6 +319,9 @@ var apollo_server_ws_default = defineWebSocketHandler({
|
|
|
285
319
|
}
|
|
286
320
|
},
|
|
287
321
|
async close(peer, details) {
|
|
322
|
+
const state = getWsState();
|
|
323
|
+
state.activePeers.delete(peer);
|
|
324
|
+
state.cleanupFns.delete(peer);
|
|
288
325
|
devLog("[Apollo WS] Client disconnected:", details);
|
|
289
326
|
stopKeepAlive(peer);
|
|
290
327
|
await cleanupSubscriptions(peer, true);
|
|
@@ -295,4 +332,4 @@ var apollo_server_ws_default = defineWebSocketHandler({
|
|
|
295
332
|
});
|
|
296
333
|
|
|
297
334
|
//#endregion
|
|
298
|
-
export { apollo_server_ws_default as default };
|
|
335
|
+
export { apollo_server_ws_default as default, shutdownAllConnections };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h39 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/apollo-server.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h39.EventHandler<h39.EventHandlerRequest, Promise<any>>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { _default as default };
|
|
@@ -10,6 +10,7 @@ import { schemas } from "#nitro-internal-virtual/server-schemas";
|
|
|
10
10
|
import { makeExecutableSchema } from "@graphql-tools/schema";
|
|
11
11
|
import { defineEventHandler } from "h3";
|
|
12
12
|
import { ApolloServer } from "@apollo/server";
|
|
13
|
+
import { ApolloServerPluginLandingPageDisabled } from "@apollo/server/plugin/disabled";
|
|
13
14
|
import { ApolloServerPluginLandingPageLocalDefault } from "@apollo/server/plugin/landingPage/default";
|
|
14
15
|
import { startServerAndCreateH3Handler } from "nitro-graphql/utils/apollo";
|
|
15
16
|
|
|
@@ -64,10 +65,34 @@ let apolloServer = null;
|
|
|
64
65
|
let serverStarted = false;
|
|
65
66
|
async function createApolloServer() {
|
|
66
67
|
if (!apolloServer) {
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
const schema = await createMergedSchema();
|
|
69
|
+
const securityConfig = moduleConfig.security || {
|
|
69
70
|
introspection: true,
|
|
70
|
-
|
|
71
|
+
playground: true,
|
|
72
|
+
maskErrors: false,
|
|
73
|
+
disableSuggestions: false
|
|
74
|
+
};
|
|
75
|
+
const plugins = [];
|
|
76
|
+
if (securityConfig.playground) plugins.push(ApolloServerPluginLandingPageLocalDefault({ embed: true }));
|
|
77
|
+
else plugins.push(ApolloServerPluginLandingPageDisabled());
|
|
78
|
+
apolloServer = new ApolloServer(defu({
|
|
79
|
+
schema,
|
|
80
|
+
introspection: securityConfig.introspection,
|
|
81
|
+
plugins,
|
|
82
|
+
formatError: securityConfig.maskErrors ? (formattedError, _error) => {
|
|
83
|
+
const code = formattedError?.extensions?.code;
|
|
84
|
+
if (code && [
|
|
85
|
+
"BAD_USER_INPUT",
|
|
86
|
+
"GRAPHQL_VALIDATION_FAILED",
|
|
87
|
+
"UNAUTHENTICATED",
|
|
88
|
+
"FORBIDDEN",
|
|
89
|
+
"BAD_REQUEST"
|
|
90
|
+
].includes(code)) return formattedError;
|
|
91
|
+
return {
|
|
92
|
+
message: "Internal server error",
|
|
93
|
+
extensions: { code: "INTERNAL_SERVER_ERROR" }
|
|
94
|
+
};
|
|
95
|
+
} : void 0
|
|
71
96
|
}, importedConfig));
|
|
72
97
|
if (!serverStarted) {
|
|
73
98
|
await apolloServer.start();
|
package/dist/routes/debug.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h35 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/debug.d.ts
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ import * as h37 from "h3";
|
|
|
10
10
|
* - /_nitro/graphql/debug - HTML dashboard
|
|
11
11
|
* - /_nitro/graphql/debug?format=json - JSON API
|
|
12
12
|
*/
|
|
13
|
-
declare const _default:
|
|
13
|
+
declare const _default: h35.EventHandler<h35.EventHandlerRequest, Promise<string | {
|
|
14
14
|
timestamp: string;
|
|
15
15
|
environment: {
|
|
16
16
|
dev: any;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h30 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/graphql-yoga-ws.d.ts
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Gracefully shutdown all WebSocket connections.
|
|
7
|
+
* Called by the Nitro runtime plugin on server close.
|
|
8
|
+
*/
|
|
9
|
+
declare function shutdownAllConnections(): Promise<void>;
|
|
10
|
+
declare const _default: h30.EventHandler<h30.EventHandlerRequest, never>;
|
|
5
11
|
//#endregion
|
|
6
|
-
export { _default as default };
|
|
12
|
+
export { _default as default, shutdownAllConnections };
|
|
@@ -13,6 +13,34 @@ const isDev = process.env.NODE_ENV === "development";
|
|
|
13
13
|
function devLog(message, ...args) {
|
|
14
14
|
if (isDev) console.log(message, ...args);
|
|
15
15
|
}
|
|
16
|
+
const WS_STATE_KEY = "__nitro_graphql_ws_yoga__";
|
|
17
|
+
function getWsState() {
|
|
18
|
+
if (!globalThis[WS_STATE_KEY]) globalThis[WS_STATE_KEY] = {
|
|
19
|
+
activePeers: /* @__PURE__ */ new Set(),
|
|
20
|
+
cleanupFns: /* @__PURE__ */ new Map()
|
|
21
|
+
};
|
|
22
|
+
return globalThis[WS_STATE_KEY];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Gracefully shutdown all WebSocket connections.
|
|
26
|
+
* Called by the Nitro runtime plugin on server close.
|
|
27
|
+
*/
|
|
28
|
+
async function shutdownAllConnections() {
|
|
29
|
+
const state = getWsState();
|
|
30
|
+
const peers = Array.from(state.activePeers);
|
|
31
|
+
if (peers.length > 0) devLog(`[GraphQL WS] Shutting down ${peers.length} connection(s)...`);
|
|
32
|
+
for (const peer of peers) {
|
|
33
|
+
const cleanup = state.cleanupFns.get(peer);
|
|
34
|
+
if (cleanup) try {
|
|
35
|
+
await cleanup();
|
|
36
|
+
} catch {}
|
|
37
|
+
try {
|
|
38
|
+
peer.close(1012, "Service Restart");
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
state.activePeers.clear();
|
|
42
|
+
state.cleanupFns.clear();
|
|
43
|
+
}
|
|
16
44
|
const DEFAULT_MAX_SUBSCRIPTIONS_PER_PEER = 20;
|
|
17
45
|
const DEFAULT_PING_INTERVAL_MS = 15e3;
|
|
18
46
|
const DEFAULT_PONG_TIMEOUT_MS = 5e3;
|
|
@@ -250,6 +278,12 @@ async function getSchema() {
|
|
|
250
278
|
}
|
|
251
279
|
var graphql_yoga_ws_default = defineWebSocketHandler({
|
|
252
280
|
async open(peer) {
|
|
281
|
+
const state = getWsState();
|
|
282
|
+
state.activePeers.add(peer);
|
|
283
|
+
state.cleanupFns.set(peer, async () => {
|
|
284
|
+
stopKeepAlive(peer);
|
|
285
|
+
await cleanupSubscriptions(peer, true);
|
|
286
|
+
});
|
|
253
287
|
devLog("[GraphQL WS] Client connected");
|
|
254
288
|
peer.context.subscriptions = /* @__PURE__ */ new Map();
|
|
255
289
|
},
|
|
@@ -285,6 +319,9 @@ var graphql_yoga_ws_default = defineWebSocketHandler({
|
|
|
285
319
|
}
|
|
286
320
|
},
|
|
287
321
|
async close(peer, details) {
|
|
322
|
+
const state = getWsState();
|
|
323
|
+
state.activePeers.delete(peer);
|
|
324
|
+
state.cleanupFns.delete(peer);
|
|
288
325
|
devLog("[GraphQL WS] Client disconnected:", details);
|
|
289
326
|
stopKeepAlive(peer);
|
|
290
327
|
await cleanupSubscriptions(peer, true);
|
|
@@ -295,4 +332,4 @@ var graphql_yoga_ws_default = defineWebSocketHandler({
|
|
|
295
332
|
});
|
|
296
333
|
|
|
297
334
|
//#endregion
|
|
298
|
-
export { graphql_yoga_ws_default as default };
|
|
335
|
+
export { graphql_yoga_ws_default as default, shutdownAllConnections };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h31 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/graphql-yoga.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h31.EventHandler<h31.EventHandlerRequest, Promise<Response>>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { _default as default };
|
|
@@ -77,12 +77,23 @@ async function createMergedSchema() {
|
|
|
77
77
|
}
|
|
78
78
|
let yoga;
|
|
79
79
|
var graphql_yoga_default = defineEventHandler(async (event) => {
|
|
80
|
-
if (!yoga)
|
|
81
|
-
schema
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
if (!yoga) {
|
|
81
|
+
const schema = await createMergedSchema();
|
|
82
|
+
const securityConfig = moduleConfig.security || {
|
|
83
|
+
introspection: true,
|
|
84
|
+
playground: true,
|
|
85
|
+
maskErrors: false,
|
|
86
|
+
disableSuggestions: false
|
|
87
|
+
};
|
|
88
|
+
yoga = createYoga(defu({
|
|
89
|
+
schema,
|
|
90
|
+
graphqlEndpoint: "/api/graphql",
|
|
91
|
+
landingPage: securityConfig.playground,
|
|
92
|
+
graphiql: securityConfig.playground ? { defaultQuery: "# Welcome to the GraphQL Playground" } : false,
|
|
93
|
+
renderGraphiQL: securityConfig.playground ? () => apolloSandboxHtml : void 0,
|
|
94
|
+
maskedErrors: securityConfig.maskErrors
|
|
95
|
+
}, importedConfig));
|
|
96
|
+
}
|
|
86
97
|
const request = toWebRequest(event);
|
|
87
98
|
const response = await yoga.handleRequest(request, event);
|
|
88
99
|
return new Response(response.body, response);
|
package/dist/routes/health.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h37 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/health.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h37.EventHandler<h37.EventHandlerRequest, Promise<{
|
|
5
5
|
status: string;
|
|
6
6
|
message: string;
|
|
7
7
|
timestamp: string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as nitropack0 from "nitropack";
|
|
2
|
+
|
|
3
|
+
//#region src/routes/ws-shutdown.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Nitro runtime plugin for graceful WebSocket shutdown.
|
|
7
|
+
* Registered when subscriptions are enabled.
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: nitropack0.NitroAppPlugin;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { _default as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineNitroPlugin } from "nitropack/runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/routes/ws-shutdown.ts
|
|
4
|
+
/**
|
|
5
|
+
* Nitro runtime plugin for graceful WebSocket shutdown.
|
|
6
|
+
* Registered when subscriptions are enabled.
|
|
7
|
+
*/
|
|
8
|
+
var ws_shutdown_default = defineNitroPlugin((nitroApp) => {
|
|
9
|
+
nitroApp.hooks.hook("close", async () => {
|
|
10
|
+
if (globalThis.__nitro_graphql_ws_yoga__?.activePeers?.size > 0) try {
|
|
11
|
+
const { shutdownAllConnections } = await import("./graphql-yoga-ws.mjs");
|
|
12
|
+
await shutdownAllConnections();
|
|
13
|
+
} catch {}
|
|
14
|
+
if (globalThis.__nitro_graphql_ws_apollo__?.activePeers?.size > 0) try {
|
|
15
|
+
const { shutdownAllConnections } = await import("./apollo-server-ws.mjs");
|
|
16
|
+
await shutdownAllConnections();
|
|
17
|
+
} catch {}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { ws_shutdown_default as default };
|
package/dist/types/index.d.mts
CHANGED
|
@@ -16,6 +16,13 @@ type GenericSdkConfig = Omit<Parameters<typeof plugin$1>[2], 'documentMode'> & {
|
|
|
16
16
|
};
|
|
17
17
|
type CodegenClientConfig = TypeScriptPluginConfig & TypeScriptDocumentsPluginConfig & {
|
|
18
18
|
endpoint?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Generate TypedDocumentNode exports for urql/Apollo Client compatibility.
|
|
21
|
+
* When enabled, generates typed document constants that can be used with
|
|
22
|
+
* any GraphQL client that supports TypedDocumentNode.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
typedDocumentNode?: boolean;
|
|
19
26
|
};
|
|
20
27
|
interface IESMImport {
|
|
21
28
|
name: string;
|
|
@@ -198,6 +205,34 @@ interface SubscriptionsConfig {
|
|
|
198
205
|
/** WebSocket protocol (currently only graphql-ws is supported) */
|
|
199
206
|
protocol?: 'graphql-ws';
|
|
200
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Security configuration for production environments
|
|
210
|
+
* All options auto-detect based on NODE_ENV when not explicitly set
|
|
211
|
+
*/
|
|
212
|
+
interface SecurityConfig {
|
|
213
|
+
/**
|
|
214
|
+
* Enable GraphQL introspection queries
|
|
215
|
+
* @default true in development, false in production
|
|
216
|
+
*/
|
|
217
|
+
introspection?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Enable GraphQL playground/sandbox UI
|
|
220
|
+
* @default true in development, false in production
|
|
221
|
+
*/
|
|
222
|
+
playground?: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Mask internal error details in responses
|
|
225
|
+
* When enabled, internal errors show "Internal server error" instead of actual message
|
|
226
|
+
* @default false in development, true in production
|
|
227
|
+
*/
|
|
228
|
+
maskErrors?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Disable "Did you mean X?" field suggestions in error messages
|
|
231
|
+
* Prevents attackers from discovering field names via brute force
|
|
232
|
+
* @default false in development, true in production
|
|
233
|
+
*/
|
|
234
|
+
disableSuggestions?: boolean;
|
|
235
|
+
}
|
|
201
236
|
interface NitroGraphQLOptions {
|
|
202
237
|
framework: 'graphql-yoga' | 'apollo-server';
|
|
203
238
|
endpoint?: {
|
|
@@ -256,6 +291,11 @@ interface NitroGraphQLOptions {
|
|
|
256
291
|
* Customize base directories for file generation
|
|
257
292
|
*/
|
|
258
293
|
paths?: PathsConfig;
|
|
294
|
+
/**
|
|
295
|
+
* Security configuration for production environments
|
|
296
|
+
* Auto-detects NODE_ENV and applies secure defaults in production
|
|
297
|
+
*/
|
|
298
|
+
security?: SecurityConfig;
|
|
259
299
|
}
|
|
260
300
|
//#endregion
|
|
261
|
-
export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, SubscriptionsConfig, TypesConfig };
|
|
301
|
+
export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, SecurityConfig, SubscriptionsConfig, TypesConfig };
|
|
@@ -7,9 +7,10 @@ import { printSchemaWithDirectives } from "@graphql-tools/utils";
|
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { codegen } from "@graphql-codegen/core";
|
|
9
9
|
import { preset } from "@graphql-codegen/import-types-preset";
|
|
10
|
-
import { plugin } from "@graphql-codegen/
|
|
11
|
-
import { plugin as plugin$1 } from "@graphql-codegen/typescript
|
|
12
|
-
import { plugin as plugin$2 } from "@graphql-codegen/typescript-
|
|
10
|
+
import { plugin } from "@graphql-codegen/typed-document-node";
|
|
11
|
+
import { plugin as plugin$1 } from "@graphql-codegen/typescript";
|
|
12
|
+
import { plugin as plugin$2 } from "@graphql-codegen/typescript-generic-sdk";
|
|
13
|
+
import { plugin as plugin$3 } from "@graphql-codegen/typescript-operations";
|
|
13
14
|
import { GraphQLFileLoader } from "@graphql-tools/graphql-file-loader";
|
|
14
15
|
import { loadDocuments, loadSchemaSync } from "@graphql-tools/load";
|
|
15
16
|
import { UrlLoader } from "@graphql-tools/url-loader";
|
|
@@ -207,7 +208,7 @@ async function generateClientTypes(schema, docs, config = {}, sdkConfig = {}, ou
|
|
|
207
208
|
plugins: [{ pluginContent: {} }, { typescript: {} }],
|
|
208
209
|
pluginMap: {
|
|
209
210
|
pluginContent: { plugin: pluginContent },
|
|
210
|
-
typescript: { plugin }
|
|
211
|
+
typescript: { plugin: plugin$1 }
|
|
211
212
|
}
|
|
212
213
|
}),
|
|
213
214
|
sdk: `// THIS FILE IS GENERATED, DO NOT EDIT!
|
|
@@ -236,21 +237,28 @@ export function getSdk(requester: Requester): Sdk {
|
|
|
236
237
|
}
|
|
237
238
|
`
|
|
238
239
|
};
|
|
240
|
+
const enableTypedDocumentNode = config.typedDocumentNode === true;
|
|
241
|
+
const plugins = [
|
|
242
|
+
{ pluginContent: {} },
|
|
243
|
+
{ typescript: {} },
|
|
244
|
+
{ typescriptOperations: {} }
|
|
245
|
+
];
|
|
246
|
+
const pluginMap = {
|
|
247
|
+
pluginContent: { plugin: pluginContent },
|
|
248
|
+
typescript: { plugin: plugin$1 },
|
|
249
|
+
typescriptOperations: { plugin: plugin$3 }
|
|
250
|
+
};
|
|
251
|
+
if (enableTypedDocumentNode) {
|
|
252
|
+
plugins.push({ typedDocumentNode: {} });
|
|
253
|
+
pluginMap.typedDocumentNode = { plugin };
|
|
254
|
+
}
|
|
239
255
|
const output = await codegen({
|
|
240
256
|
filename: outputPath || "client-types.generated.ts",
|
|
241
257
|
schema: parse(printSchemaWithDirectives(schema)),
|
|
242
258
|
documents: [...docs],
|
|
243
259
|
config: mergedConfig,
|
|
244
|
-
plugins
|
|
245
|
-
|
|
246
|
-
{ typescript: {} },
|
|
247
|
-
{ typescriptOperations: {} }
|
|
248
|
-
],
|
|
249
|
-
pluginMap: {
|
|
250
|
-
pluginContent: { plugin: pluginContent },
|
|
251
|
-
typescript: { plugin },
|
|
252
|
-
typescriptOperations: { plugin: plugin$2 }
|
|
253
|
-
}
|
|
260
|
+
plugins,
|
|
261
|
+
pluginMap
|
|
254
262
|
});
|
|
255
263
|
const typesPath = virtualTypesPath || (serviceName ? `#graphql/client/${serviceName}` : "#graphql/client");
|
|
256
264
|
const sdkOutput = await preset.buildGeneratesSection({
|
|
@@ -262,7 +270,7 @@ export function getSdk(requester: Requester): Sdk {
|
|
|
262
270
|
plugins: [{ pluginContent: {} }, { typescriptGenericSdk: {} }],
|
|
263
271
|
pluginMap: {
|
|
264
272
|
pluginContent: { plugin: pluginContent },
|
|
265
|
-
typescriptGenericSdk: { plugin: plugin$
|
|
273
|
+
typescriptGenericSdk: { plugin: plugin$2 }
|
|
266
274
|
}
|
|
267
275
|
});
|
|
268
276
|
const sdkContent = (await Promise.all(sdkOutput.map(async (config$1) => {
|
|
@@ -232,7 +232,6 @@ async function serverTypeGeneration(app) {
|
|
|
232
232
|
if (serverTypesPath) {
|
|
233
233
|
mkdirSync(dirname(serverTypesPath), { recursive: true });
|
|
234
234
|
writeFileSync(serverTypesPath, data, "utf-8");
|
|
235
|
-
consola.success(`[nitro-graphql] Generated server types at: ${serverTypesPath}`);
|
|
236
235
|
}
|
|
237
236
|
} catch (error) {
|
|
238
237
|
consola.error("Server schema generation error:", error);
|
|
@@ -293,13 +292,11 @@ async function generateMainClientTypes(nitro) {
|
|
|
293
292
|
if (clientTypesPath) {
|
|
294
293
|
mkdirSync(dirname(clientTypesPath), { recursive: true });
|
|
295
294
|
writeFileSync(clientTypesPath, types.types, "utf-8");
|
|
296
|
-
consola.success(`[nitro-graphql] Generated client types at: ${clientTypesPath}`);
|
|
297
295
|
}
|
|
298
296
|
const sdkPath = resolveFilePath(sdkConfig.main, sdkConfig.enabled, true, "{clientGraphql}/default/sdk.ts", placeholders);
|
|
299
297
|
if (sdkPath) {
|
|
300
298
|
mkdirSync(dirname(sdkPath), { recursive: true });
|
|
301
299
|
writeFileSync(sdkPath, types.sdk, "utf-8");
|
|
302
|
-
consola.success(`[nitro-graphql] Generated SDK at: ${sdkPath}`);
|
|
303
300
|
}
|
|
304
301
|
if (nitro.options.framework?.name === "nuxt") {
|
|
305
302
|
generateNuxtOfetchClient(nitro, nitro.graphql.clientDir, "default");
|
|
@@ -310,7 +307,6 @@ async function generateMainClientTypes(nitro) {
|
|
|
310
307
|
async function generateExternalServicesTypes(nitro) {
|
|
311
308
|
const externalServices = nitro.options.graphql?.externalServices || [];
|
|
312
309
|
for (const service of externalServices) try {
|
|
313
|
-
consola.info(`[graphql:${service.name}] Processing external service`);
|
|
314
310
|
await downloadAndSaveSchema(service, nitro.options.buildDir);
|
|
315
311
|
const schema = await loadExternalSchema(service, nitro.options.buildDir);
|
|
316
312
|
if (!schema) {
|
|
@@ -344,16 +340,13 @@ async function generateExternalServicesTypes(nitro) {
|
|
|
344
340
|
if (serviceTypesPath) {
|
|
345
341
|
mkdirSync(dirname(serviceTypesPath), { recursive: true });
|
|
346
342
|
writeFileSync(serviceTypesPath, types.types, "utf-8");
|
|
347
|
-
consola.success(`[graphql:${service.name}] Generated types at: ${serviceTypesPath}`);
|
|
348
343
|
}
|
|
349
344
|
const serviceSdkPath = resolveFilePath(service.paths?.sdk ?? sdkConfig.external, sdkConfig.enabled, true, "{clientGraphql}/{serviceName}/sdk.ts", placeholders);
|
|
350
345
|
if (serviceSdkPath) {
|
|
351
346
|
mkdirSync(dirname(serviceSdkPath), { recursive: true });
|
|
352
347
|
writeFileSync(serviceSdkPath, types.sdk, "utf-8");
|
|
353
|
-
consola.success(`[graphql:${service.name}] Generated SDK at: ${serviceSdkPath}`);
|
|
354
348
|
}
|
|
355
349
|
if (nitro.options.framework?.name === "nuxt") generateExternalOfetchClient(nitro, service, service.endpoint);
|
|
356
|
-
consola.success(`[graphql:${service.name}] External service types generated successfully`);
|
|
357
350
|
} catch (error) {
|
|
358
351
|
consola.error(`[graphql:${service.name}] External service generation failed:`, error);
|
|
359
352
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-graphql",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.7.
|
|
4
|
+
"version": "1.7.1",
|
|
5
5
|
"description": "GraphQL integration for Nitro",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -55,10 +55,6 @@
|
|
|
55
55
|
"./nuxt": {
|
|
56
56
|
"types": "./dist/ecosystem/nuxt.d.mts",
|
|
57
57
|
"import": "./dist/ecosystem/nuxt.mjs"
|
|
58
|
-
},
|
|
59
|
-
"./subscribe": {
|
|
60
|
-
"types": "./dist/subscribe/index.d.mts",
|
|
61
|
-
"import": "./dist/subscribe/index.mjs"
|
|
62
58
|
}
|
|
63
59
|
},
|
|
64
60
|
"module": "./dist/index.mjs",
|
|
@@ -89,10 +85,11 @@
|
|
|
89
85
|
"@apollo/subgraph": "^2.12.2",
|
|
90
86
|
"@graphql-codegen/core": "^5.0.0",
|
|
91
87
|
"@graphql-codegen/import-types-preset": "^3.0.1",
|
|
92
|
-
"@graphql-codegen/
|
|
88
|
+
"@graphql-codegen/typed-document-node": "^6.1.5",
|
|
89
|
+
"@graphql-codegen/typescript": "^5.0.7",
|
|
93
90
|
"@graphql-codegen/typescript-generic-sdk": "^4.0.2",
|
|
94
|
-
"@graphql-codegen/typescript-operations": "^5.0.
|
|
95
|
-
"@graphql-codegen/typescript-resolvers": "^5.1.
|
|
91
|
+
"@graphql-codegen/typescript-operations": "^5.0.7",
|
|
92
|
+
"@graphql-codegen/typescript-resolvers": "^5.1.5",
|
|
96
93
|
"@graphql-tools/graphql-file-loader": "^8.1.8",
|
|
97
94
|
"@graphql-tools/load": "^8.1.7",
|
|
98
95
|
"@graphql-tools/load-files": "^7.0.1",
|
|
@@ -107,24 +104,24 @@
|
|
|
107
104
|
"graphql-scalars": "^1.25.0",
|
|
108
105
|
"knitwork": "^1.3.0",
|
|
109
106
|
"ohash": "^2.0.11",
|
|
110
|
-
"oxc-parser": "^0.
|
|
107
|
+
"oxc-parser": "^0.104.0",
|
|
111
108
|
"pathe": "^2.0.3",
|
|
112
109
|
"tinyglobby": "^0.2.15"
|
|
113
110
|
},
|
|
114
111
|
"devDependencies": {
|
|
115
|
-
"@antfu/eslint-config": "^6.
|
|
112
|
+
"@antfu/eslint-config": "^6.7.2",
|
|
116
113
|
"@nuxt/kit": "^4.2.2",
|
|
117
114
|
"@nuxt/schema": "^4.2.2",
|
|
118
|
-
"@types/node": "^
|
|
115
|
+
"@types/node": "^25.0.3",
|
|
119
116
|
"bumpp": "^10.3.2",
|
|
120
117
|
"changelogen": "^0.6.2",
|
|
121
118
|
"crossws": "0.3.5",
|
|
122
|
-
"eslint": "^9.39.
|
|
119
|
+
"eslint": "^9.39.2",
|
|
123
120
|
"graphql": "16.11.0",
|
|
124
|
-
"graphql-yoga": "^5.
|
|
121
|
+
"graphql-yoga": "^5.18.0",
|
|
125
122
|
"h3": "1.15.3",
|
|
126
123
|
"nitropack": "^2.12.9",
|
|
127
|
-
"tsdown": "^0.
|
|
124
|
+
"tsdown": "^0.18.2",
|
|
128
125
|
"typescript": "^5.9.3",
|
|
129
126
|
"vitepress-plugin-llms": "^1.9.3"
|
|
130
127
|
},
|
|
@@ -143,7 +140,6 @@
|
|
|
143
140
|
"docs:build": "cd .docs && pnpm install && pnpm build",
|
|
144
141
|
"docs:preview": "cd .docs && pnpm preview",
|
|
145
142
|
"lint": "eslint .",
|
|
146
|
-
"lint:fix": "eslint . --fix"
|
|
147
|
-
"typecheck": "tsc --noEmit"
|
|
143
|
+
"lint:fix": "eslint . --fix"
|
|
148
144
|
}
|
|
149
145
|
}
|