nitro-graphql 0.0.1 → 0.0.3

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 (39) hide show
  1. package/README.md +14 -14
  2. package/dist/{client-codegen-DM2n5Gt2.js → client-codegen.js} +1 -2
  3. package/dist/client-watcher.d.ts +2 -5
  4. package/dist/client-watcher.js +36 -28
  5. package/dist/codegen.d.ts +12 -1
  6. package/dist/codegen.js +107 -1
  7. package/dist/context.d.ts +9 -1
  8. package/dist/context.js +0 -1
  9. package/dist/dev.js +95 -0
  10. package/dist/index.d.ts +12 -8
  11. package/dist/index.js +67 -329
  12. package/dist/prerender.js +279 -0
  13. package/dist/{scanner-BdcKEPQk.js → scanner.js} +4 -5
  14. package/dist/{types-D_NqyCcy.d.ts → types.d.ts} +2 -11
  15. package/dist/utils.d.ts +13 -3
  16. package/dist/utils.js +22 -2
  17. package/package.json +9 -4
  18. package/dist/client-codegen-DM2n5Gt2.js.map +0 -1
  19. package/dist/client-watcher.d.ts.map +0 -1
  20. package/dist/client-watcher.js.map +0 -1
  21. package/dist/codegen-DWJuLowd.d.ts +0 -16
  22. package/dist/codegen-DWJuLowd.d.ts.map +0 -1
  23. package/dist/codegen-Dbw6gEZt.js +0 -110
  24. package/dist/codegen-Dbw6gEZt.js.map +0 -1
  25. package/dist/context-BgqNJFCT.d.ts +0 -13
  26. package/dist/context-BgqNJFCT.d.ts.map +0 -1
  27. package/dist/index.d.ts.map +0 -1
  28. package/dist/index.js.map +0 -1
  29. package/dist/scanner-BdcKEPQk.js.map +0 -1
  30. package/dist/types-D_NqyCcy.d.ts.map +0 -1
  31. package/dist/utils-87_22aIA.js +0 -41
  32. package/dist/utils-87_22aIA.js.map +0 -1
  33. package/dist/utils-BuYDOLIi.d.ts +0 -22
  34. package/dist/utils-BuYDOLIi.d.ts.map +0 -1
  35. package/dist/watcher.d.ts +0 -9
  36. package/dist/watcher.d.ts.map +0 -1
  37. package/dist/watcher.js +0 -96
  38. package/dist/watcher.js.map +0 -1
  39. /package/dist/{context-CZdhkJYD.js → types.js} +0 -0
package/dist/index.js CHANGED
@@ -1,19 +1,26 @@
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";
5
- import { mkdir, writeFile } from "node:fs/promises";
6
- import { mergeTypeDefs } from "@graphql-tools/merge";
7
- import { makeExecutableSchema } from "@graphql-tools/schema";
8
- import { consola } from "consola";
9
- import { join } from "pathe";
1
+ import { devmode } from "./dev.js";
2
+ import { relativeWithDot } from "./utils.js";
3
+ import { dirname, join, resolve } from "pathe";
10
4
  import { defineNitroModule } from "nitropack/kit";
11
5
 
12
6
  //#region src/index.ts
13
- const logger = consola.withTag("graphql");
14
7
  var src_default = defineNitroModule({
15
8
  name: "nitro:graphql-yoga",
16
9
  async setup(nitro) {
10
+ if (!nitro.options.dev) {
11
+ nitro.options.rollupConfig ??= {};
12
+ if (nitro.options.rollupConfig) {
13
+ nitro.options.rollupConfig.plugins ??= [];
14
+ const originalExternal = nitro.options.rollupConfig.external;
15
+ nitro.options.rollupConfig.external = (id, parentId, isResolved) => {
16
+ if (id.startsWith("./dev")) return true;
17
+ if (id.startsWith("./prerender") && !nitro.options.prerender) return true;
18
+ if (typeof originalExternal === "function") return originalExternal(id, parentId, isResolved);
19
+ if (Array.isArray(originalExternal)) return originalExternal.includes(id);
20
+ return false;
21
+ };
22
+ }
23
+ }
17
24
  const options = {
18
25
  endpoint: "/api/graphql",
19
26
  playground: true,
@@ -23,7 +30,7 @@ var src_default = defineNitroModule({
23
30
  maxAge: 604800
24
31
  },
25
32
  client: {
26
- enabled: false,
33
+ enabled: nitro.options.framework?.name === "nuxt",
27
34
  outputPath: void 0,
28
35
  watchPatterns: void 0,
29
36
  config: {
@@ -36,90 +43,17 @@ var src_default = defineNitroModule({
36
43
  ...nitro.options.graphqlYoga,
37
44
  ...nitro.options.runtimeConfig?.graphqlYoga
38
45
  };
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
- });
46
+ devmode(nitro, options);
68
47
  nitro.options.virtual ??= {};
69
48
  nitro.options.virtual["#nitro-graphql/context"] = () => `
70
49
  export type { GraphQLContext } from 'nitro-graphql/context'
71
50
  `;
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
51
  nitro.options.handlers = nitro.options.handlers || [];
122
52
  const endpoint = options.endpoint || "/api/graphql";
53
+ if (nitro.options.prerender || nitro.options.dev) {
54
+ const { prerender } = await import("./prerender.js");
55
+ await prerender(nitro, options);
56
+ }
123
57
  nitro.options.handlers.push({
124
58
  route: endpoint,
125
59
  handler: "#nitro-graphql/handler",
@@ -140,228 +74,6 @@ declare module 'nitro-graphql' {
140
74
  handler: "#nitro-graphql/health",
141
75
  method: "get"
142
76
  });
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
77
  nitro.options.virtual["#nitro-graphql/health"] = () => `
366
78
  import { defineEventHandler, setResponseStatus } from 'h3'
367
79
 
@@ -399,26 +111,52 @@ export default defineEventHandler(async (event) => {
399
111
  })
400
112
  `;
401
113
  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
- ]
114
+ from: "nitro-graphql/utils",
115
+ imports: ["defineResolver", "defineYogaConfig"]
116
+ });
117
+ const tsConfigPath = resolve(nitro.options.buildDir, nitro.options.typescript.tsconfigPath);
118
+ const tsconfigDir = dirname(tsConfigPath);
119
+ const typesDir = resolve(nitro.options.buildDir, "types");
120
+ nitro.hooks.hook("types:extend", (types) => {
121
+ types.tsConfig ||= {};
122
+ types.tsConfig.compilerOptions ??= {};
123
+ types.tsConfig.compilerOptions.paths ??= {};
124
+ types.tsConfig.compilerOptions.paths["#graphql/server"] = [relativeWithDot(tsconfigDir, join(typesDir, "graphql-types.generated.ts"))];
125
+ types.tsConfig.compilerOptions.paths["#graphql/client"] = [relativeWithDot(tsconfigDir, join(typesDir, "graphql-client.generated.ts"))];
126
+ types.tsConfig.include = types.tsConfig.include || [];
127
+ types.tsConfig.include.push(relativeWithDot(tsconfigDir, join(typesDir, "graphql-client.generated.ts")), relativeWithDot(tsconfigDir, join(typesDir, "graphql-types.generated.ts")), relativeWithDot(tsconfigDir, join(typesDir, "graphql.d.ts")));
128
+ });
129
+ const graphqlPath = join(nitro.options.srcDir, "graphql");
130
+ nitro.hooks.hook("rollup:before", (nitro$1, rollupConfig) => {
131
+ rollupConfig.external = rollupConfig.external || [];
132
+ const codegenExternals = [
133
+ "@graphql-codegen/core",
134
+ "@graphql-codegen/typescript",
135
+ "@graphql-codegen/typescript-resolvers",
136
+ "@graphql-codegen/typescript-operations",
137
+ "@graphql-codegen/typescript-generic-sdk",
138
+ "@graphql-tools/graphql-file-loader",
139
+ "@graphql-tools/load"
140
+ ];
141
+ if (Array.isArray(rollupConfig.external)) rollupConfig.external.push(...codegenExternals);
142
+ else if (typeof rollupConfig.external === "function") {
143
+ const originalExternal = rollupConfig.external;
144
+ rollupConfig.external = (id, parent, isResolved) => {
145
+ if (codegenExternals.some((external) => id.includes(external))) return true;
146
+ return originalExternal(id, parent, isResolved);
147
+ };
148
+ }
149
+ const originalChunkFileNames = rollupConfig.output.chunkFileNames;
150
+ rollupConfig.output.chunkFileNames = (chunk) => {
151
+ const allIds = chunk.moduleIds || [];
152
+ 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")));
153
+ if (hasGraphQLResolverFile) return `chunks/graphql/[name].mjs`;
154
+ if (typeof originalChunkFileNames === "function") return originalChunkFileNames(chunk);
155
+ return originalChunkFileNames || "chunks/_/[name].mjs";
156
+ };
411
157
  });
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
158
  }
420
159
  });
421
160
 
422
161
  //#endregion
423
- export { createResolver, src_default as default, defineGraphQLResolver, defineYogaConfig, generateTypes };
424
- //# sourceMappingURL=index.js.map
162
+ export { src_default as default };