nitro-graphql 0.0.1 → 0.0.2

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.
Files changed (44) hide show
  1. package/README.md +14 -14
  2. package/dist/client-watcher-DpYM5JpN.js +101 -0
  3. package/dist/client-watcher-DpYM5JpN.js.map +1 -0
  4. package/dist/client-watcher.d.ts +1 -1
  5. package/dist/client-watcher.d.ts.map +1 -1
  6. package/dist/client-watcher.js +4 -91
  7. package/dist/{codegen-Dbw6gEZt.js → codegen-JCUglvgC.js} +1 -1
  8. package/dist/{codegen-Dbw6gEZt.js.map → codegen-JCUglvgC.js.map} +1 -1
  9. package/dist/codegen.d.ts +16 -2
  10. package/dist/codegen.d.ts.map +1 -0
  11. package/dist/codegen.js +1 -1
  12. package/dist/context.d.ts +13 -2
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +0 -1
  15. package/dist/index.d.ts +1 -5
  16. package/dist/index.js +158 -323
  17. package/dist/index.js.map +1 -1
  18. package/dist/prerender-BWFqvlWv.js +280 -0
  19. package/dist/prerender-BWFqvlWv.js.map +1 -0
  20. package/dist/{scanner-BdcKEPQk.js → scanner-DA9Zg-ri.js} +4 -4
  21. package/dist/scanner-DA9Zg-ri.js.map +1 -0
  22. package/dist/{types-D_NqyCcy.d.ts → types-BLYuSc3f.d.ts} +3 -2
  23. package/dist/{types-D_NqyCcy.d.ts.map → types-BLYuSc3f.d.ts.map} +1 -1
  24. package/dist/utils-C7-cM2zI.js +24 -0
  25. package/dist/utils-C7-cM2zI.js.map +1 -0
  26. package/dist/utils.d.ts +16 -3
  27. package/dist/utils.d.ts.map +1 -0
  28. package/dist/utils.js +2 -2
  29. package/package.json +4 -4
  30. package/dist/client-watcher.js.map +0 -1
  31. package/dist/codegen-DWJuLowd.d.ts +0 -16
  32. package/dist/codegen-DWJuLowd.d.ts.map +0 -1
  33. package/dist/context-BgqNJFCT.d.ts +0 -13
  34. package/dist/context-BgqNJFCT.d.ts.map +0 -1
  35. package/dist/context-CZdhkJYD.js +0 -0
  36. package/dist/scanner-BdcKEPQk.js.map +0 -1
  37. package/dist/utils-87_22aIA.js +0 -41
  38. package/dist/utils-87_22aIA.js.map +0 -1
  39. package/dist/utils-BuYDOLIi.d.ts +0 -22
  40. package/dist/utils-BuYDOLIi.d.ts.map +0 -1
  41. package/dist/watcher.d.ts +0 -9
  42. package/dist/watcher.d.ts.map +0 -1
  43. package/dist/watcher.js +0 -96
  44. package/dist/watcher.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,19 +1,126 @@
1
- import { scanGraphQLFiles } from "./scanner-BdcKEPQk.js";
2
- import { createResolver, defineGraphQLResolver, defineYogaConfig } from "./utils-87_22aIA.js";
3
- import { generateTypes } from "./codegen-Dbw6gEZt.js";
4
- import "./context-CZdhkJYD.js";
1
+ import { scanGraphQLFiles } from "./scanner-DA9Zg-ri.js";
2
+ import { debounce } from "./utils-C7-cM2zI.js";
3
+ import { setupClientWatcher } from "./client-watcher-DpYM5JpN.js";
4
+ import { generateTypes } from "./codegen-JCUglvgC.js";
5
5
  import { mkdir, writeFile } from "node:fs/promises";
6
6
  import { mergeTypeDefs } from "@graphql-tools/merge";
7
7
  import { makeExecutableSchema } from "@graphql-tools/schema";
8
8
  import { consola } from "consola";
9
9
  import { join } from "pathe";
10
+ import { existsSync } from "node:fs";
10
11
  import { defineNitroModule } from "nitropack/kit";
12
+ import { watch } from "chokidar";
11
13
 
12
- //#region src/index.ts
14
+ //#region src/dev.ts
13
15
  const logger = consola.withTag("graphql");
16
+ async function regenerateGraphQLTypes(nitro) {
17
+ try {
18
+ const scanResult = await scanGraphQLFiles(nitro);
19
+ if (scanResult.typeDefs.length === 0) {
20
+ logger.warn("⚠️ No schema files found");
21
+ return;
22
+ }
23
+ const mergedTypeDefs = mergeTypeDefs(scanResult.typeDefs);
24
+ const schema = makeExecutableSchema({
25
+ typeDefs: mergedTypeDefs,
26
+ resolvers: {}
27
+ });
28
+ const generatedTypes = await generateTypes(schema);
29
+ const outputPath = join(nitro.options.buildDir, "types", "graphql-types.generated.ts");
30
+ const typesDir = join(nitro.options.buildDir, "types");
31
+ await mkdir(typesDir, { recursive: true });
32
+ await writeFile(outputPath, generatedTypes);
33
+ const graphqlDtsPath = join(typesDir, "graphql.d.ts");
34
+ console.log("graphqlDtsPath", graphqlDtsPath);
35
+ const graphqlDtsContent = `// Auto-generated by nitro-graphql
36
+ import type { Resolvers as Test } from './graphql-types.generated'
37
+
38
+ declare module 'nitro-graphql' {
39
+ interface Resolvers extends Test {}
40
+ }
41
+ `;
42
+ await writeFile(graphqlDtsPath, graphqlDtsContent);
43
+ logger.success("✨ Types regenerated");
44
+ } catch (error) {
45
+ const errorMessage = error instanceof Error ? error.message : String(error);
46
+ logger.error("❌ Type generation failed:", errorMessage);
47
+ }
48
+ }
49
+ function devmode(nitro, options) {
50
+ if (nitro.options.dev) {
51
+ const generateTypesDebounced = debounce(async () => {
52
+ await regenerateGraphQLTypes(nitro);
53
+ }, 300);
54
+ const graphqlDir = join(nitro.options.srcDir, "graphql");
55
+ logger.info("🔍 Setting up independent GraphQL watcher for directory:", graphqlDir);
56
+ try {
57
+ if (!existsSync(graphqlDir)) {
58
+ logger.warn(`⚠️ GraphQL directory not found: ${graphqlDir}`);
59
+ return;
60
+ }
61
+ } catch (error) {
62
+ logger.warn("⚠️ Could not check GraphQL directory:", error);
63
+ return;
64
+ }
65
+ const graphqlWatcher = watch(graphqlDir, {
66
+ ignoreInitial: true,
67
+ persistent: true,
68
+ usePolling: true,
69
+ interval: 500,
70
+ depth: 10
71
+ });
72
+ graphqlWatcher.on("add", (path) => {
73
+ logger.info("📁 GraphQL file added:", path);
74
+ generateTypesDebounced();
75
+ });
76
+ graphqlWatcher.on("change", (path) => {
77
+ logger.info("📝 GraphQL file changed:", path);
78
+ generateTypesDebounced();
79
+ });
80
+ graphqlWatcher.on("unlink", (path) => {
81
+ logger.info("🗑️ GraphQL file deleted:", path);
82
+ generateTypesDebounced();
83
+ });
84
+ graphqlWatcher.on("error", (error) => {
85
+ logger.error("❌ GraphQL watcher error:", error);
86
+ });
87
+ graphqlWatcher.on("raw", (event, path) => {
88
+ if (event === "change" && path && path.endsWith("graphql")) {
89
+ logger.info("📝 GraphQL directory change detected, regenerating types");
90
+ generateTypesDebounced();
91
+ }
92
+ });
93
+ graphqlWatcher.on("ready", () => {
94
+ logger.success("✅ GraphQL file watcher ready");
95
+ });
96
+ nitro.hooks.hook("close", async () => {
97
+ await graphqlWatcher.close();
98
+ logger.info("🔒 GraphQL watcher closed");
99
+ });
100
+ setupClientWatcher(nitro, options);
101
+ logger.success("✅ Independent GraphQL watcher set up");
102
+ }
103
+ }
104
+
105
+ //#endregion
106
+ //#region src/index.ts
14
107
  var src_default = defineNitroModule({
15
108
  name: "nitro:graphql-yoga",
16
109
  async setup(nitro) {
110
+ if (!nitro.options.dev) {
111
+ nitro.options.rollupConfig ??= {};
112
+ if (nitro.options.rollupConfig) {
113
+ nitro.options.rollupConfig.plugins ??= [];
114
+ const originalExternal = nitro.options.rollupConfig.external;
115
+ nitro.options.rollupConfig.external = (id, parentId, isResolved) => {
116
+ if (id.startsWith("./dev")) return true;
117
+ if (id.startsWith("./prerender") && !nitro.options.prerender) return true;
118
+ if (typeof originalExternal === "function") return originalExternal(id, parentId, isResolved);
119
+ if (Array.isArray(originalExternal)) return originalExternal.includes(id);
120
+ return false;
121
+ };
122
+ }
123
+ }
17
124
  const options = {
18
125
  endpoint: "/api/graphql",
19
126
  playground: true,
@@ -23,7 +130,7 @@ var src_default = defineNitroModule({
23
130
  maxAge: 604800
24
131
  },
25
132
  client: {
26
- enabled: false,
133
+ enabled: nitro.options.framework?.name === "nuxt",
27
134
  outputPath: void 0,
28
135
  watchPatterns: void 0,
29
136
  config: {
@@ -36,90 +143,17 @@ var src_default = defineNitroModule({
36
143
  ...nitro.options.graphqlYoga,
37
144
  ...nitro.options.runtimeConfig?.graphqlYoga
38
145
  };
39
- const graphqlPath = join(nitro.options.srcDir, "graphql");
40
- nitro.hooks.hook("rollup:before", (nitro$1, rollupConfig) => {
41
- rollupConfig.external = rollupConfig.external || [];
42
- const codegenExternals = [
43
- "@graphql-codegen/core",
44
- "@graphql-codegen/typescript",
45
- "@graphql-codegen/typescript-resolvers",
46
- "@graphql-codegen/typescript-operations",
47
- "@graphql-codegen/typescript-generic-sdk",
48
- "@graphql-tools/graphql-file-loader",
49
- "@graphql-tools/load"
50
- ];
51
- if (Array.isArray(rollupConfig.external)) rollupConfig.external.push(...codegenExternals);
52
- else if (typeof rollupConfig.external === "function") {
53
- const originalExternal = rollupConfig.external;
54
- rollupConfig.external = (id, parent, isResolved) => {
55
- if (codegenExternals.some((external) => id.includes(external))) return true;
56
- return originalExternal(id, parent, isResolved);
57
- };
58
- }
59
- const originalChunkFileNames = rollupConfig.output.chunkFileNames;
60
- rollupConfig.output.chunkFileNames = (chunk) => {
61
- const allIds = chunk.moduleIds || [];
62
- const hasGraphQLResolverFile = allIds.some((id) => id.includes(graphqlPath) && !id.includes("node_modules") && !id.includes("#nitro-graphql") && (id.endsWith(".ts") || id.endsWith(".js") || id.endsWith(".mjs")));
63
- if (hasGraphQLResolverFile) return `chunks/graphql/[name].mjs`;
64
- if (typeof originalChunkFileNames === "function") return originalChunkFileNames(chunk);
65
- return originalChunkFileNames || "chunks/_/[name].mjs";
66
- };
67
- });
146
+ devmode(nitro, options);
68
147
  nitro.options.virtual ??= {};
69
148
  nitro.options.virtual["#nitro-graphql/context"] = () => `
70
149
  export type { GraphQLContext } from 'nitro-graphql/context'
71
150
  `;
72
- const scanResult = await scanGraphQLFiles(nitro);
73
- if (scanResult.resolvers.length > 0) logger.success(`Found ${scanResult.resolvers.length} resolvers`);
74
- if (scanResult.typeDefs.length > 0) {
75
- const mergedTypeDefs = mergeTypeDefs(scanResult.typeDefs);
76
- const schema = makeExecutableSchema({
77
- typeDefs: mergedTypeDefs,
78
- resolvers: {}
79
- });
80
- const { generateTypes: generateTypes$1 } = await new Function("return import(\"nitro-graphql/codegen\")")();
81
- const generatedTypes = await generateTypes$1(schema);
82
- const outputPath = join(nitro.options.buildDir, "types", "graphql-types.generated.ts");
83
- const typesDir = join(nitro.options.buildDir, "types");
84
- await mkdir(typesDir, { recursive: true });
85
- await writeFile(outputPath, generatedTypes);
86
- const graphqlDtsPath = join(typesDir, "graphql.d.ts");
87
- const graphqlDtsContent = `// Auto-generated by nitro-graphql
88
- import type { Resolvers as Test } from './graphql-types.generated'
89
-
90
- declare module 'nitro-graphql' {
91
- interface Resolvers extends Test {}
92
- }
93
- `;
94
- await writeFile(graphqlDtsPath, graphqlDtsContent);
95
- logger.success("Types generated");
96
- } else {
97
- const typesDir = join(nitro.options.buildDir, "types");
98
- await mkdir(typesDir, { recursive: true });
99
- const minimalTypes = `// Generated by nitro-graphql (no schema found)
100
- export type Resolvers = any
101
- `;
102
- const outputPath = join(typesDir, "graphql-types.generated.ts");
103
- await writeFile(outputPath, minimalTypes);
104
- const graphqlDtsPath = join(typesDir, "graphql.d.ts");
105
- const graphqlDtsContent = `// Auto-generated by nitro-graphql
106
- import type { Resolvers as Test } from './graphql-types.generated'
107
-
108
- declare module 'nitro-graphql' {
109
- interface Resolvers extends Test {}
110
- }
111
- `;
112
- await writeFile(graphqlDtsPath, graphqlDtsContent);
113
- logger.info("Created minimal types (no schema found)");
114
- }
115
- if (nitro.options.dev) {
116
- const setupGraphQLWatcher = (await new Function("return import(\"nitro-graphql/watcher\")")()).setupGraphQLWatcher;
117
- const setupClientWatcher = (await new Function("return import(\"nitro-graphql/client-watcher\")")()).setupClientWatcher;
118
- await setupGraphQLWatcher(nitro);
119
- await setupClientWatcher(nitro, options);
120
- }
121
151
  nitro.options.handlers = nitro.options.handlers || [];
122
152
  const endpoint = options.endpoint || "/api/graphql";
153
+ if (nitro.options.prerender || nitro.options.dev) {
154
+ const { prerender } = await import("./prerender-BWFqvlWv.js");
155
+ await prerender(nitro, options);
156
+ }
123
157
  nitro.options.handlers.push({
124
158
  route: endpoint,
125
159
  handler: "#nitro-graphql/handler",
@@ -140,228 +174,6 @@ declare module 'nitro-graphql' {
140
174
  handler: "#nitro-graphql/health",
141
175
  method: "get"
142
176
  });
143
- nitro.options.virtual["#nitro-graphql/handler"] = () => `
144
- import { createYoga } from 'graphql-yoga'
145
- import { defineEventHandler, readRawBody, setHeader, setResponseStatus } from 'h3'
146
- import { useStorage } from 'nitro/runtime'
147
- import { makeExecutableSchema } from '@graphql-tools/schema'
148
- import { mergeTypeDefs, mergeResolvers } from '@graphql-tools/merge'
149
- import { join } from 'pathe'
150
- // Types are generated at build time to .nitro/graphql-types.generated.ts
151
-
152
- // GraphQL Context type is injected via context module
153
-
154
- // Create resolver helper
155
- globalThis.createResolver = function(resolvers) {
156
- return resolvers
157
- }
158
-
159
- // Dynamic schema loading function
160
- async function loadTypeDefs() {
161
- const schemaPath = join('${nitro.options.srcDir}', 'graphql', '**', '*.graphql')
162
- const { loadFilesSync } = await import('@graphql-tools/load-files')
163
- return loadFilesSync(schemaPath, {
164
- recursive: true,
165
- })
166
- }
167
-
168
- // Load resolvers using dynamic imports (Nitro handles the bundling)
169
- const resolverImports = [
170
- ${scanResult.resolvers.map((resolver) => ` () => import('${resolver.path}')`).join(",\n")}
171
- ]
172
-
173
- // Async function to load resolvers
174
- async function loadResolvers() {
175
- let resolvers = {}
176
- try {
177
- if (resolverImports.length > 0) {
178
- const resolverModules = []
179
-
180
- for (let i = 0; i < resolverImports.length; i++) {
181
- try {
182
- const resolverModule = await resolverImports[i]()
183
- const resolver = resolverModule.default || resolverModule
184
-
185
- if (resolver) {
186
- resolverModules.push(resolver)
187
- }
188
- } catch (error) {
189
- console.warn('[graphql] Failed to load resolver:', i, error.message)
190
- }
191
- }
192
-
193
- if (resolverModules.length > 0) {
194
- resolvers = mergeResolvers(resolverModules)
195
- } else {
196
- console.warn('[graphql] No resolvers could be loaded')
197
- resolvers = { Query: {}, Mutation: {} }
198
- }
199
- } else {
200
- console.warn('[graphql] No resolvers found')
201
- resolvers = { Query: {}, Mutation: {} }
202
- }
203
- } catch (error) {
204
- console.warn('[graphql] Error loading resolvers:', error.message)
205
- resolvers = { Query: {}, Mutation: {} }
206
- }
207
- return resolvers
208
- }
209
-
210
- // Apollo Sandbox HTML with 1 week cache
211
- const apolloSandboxHtml = \`<!DOCTYPE html>
212
- <html lang="en">
213
- <body style="margin: 0; overflow-x: hidden; overflow-y: hidden">
214
- <div id="sandbox" style="height:100vh; width:100vw;"></div>
215
- <script src="https://embeddable-sandbox.cdn.apollographql.com/02e2da0fccbe0240ef03d2396d6c98559bab5b06/embeddable-sandbox.umd.production.min.js"><\/script>
216
- <script>
217
- new window.EmbeddedSandbox({
218
- target: "#sandbox",
219
- initialEndpoint: window.location.href,
220
- hideCookieToggle: false,
221
- initialState: {
222
- includeCookies: true
223
- }
224
- });
225
- <\/script>
226
- </body>
227
- </html>\`
228
-
229
- // Set cache headers for Apollo Sandbox HTML (1 week = 604800 seconds)
230
- function setApolloSandboxCacheHeaders(event) {
231
- setHeader(event, 'Cache-Control', 'public, max-age=604800, s-maxage=604800')
232
- setHeader(event, 'Expires', new Date(Date.now() + 604800000).toUTCString())
233
- setHeader(event, 'ETag', \`"apollo-sandbox-\${Date.now()}"\`)
234
- }
235
-
236
- // Lazy initialization
237
- let yoga = null
238
- let initPromise = null
239
-
240
- async function getYoga() {
241
- // In development mode, always reload schema for hot updates
242
- const isDev = ${nitro.options.dev}
243
- if (yoga && !isDev) return yoga
244
-
245
- if (!initPromise || isDev) {
246
- // Reset yoga instance in development mode
247
- if (isDev) {
248
- yoga = null
249
- }
250
-
251
- initPromise = (async () => {
252
- // Load custom yoga config first (separate from resolvers)
253
- let customYogaConfig = {}
254
- ${scanResult.yogaConfigPath ? `
255
- try {
256
- const yogaConfigModule = await import('${scanResult.yogaConfigPath}')
257
- customYogaConfig = yogaConfigModule.default || yogaConfigModule
258
- } catch (error) {
259
- console.warn('[graphql] Failed to load yoga config:', error.message)
260
- }` : ""}
261
-
262
- const resolvers = await loadResolvers()
263
- const typeDefs = await loadTypeDefs()
264
-
265
- // Merge schema and resolvers (without yoga config interfering)
266
- const schema = makeExecutableSchema({
267
- typeDefs: mergeTypeDefs(typeDefs),
268
- resolvers,
269
- })
270
-
271
- // Default yoga configuration
272
- const defaultYogaConfig = {
273
- schema,
274
- context: async ({ request }) => {
275
- const event = request.$$event
276
- return {
277
- event,
278
- request,
279
- storage: useStorage(),
280
- }
281
- },
282
- graphqlEndpoint: '${endpoint}',
283
- graphiql: ${options.playground !== false},
284
- renderGraphiQL: () => apolloSandboxHtml,
285
- landingPage: false,
286
- cors: ${JSON.stringify(options.cors || false)},
287
- }
288
-
289
- // Clean up custom config (remove properties that could be mistaken for GraphQL resolvers)
290
- const cleanCustomConfig = { ...customYogaConfig }
291
-
292
- // Remove empty arrays and functions that GraphQL Tools might confuse with resolvers
293
- if (Array.isArray(cleanCustomConfig.plugins) && cleanCustomConfig.plugins.length === 0) {
294
- delete cleanCustomConfig.plugins
295
- }
296
-
297
- // Remove these yoga-specific configs from resolver merging
298
- const yogaOnlyConfigs = ['context', 'plugins', 'maskedErrors', 'graphiql', 'cors']
299
- const cleanResolverConfig = { ...cleanCustomConfig }
300
- yogaOnlyConfigs.forEach(key => {
301
- delete cleanResolverConfig[key]
302
- })
303
-
304
- // Merge custom config with defaults
305
- const yogaConfig = {
306
- ...defaultYogaConfig,
307
- ...cleanCustomConfig,
308
- // Always override schema and endpoint from default config
309
- schema,
310
- graphqlEndpoint: '${endpoint}',
311
- }
312
-
313
- yoga = createYoga(yogaConfig)
314
-
315
- return yoga
316
- })()
317
- }
318
-
319
- return initPromise
320
- }
321
-
322
- export default defineEventHandler(async (event) => {
323
- const { req } = event.node
324
- const host = req.headers.host || 'localhost'
325
- const protocol = 'http'
326
- const url = new URL(req.url || '/', protocol + '://' + host)
327
-
328
- // Attach event to request for context
329
- req.$$event = event
330
-
331
- const yogaInstance = await getYoga()
332
- const response = await yogaInstance.fetch(url.toString(), {
333
- method: req.method || 'GET',
334
- headers: req.headers,
335
- body: req.method !== 'GET' && req.method !== 'HEAD' ? await readRawBody(event) : undefined,
336
- }, {
337
- event,
338
- })
339
-
340
- // Set response headers
341
- response.headers.forEach((value, key) => {
342
- setHeader(event, key, value)
343
- })
344
-
345
- // Set status code
346
- setResponseStatus(event, response.status)
347
-
348
- // Return response body
349
- if (response.body) {
350
- const contentType = response.headers.get('content-type')
351
- if (contentType?.includes('text/html')) {
352
- // Set cache headers for Apollo Sandbox HTML
353
- setApolloSandboxCacheHeaders(event)
354
- return await response.text()
355
- }
356
- if (contentType?.includes('application/json')) {
357
- return await response.text()
358
- }
359
- return response.body
360
- }
361
-
362
- return null
363
- })
364
- `;
365
177
  nitro.options.virtual["#nitro-graphql/health"] = () => `
366
178
  import { defineEventHandler, setResponseStatus } from 'h3'
367
179
 
@@ -399,26 +211,49 @@ export default defineEventHandler(async (event) => {
399
211
  })
400
212
  `;
401
213
  if (nitro.options.imports) nitro.options.imports.presets.push({
402
- from: "nitro-graphql",
403
- imports: [
404
- "createResolver",
405
- "defineGraphQLResolver",
406
- "defineGraphQLSchema",
407
- "defineGraphQLResolvers",
408
- "defineYogaConfig",
409
- "gql"
410
- ]
214
+ from: "nitro-graphql/utils",
215
+ imports: ["defineResolver", "defineYogaConfig"]
216
+ });
217
+ nitro.hooks.hook("types:extend", (types) => {
218
+ types.tsConfig ||= {};
219
+ types.tsConfig.compilerOptions ??= {};
220
+ types.tsConfig.compilerOptions.paths ??= {};
221
+ types.tsConfig.compilerOptions.paths["#build/graphql-types.generated"] = [join(nitro.options.buildDir, "types", "graphql-types.generated.ts")];
222
+ types.tsConfig.include = types.tsConfig.include || [];
223
+ types.tsConfig.include.push(join(nitro.options.buildDir, "types", "graphql-types.generated.ts"), join(nitro.options.buildDir, "types", "graphql.d.ts"));
224
+ });
225
+ const graphqlPath = join(nitro.options.srcDir, "graphql");
226
+ nitro.hooks.hook("rollup:before", (nitro$1, rollupConfig) => {
227
+ rollupConfig.external = rollupConfig.external || [];
228
+ const codegenExternals = [
229
+ "@graphql-codegen/core",
230
+ "@graphql-codegen/typescript",
231
+ "@graphql-codegen/typescript-resolvers",
232
+ "@graphql-codegen/typescript-operations",
233
+ "@graphql-codegen/typescript-generic-sdk",
234
+ "@graphql-tools/graphql-file-loader",
235
+ "@graphql-tools/load"
236
+ ];
237
+ if (Array.isArray(rollupConfig.external)) rollupConfig.external.push(...codegenExternals);
238
+ else if (typeof rollupConfig.external === "function") {
239
+ const originalExternal = rollupConfig.external;
240
+ rollupConfig.external = (id, parent, isResolved) => {
241
+ if (codegenExternals.some((external) => id.includes(external))) return true;
242
+ return originalExternal(id, parent, isResolved);
243
+ };
244
+ }
245
+ const originalChunkFileNames = rollupConfig.output.chunkFileNames;
246
+ rollupConfig.output.chunkFileNames = (chunk) => {
247
+ const allIds = chunk.moduleIds || [];
248
+ const hasGraphQLResolverFile = allIds.some((id) => id.includes(graphqlPath) && !id.includes("node_modules") && !id.includes("#nitro-graphql") && (id.endsWith(".ts") || id.endsWith(".js") || id.endsWith(".mjs")));
249
+ if (hasGraphQLResolverFile) return `chunks/graphql/[name].mjs`;
250
+ if (typeof originalChunkFileNames === "function") return originalChunkFileNames(chunk);
251
+ return originalChunkFileNames || "chunks/_/[name].mjs";
252
+ };
411
253
  });
412
- nitro.options.typescript ??= {};
413
- nitro.options.typescript.tsConfig ??= {};
414
- nitro.options.typescript.tsConfig.compilerOptions ??= {};
415
- nitro.options.typescript.tsConfig.compilerOptions.paths ??= {};
416
- nitro.options.typescript.tsConfig.compilerOptions.paths["#build/graphql-types.generated"] = [join(nitro.options.buildDir, "types", "graphql-types.generated.ts")];
417
- nitro.options.typescript.tsConfig.include = nitro.options.typescript.tsConfig.include || [];
418
- nitro.options.typescript.tsConfig.include.push(join(nitro.options.buildDir, "types", "graphql-types.generated.ts"), join(nitro.options.buildDir, "types", "graphql.d.ts"));
419
254
  }
420
255
  });
421
256
 
422
257
  //#endregion
423
- export { createResolver, src_default as default, defineGraphQLResolver, defineYogaConfig, generateTypes };
258
+ export { src_default as default };
424
259
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["nitro: Nitro","options: NitroGraphQLOptions","nitro"],"sources":["../src/index.ts"],"sourcesContent":["import type { Nitro } from 'nitropack/types'\nimport type { NitroGraphQLOptions } from './types'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { mergeTypeDefs } from '@graphql-tools/merge'\nimport { makeExecutableSchema } from '@graphql-tools/schema'\nimport { consola } from 'consola'\nimport { defineNitroModule } from 'nitropack/kit'\nimport { join } from 'pathe'\n// import { generateTypes } from './codegen' // Conditionally imported to prevent bundling\nimport { scanGraphQLFiles } from './scanner'\n\nconst logger = consola.withTag('graphql')\n\nexport default defineNitroModule({\n name: 'nitro:graphql-yoga',\n async setup(nitro: Nitro) {\n // console.log('Setting up nitro:graphql-yoga module', nitro.options.framework)\n // Get module options from nitro config\n const options: NitroGraphQLOptions = {\n endpoint: '/api/graphql',\n playground: true,\n cors: false,\n cacheHeaders: {\n enabled: true,\n maxAge: 604800, // 1 week\n },\n client: {\n enabled: false,\n outputPath: undefined, // Will default to buildDir/types/graphql-client.generated.ts\n watchPatterns: undefined, // Will default to src/**/*.{graphql,gql} excluding server/graphql\n config: {\n documentMode: 'string',\n emitLegacyCommonJSImports: false,\n useTypeImports: true,\n enumsAsTypes: true,\n },\n },\n // Merge with user config from nitro.options\n ...(nitro.options as any).graphqlYoga,\n // Fallback to runtimeConfig for backward compatibility\n ...nitro.options.runtimeConfig?.graphqlYoga,\n }\n // Add GraphQL path to known chunk prefixes\n const graphqlPath = join(nitro.options.srcDir, 'graphql')\n\n // Access the internal rollup config and add our prefix\n nitro.hooks.hook('rollup:before', (nitro, rollupConfig) => {\n // Add codegen packages as external dependencies to prevent bundling\n rollupConfig.external = rollupConfig.external || []\n const codegenExternals = [\n '@graphql-codegen/core',\n '@graphql-codegen/typescript',\n '@graphql-codegen/typescript-resolvers',\n '@graphql-codegen/typescript-operations',\n '@graphql-codegen/typescript-generic-sdk',\n '@graphql-tools/graphql-file-loader',\n '@graphql-tools/load',\n ]\n\n if (Array.isArray(rollupConfig.external)) {\n rollupConfig.external.push(...codegenExternals)\n }\n else if (typeof rollupConfig.external === 'function') {\n const originalExternal = rollupConfig.external\n rollupConfig.external = (id, parent, isResolved) => {\n if (codegenExternals.some(external => id.includes(external))) {\n return true\n }\n return originalExternal(id, parent, isResolved)\n }\n }\n\n // Add GraphQL path to chunkNamePrefixes\n const originalChunkFileNames = rollupConfig.output.chunkFileNames\n rollupConfig.output.chunkFileNames = (chunk) => {\n // Only GraphQL resolvers (actual resolver files) should go to graphql folder\n const allIds = chunk.moduleIds || []\n\n const hasGraphQLResolverFile = allIds.some(id =>\n // Only server/graphql resolver files (not node_modules, not virtual modules)\n id.includes(graphqlPath)\n && !id.includes('node_modules')\n && !id.includes('#nitro-graphql')\n && (id.endsWith('.ts') || id.endsWith('.js') || id.endsWith('.mjs')),\n )\n\n if (hasGraphQLResolverFile) {\n return `chunks/graphql/[name].mjs`\n }\n // Use original logic for other chunks\n if (typeof originalChunkFileNames === 'function') {\n return originalChunkFileNames(chunk)\n }\n return originalChunkFileNames || 'chunks/_/[name].mjs'\n }\n })\n\n // Add virtual imports\n nitro.options.virtual ??= {}\n\n // Add context type\n nitro.options.virtual['#nitro-graphql/context'] = () => `\nexport type { GraphQLContext } from 'nitro-graphql/context'\n`\n\n // Initial scan\n const scanResult = await scanGraphQLFiles(nitro)\n\n // Log resolver discovery for debugging\n if (scanResult.resolvers.length > 0) {\n logger.success(`Found ${scanResult.resolvers.length} resolvers`)\n }\n\n // Generate types for both development and build modes\n if (scanResult.typeDefs.length > 0) {\n const mergedTypeDefs = mergeTypeDefs(scanResult.typeDefs)\n const schema = makeExecutableSchema({\n typeDefs: mergedTypeDefs,\n resolvers: {},\n })\n\n // Use Function constructor to prevent bundling in production\n const { generateTypes } = await (new Function('return import(\"nitro-graphql/codegen\")'))()\n const generatedTypes = await generateTypes(schema)\n\n // Write to file\n const outputPath = join(nitro.options.buildDir, 'types', 'graphql-types.generated.ts')\n const typesDir = join(nitro.options.buildDir, 'types')\n await mkdir(typesDir, { recursive: true })\n await writeFile(outputPath, generatedTypes)\n\n // Create graphql.d.ts that declares the module\n const graphqlDtsPath = join(typesDir, 'graphql.d.ts')\n const graphqlDtsContent = `// Auto-generated by nitro-graphql\nimport type { Resolvers as Test } from './graphql-types.generated'\n\ndeclare module 'nitro-graphql' {\n interface Resolvers extends Test {}\n}\n`\n await writeFile(graphqlDtsPath, graphqlDtsContent)\n\n logger.success('Types generated')\n }\n else {\n // Create minimal types when no schema files found\n const typesDir = join(nitro.options.buildDir, 'types')\n await mkdir(typesDir, { recursive: true })\n\n const minimalTypes = `// Generated by nitro-graphql (no schema found)\nexport type Resolvers = any\n`\n const outputPath = join(typesDir, 'graphql-types.generated.ts')\n await writeFile(outputPath, minimalTypes)\n\n const graphqlDtsPath = join(typesDir, 'graphql.d.ts')\n const graphqlDtsContent = `// Auto-generated by nitro-graphql\nimport type { Resolvers as Test } from './graphql-types.generated'\n\ndeclare module 'nitro-graphql' {\n interface Resolvers extends Test {}\n}\n`\n await writeFile(graphqlDtsPath, graphqlDtsContent)\n\n logger.info('Created minimal types (no schema found)')\n }\n\n // Setup file watchers in dev mode - completely excluded from production\n if (nitro.options.dev) {\n // Use Function constructor to prevent bundling in production\n const setupGraphQLWatcher = (await (new Function('return import(\"nitro-graphql/watcher\")'))()).setupGraphQLWatcher\n const setupClientWatcher = (await (new Function('return import(\"nitro-graphql/client-watcher\")'))()).setupClientWatcher\n await setupGraphQLWatcher(nitro)\n await setupClientWatcher(nitro, options)\n }\n\n // Add GraphQL Yoga handlers\n nitro.options.handlers = nitro.options.handlers || []\n const endpoint = options.endpoint || '/api/graphql'\n\n // Main GraphQL endpoint\n nitro.options.handlers.push({\n route: endpoint,\n handler: '#nitro-graphql/handler',\n method: 'get',\n })\n\n nitro.options.handlers.push({\n route: endpoint,\n handler: '#nitro-graphql/handler',\n method: 'post',\n })\n\n nitro.options.handlers.push({\n route: endpoint,\n handler: '#nitro-graphql/handler',\n method: 'options',\n })\n\n // Health check endpoint\n nitro.options.handlers.push({\n route: `${endpoint}/health`,\n handler: '#nitro-graphql/health',\n method: 'get',\n })\n\n // Create GraphQL handler\n nitro.options.virtual['#nitro-graphql/handler'] = () => `\nimport { createYoga } from 'graphql-yoga'\nimport { defineEventHandler, readRawBody, setHeader, setResponseStatus } from 'h3'\nimport { useStorage } from 'nitro/runtime'\nimport { makeExecutableSchema } from '@graphql-tools/schema'\nimport { mergeTypeDefs, mergeResolvers } from '@graphql-tools/merge'\nimport { join } from 'pathe'\n// Types are generated at build time to .nitro/graphql-types.generated.ts\n\n// GraphQL Context type is injected via context module\n\n// Create resolver helper\nglobalThis.createResolver = function(resolvers) {\n return resolvers\n}\n\n// Dynamic schema loading function\nasync function loadTypeDefs() {\n const schemaPath = join('${nitro.options.srcDir}', 'graphql', '**', '*.graphql')\n const { loadFilesSync } = await import('@graphql-tools/load-files')\n return loadFilesSync(schemaPath, {\n recursive: true,\n })\n}\n\n// Load resolvers using dynamic imports (Nitro handles the bundling)\nconst resolverImports = [\n${scanResult.resolvers.map(resolver => ` () => import('${resolver.path}')`).join(',\\n')}\n]\n\n// Async function to load resolvers\nasync function loadResolvers() {\n let resolvers = {}\n try {\n if (resolverImports.length > 0) {\n const resolverModules = []\n \n for (let i = 0; i < resolverImports.length; i++) {\n try {\n const resolverModule = await resolverImports[i]()\n const resolver = resolverModule.default || resolverModule\n \n if (resolver) {\n resolverModules.push(resolver)\n }\n } catch (error) {\n console.warn('[graphql] Failed to load resolver:', i, error.message)\n }\n }\n \n if (resolverModules.length > 0) {\n resolvers = mergeResolvers(resolverModules)\n } else {\n console.warn('[graphql] No resolvers could be loaded')\n resolvers = { Query: {}, Mutation: {} }\n }\n } else {\n console.warn('[graphql] No resolvers found')\n resolvers = { Query: {}, Mutation: {} }\n }\n } catch (error) {\n console.warn('[graphql] Error loading resolvers:', error.message)\n resolvers = { Query: {}, Mutation: {} }\n }\n return resolvers\n}\n\n// Apollo Sandbox HTML with 1 week cache\nconst apolloSandboxHtml = \\`<!DOCTYPE html>\n<html lang=\"en\">\n<body style=\"margin: 0; overflow-x: hidden; overflow-y: hidden\">\n<div id=\"sandbox\" style=\"height:100vh; width:100vw;\"></div>\n<script src=\"https://embeddable-sandbox.cdn.apollographql.com/02e2da0fccbe0240ef03d2396d6c98559bab5b06/embeddable-sandbox.umd.production.min.js\"></script>\n<script>\nnew window.EmbeddedSandbox({\n target: \"#sandbox\",\n initialEndpoint: window.location.href,\n hideCookieToggle: false,\n initialState: {\n includeCookies: true\n }\n});\n</script>\n</body>\n</html>\\`\n\n// Set cache headers for Apollo Sandbox HTML (1 week = 604800 seconds)\nfunction setApolloSandboxCacheHeaders(event) {\n setHeader(event, 'Cache-Control', 'public, max-age=604800, s-maxage=604800')\n setHeader(event, 'Expires', new Date(Date.now() + 604800000).toUTCString())\n setHeader(event, 'ETag', \\`\"apollo-sandbox-\\${Date.now()}\"\\`)\n}\n\n// Lazy initialization\nlet yoga = null\nlet initPromise = null\n\nasync function getYoga() {\n // In development mode, always reload schema for hot updates\n const isDev = ${nitro.options.dev}\n if (yoga && !isDev) return yoga\n \n if (!initPromise || isDev) {\n // Reset yoga instance in development mode\n if (isDev) {\n yoga = null\n }\n \n initPromise = (async () => {\n // Load custom yoga config first (separate from resolvers)\n let customYogaConfig = {}\n ${scanResult.yogaConfigPath\n ? `\n try {\n const yogaConfigModule = await import('${scanResult.yogaConfigPath}')\n customYogaConfig = yogaConfigModule.default || yogaConfigModule\n } catch (error) {\n console.warn('[graphql] Failed to load yoga config:', error.message)\n }`\n : ''}\n\n const resolvers = await loadResolvers()\n const typeDefs = await loadTypeDefs()\n \n // Merge schema and resolvers (without yoga config interfering)\n const schema = makeExecutableSchema({\n typeDefs: mergeTypeDefs(typeDefs),\n resolvers,\n })\n\n // Default yoga configuration\n const defaultYogaConfig = {\n schema,\n context: async ({ request }) => {\n const event = request.$$event\n return {\n event,\n request,\n storage: useStorage(),\n }\n },\n graphqlEndpoint: '${endpoint}',\n graphiql: ${options.playground !== false},\n renderGraphiQL: () => apolloSandboxHtml,\n landingPage: false,\n cors: ${JSON.stringify(options.cors || false)},\n }\n\n // Clean up custom config (remove properties that could be mistaken for GraphQL resolvers)\n const cleanCustomConfig = { ...customYogaConfig }\n \n // Remove empty arrays and functions that GraphQL Tools might confuse with resolvers\n if (Array.isArray(cleanCustomConfig.plugins) && cleanCustomConfig.plugins.length === 0) {\n delete cleanCustomConfig.plugins\n }\n \n // Remove these yoga-specific configs from resolver merging\n const yogaOnlyConfigs = ['context', 'plugins', 'maskedErrors', 'graphiql', 'cors']\n const cleanResolverConfig = { ...cleanCustomConfig }\n yogaOnlyConfigs.forEach(key => {\n delete cleanResolverConfig[key]\n })\n\n // Merge custom config with defaults\n const yogaConfig = {\n ...defaultYogaConfig,\n ...cleanCustomConfig,\n // Always override schema and endpoint from default config\n schema,\n graphqlEndpoint: '${endpoint}',\n }\n\n yoga = createYoga(yogaConfig)\n \n return yoga\n })()\n }\n \n return initPromise\n}\n\nexport default defineEventHandler(async (event) => {\n const { req } = event.node\n const host = req.headers.host || 'localhost'\n const protocol = 'http'\n const url = new URL(req.url || '/', protocol + '://' + host)\n \n // Attach event to request for context\n req.$$event = event\n \n const yogaInstance = await getYoga()\n const response = await yogaInstance.fetch(url.toString(), {\n method: req.method || 'GET',\n headers: req.headers,\n body: req.method !== 'GET' && req.method !== 'HEAD' ? await readRawBody(event) : undefined,\n }, {\n event,\n })\n \n // Set response headers\n response.headers.forEach((value, key) => {\n setHeader(event, key, value)\n })\n \n // Set status code\n setResponseStatus(event, response.status)\n \n // Return response body\n if (response.body) {\n const contentType = response.headers.get('content-type')\n if (contentType?.includes('text/html')) {\n // Set cache headers for Apollo Sandbox HTML\n setApolloSandboxCacheHeaders(event)\n return await response.text()\n }\n if (contentType?.includes('application/json')) {\n return await response.text()\n }\n return response.body\n }\n \n return null\n})\n`\n\n // Health check handler\n nitro.options.virtual['#nitro-graphql/health'] = () => `\nimport { defineEventHandler, setResponseStatus } from 'h3'\n\nexport default defineEventHandler(async (event) => {\n try {\n const response = await $fetch('${endpoint}', {\n method: 'POST',\n body: {\n query: 'query Health { __typename }',\n operationName: 'Health',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n })\n \n if (response && typeof response === 'object' && 'data' in response) {\n return {\n status: 'healthy',\n message: 'GraphQL server is running',\n timestamp: new Date().toISOString(),\n }\n }\n \n throw new Error('Invalid response from GraphQL server')\n } catch (error) {\n setResponseStatus(event, 503)\n return {\n status: 'unhealthy',\n message: error.message || 'GraphQL server is not responding',\n timestamp: new Date().toISOString(),\n }\n }\n})\n`\n\n // Auto-import utilities\n if (nitro.options.imports) {\n nitro.options.imports.presets.push({\n from: 'nitro-graphql',\n imports: [\n 'createResolver',\n 'defineGraphQLResolver',\n 'defineGraphQLSchema',\n 'defineGraphQLResolvers',\n 'defineYogaConfig',\n 'gql',\n ],\n })\n }\n\n // Add TypeScript path alias for IDE support\n nitro.options.typescript ??= {} as any\n nitro.options.typescript.tsConfig ??= {}\n nitro.options.typescript.tsConfig.compilerOptions ??= {}\n nitro.options.typescript.tsConfig.compilerOptions.paths ??= {}\n nitro.options.typescript.tsConfig.compilerOptions.paths['#build/graphql-types.generated'] = [\n join(nitro.options.buildDir, 'types', 'graphql-types.generated.ts'),\n ]\n nitro.options.typescript.tsConfig.include = nitro.options.typescript.tsConfig.include || []\n nitro.options.typescript.tsConfig.include.push(\n join(nitro.options.buildDir, 'types', 'graphql-types.generated.ts'),\n join(nitro.options.buildDir, 'types', 'graphql.d.ts'),\n )\n },\n})\n\nexport * from './codegen'\nexport * from './context'\nexport * from './types'\nexport { createResolver, defineGraphQLResolver, defineYogaConfig } from './utils'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["nitro: Nitro","options: NitroGraphQLOptions","nitro: Nitro","options: NitroGraphQLOptions","nitro"],"sources":["../src/dev.ts","../src/index.ts"],"sourcesContent":["import type { Nitro } from 'nitropack'\nimport type { NitroGraphQLOptions } from './types'\nimport { existsSync } from 'node:fs'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { mergeTypeDefs } from '@graphql-tools/merge'\nimport { makeExecutableSchema } from '@graphql-tools/schema'\nimport { watch } from 'chokidar'\nimport { consola } from 'consola'\nimport { join } from 'pathe'\nimport { setupClientWatcher } from './client-watcher'\nimport { generateTypes } from './codegen'\nimport { scanGraphQLFiles } from './scanner'\nimport { debounce } from './utils'\n\nconst logger = consola.withTag('graphql')\n\n// Type generation function that can be called from hooks\nasync function regenerateGraphQLTypes(nitro: Nitro) {\n try {\n // Scan all GraphQL files and resolvers\n const scanResult = await scanGraphQLFiles(nitro)\n\n if (scanResult.typeDefs.length === 0) {\n logger.warn('⚠️ No schema files found')\n return\n }\n\n // Merge all type definitions\n const mergedTypeDefs = mergeTypeDefs(scanResult.typeDefs)\n\n // Create schema\n const schema = makeExecutableSchema({\n typeDefs: mergedTypeDefs,\n resolvers: {}, // Empty resolvers for type generation\n })\n\n // Generate types using dynamic import\n const generatedTypes = await generateTypes(schema)\n\n // Write to file\n const outputPath = join(nitro.options.buildDir, 'types', 'graphql-types.generated.ts')\n const typesDir = join(nitro.options.buildDir, 'types')\n await mkdir(typesDir, { recursive: true })\n await writeFile(outputPath, generatedTypes)\n\n // Update graphql.d.ts\n const graphqlDtsPath = join(typesDir, 'graphql.d.ts')\n console.log('graphqlDtsPath', graphqlDtsPath)\n const graphqlDtsContent = `// Auto-generated by nitro-graphql\nimport type { Resolvers as Test } from './graphql-types.generated'\n\ndeclare module 'nitro-graphql' {\n interface Resolvers extends Test {}\n}\n`\n await writeFile(graphqlDtsPath, graphqlDtsContent)\n\n logger.success('✨ Types regenerated')\n }\n catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.error('❌ Type generation failed:', errorMessage)\n }\n}\n\nexport function devmode(nitro: Nitro, options: NitroGraphQLOptions) {\n // Setup file watchers in dev mode - completely excluded from production\n if (nitro.options.dev) {\n // Setup GraphQL watcher using our own chokidar instance\n const generateTypesDebounced = debounce(async () => {\n await regenerateGraphQLTypes(nitro)\n }, 300)\n\n // Setup GraphQL file watcher\n const graphqlDir = join(nitro.options.srcDir, 'graphql')\n\n logger.info('🔍 Setting up independent GraphQL watcher for directory:', graphqlDir)\n\n // Check if the GraphQL directory exists\n try {\n // const { existsSync } = await import('node:fs')\n if (!existsSync(graphqlDir)) {\n logger.warn(`⚠️ GraphQL directory not found: ${graphqlDir}`)\n return\n }\n }\n catch (error) {\n logger.warn('⚠️ Could not check GraphQL directory:', error)\n return\n }\n\n const graphqlWatcher = watch(graphqlDir, {\n ignoreInitial: true,\n persistent: true,\n usePolling: true, // Enable polling for better compatibility on macOS\n interval: 500, // Poll every 500ms\n depth: 10, // Watch subdirectories\n })\n\n // Set up event handlers\n graphqlWatcher.on('add', (path) => {\n logger.info('📁 GraphQL file added:', path)\n generateTypesDebounced()\n })\n\n graphqlWatcher.on('change', (path) => {\n logger.info('📝 GraphQL file changed:', path)\n generateTypesDebounced()\n })\n\n graphqlWatcher.on('unlink', (path) => {\n logger.info('🗑️ GraphQL file deleted:', path)\n generateTypesDebounced()\n })\n\n graphqlWatcher.on('error', (error) => {\n logger.error('❌ GraphQL watcher error:', error)\n })\n\n // Handle raw events as fallback for better macOS compatibility\n graphqlWatcher.on('raw', (event, path) => {\n // Check for directory changes that indicate GraphQL file modifications\n if (event === 'change' && path && path.endsWith('graphql')) {\n logger.info('📝 GraphQL directory change detected, regenerating types')\n generateTypesDebounced()\n }\n })\n\n graphqlWatcher.on('ready', () => {\n logger.success('✅ GraphQL file watcher ready')\n })\n\n // Close watcher when Nitro closes\n nitro.hooks.hook('close', async () => {\n await graphqlWatcher.close()\n logger.info('🔒 GraphQL watcher closed')\n })\n\n setupClientWatcher(nitro, options)\n\n logger.success('✅ Independent GraphQL watcher set up')\n }\n}\n","import type { Nitro } from 'nitropack/types'\nimport type { NitroGraphQLOptions } from './types'\n\nimport { defineNitroModule } from 'nitropack/kit'\nimport { join } from 'pathe'\nimport { devmode } from './dev'\n\nexport default defineNitroModule({\n name: 'nitro:graphql-yoga',\n async setup(nitro: Nitro) {\n if (!nitro.options.dev) {\n nitro.options.rollupConfig ??= {} as any\n if (nitro.options.rollupConfig) {\n nitro.options.rollupConfig.plugins ??= []\n\n const originalExternal = nitro.options.rollupConfig.external\n nitro.options.rollupConfig.external = (id, parentId, isResolved) => {\n if (id.startsWith('./dev')) {\n return true\n }\n if (id.startsWith('./prerender') && !nitro.options.prerender) {\n return true\n }\n\n // Orijinal external logic'i koru\n if (typeof originalExternal === 'function') {\n return originalExternal(id, parentId, isResolved)\n }\n if (Array.isArray(originalExternal)) {\n return originalExternal.includes(id)\n }\n return false\n }\n }\n }\n\n // Get module options from nitro config\n const options: NitroGraphQLOptions = {\n endpoint: '/api/graphql',\n playground: true,\n cors: false,\n cacheHeaders: {\n enabled: true,\n maxAge: 604800, // 1 week\n },\n client: {\n enabled: nitro.options.framework?.name === 'nuxt',\n outputPath: undefined, // Will default to buildDir/types/graphql-client.generated.ts\n watchPatterns: undefined, // Will default to src/**/*.{graphql,gql} excluding server/graphql\n config: {\n documentMode: 'string',\n emitLegacyCommonJSImports: false,\n useTypeImports: true,\n enumsAsTypes: true,\n },\n },\n // Merge with user config from nitro.options\n ...(nitro.options as any).graphqlYoga,\n // Fallback to runtimeConfig for backward compatibility\n ...nitro.options.runtimeConfig?.graphqlYoga,\n }\n\n devmode(nitro, options)\n\n // Add virtual imports\n nitro.options.virtual ??= {}\n\n // Add context type\n nitro.options.virtual['#nitro-graphql/context'] = () => `\nexport type { GraphQLContext } from 'nitro-graphql/context'\n`\n\n // Add GraphQL Yoga handlers\n nitro.options.handlers = nitro.options.handlers || []\n const endpoint = options.endpoint || '/api/graphql'\n\n if (nitro.options.prerender || nitro.options.dev) {\n const { prerender } = await import('./prerender')\n await prerender(nitro, options)\n }\n // Main GraphQL endpoint\n nitro.options.handlers.push({\n route: endpoint,\n handler: '#nitro-graphql/handler',\n method: 'get',\n })\n\n nitro.options.handlers.push({\n route: endpoint,\n handler: '#nitro-graphql/handler',\n method: 'post',\n })\n\n nitro.options.handlers.push({\n route: endpoint,\n handler: '#nitro-graphql/handler',\n method: 'options',\n })\n\n // Health check endpoint\n nitro.options.handlers.push({\n route: `${endpoint}/health`,\n handler: '#nitro-graphql/health',\n method: 'get',\n })\n\n // Health check handler\n nitro.options.virtual['#nitro-graphql/health'] = () => `\nimport { defineEventHandler, setResponseStatus } from 'h3'\n\nexport default defineEventHandler(async (event) => {\n try {\n const response = await $fetch('${endpoint}', {\n method: 'POST',\n body: {\n query: 'query Health { __typename }',\n operationName: 'Health',\n },\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n })\n \n if (response && typeof response === 'object' && 'data' in response) {\n return {\n status: 'healthy',\n message: 'GraphQL server is running',\n timestamp: new Date().toISOString(),\n }\n }\n \n throw new Error('Invalid response from GraphQL server')\n } catch (error) {\n setResponseStatus(event, 503)\n return {\n status: 'unhealthy',\n message: error.message || 'GraphQL server is not responding',\n timestamp: new Date().toISOString(),\n }\n }\n})\n`\n\n // Auto-import utilities\n if (nitro.options.imports) {\n nitro.options.imports.presets.push({\n from: 'nitro-graphql/utils',\n imports: [\n 'defineResolver',\n 'defineYogaConfig',\n ],\n })\n }\n\n nitro.hooks.hook('types:extend', (types) => {\n // Add TypeScript path alias for IDE support\n types.tsConfig ||= {}\n types.tsConfig.compilerOptions ??= {}\n types.tsConfig.compilerOptions.paths ??= {}\n types.tsConfig.compilerOptions.paths['#build/graphql-types.generated'] = [\n join(nitro.options.buildDir, 'types', 'graphql-types.generated.ts'),\n ]\n types.tsConfig.include = types.tsConfig.include || []\n types.tsConfig.include.push(\n join(nitro.options.buildDir, 'types', 'graphql-types.generated.ts'),\n join(nitro.options.buildDir, 'types', 'graphql.d.ts'),\n )\n })\n\n // Add GraphQL path to known chunk prefixes\n const graphqlPath = join(nitro.options.srcDir, 'graphql')\n\n // Access the internal rollup config and add our prefix\n nitro.hooks.hook('rollup:before', (nitro, rollupConfig) => {\n // Add codegen packages as external dependencies to prevent bundling\n rollupConfig.external = rollupConfig.external || []\n const codegenExternals = [\n '@graphql-codegen/core',\n '@graphql-codegen/typescript',\n '@graphql-codegen/typescript-resolvers',\n '@graphql-codegen/typescript-operations',\n '@graphql-codegen/typescript-generic-sdk',\n '@graphql-tools/graphql-file-loader',\n '@graphql-tools/load',\n ]\n\n if (Array.isArray(rollupConfig.external)) {\n rollupConfig.external.push(...codegenExternals)\n }\n else if (typeof rollupConfig.external === 'function') {\n const originalExternal = rollupConfig.external\n rollupConfig.external = (id, parent, isResolved) => {\n if (codegenExternals.some(external => id.includes(external))) {\n return true\n }\n return originalExternal(id, parent, isResolved)\n }\n }\n\n // Add GraphQL path to chunkNamePrefixes\n const originalChunkFileNames = rollupConfig.output.chunkFileNames\n rollupConfig.output.chunkFileNames = (chunk) => {\n // Only GraphQL resolvers (actual resolver files) should go to graphql folder\n const allIds = chunk.moduleIds || []\n\n const hasGraphQLResolverFile = allIds.some(id =>\n // Only server/graphql resolver files (not node_modules, not virtual modules)\n id.includes(graphqlPath)\n && !id.includes('node_modules')\n && !id.includes('#nitro-graphql')\n && (id.endsWith('.ts') || id.endsWith('.js') || id.endsWith('.mjs')),\n )\n\n if (hasGraphQLResolverFile) {\n return `chunks/graphql/[name].mjs`\n }\n // Use original logic for other chunks\n if (typeof originalChunkFileNames === 'function') {\n return originalChunkFileNames(chunk)\n }\n return originalChunkFileNames || 'chunks/_/[name].mjs'\n }\n })\n },\n})\n"],"mappings":"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"}