nitro-graphql 2.0.0-beta.31 → 2.0.0-beta.33

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 (86) hide show
  1. package/dist/codegen/client-types.d.mts +13 -0
  2. package/dist/codegen/client-types.mjs +131 -0
  3. package/dist/codegen/external-types.d.mts +12 -0
  4. package/dist/codegen/external-types.mjs +88 -0
  5. package/dist/codegen/index.d.mts +18 -0
  6. package/dist/codegen/index.mjs +24 -0
  7. package/dist/codegen/server-types.d.mts +13 -0
  8. package/dist/codegen/server-types.mjs +64 -0
  9. package/dist/codegen/validation.d.mts +13 -0
  10. package/dist/codegen/validation.mjs +96 -0
  11. package/dist/config/defaults.mjs +36 -0
  12. package/dist/constants/scalars.mjs +27 -0
  13. package/dist/constants.mjs +106 -0
  14. package/dist/ecosystem/nuxt.mjs +3 -3
  15. package/dist/rollup.d.mts +2 -8
  16. package/dist/rollup.mjs +24 -199
  17. package/dist/routes/apollo-server.d.mts +2 -2
  18. package/dist/routes/apollo-server.mjs +7 -51
  19. package/dist/routes/debug-template.d.mts +15 -0
  20. package/dist/routes/debug-template.mjs +385 -0
  21. package/dist/routes/debug.d.mts +2 -2
  22. package/dist/routes/debug.mjs +1 -344
  23. package/dist/routes/graphql-yoga.d.mts +2 -2
  24. package/dist/routes/graphql-yoga.mjs +7 -51
  25. package/dist/routes/health.d.mts +2 -2
  26. package/dist/setup/file-watcher.mjs +84 -0
  27. package/dist/setup/graphql-scanner.mjs +25 -0
  28. package/dist/setup/rollup-integration.mjs +90 -0
  29. package/dist/setup/scaffold-generator.mjs +109 -0
  30. package/dist/setup/ts-config.mjs +69 -0
  31. package/dist/setup.d.mts +2 -2
  32. package/dist/setup.mjs +147 -303
  33. package/dist/types/index.d.mts +2 -2
  34. package/dist/utils/client-codegen.d.mts +1 -1
  35. package/dist/utils/client-codegen.mjs +5 -28
  36. package/dist/utils/codegen-plugin.d.mts +20 -0
  37. package/dist/utils/codegen-plugin.mjs +30 -0
  38. package/dist/utils/directive-parser.d.mts +2 -1
  39. package/dist/utils/directive-parser.mjs +4 -2
  40. package/dist/utils/federation.d.mts +29 -0
  41. package/dist/utils/federation.mjs +40 -0
  42. package/dist/utils/file-generator.mjs +1 -1
  43. package/dist/utils/file-writer.d.mts +35 -0
  44. package/dist/utils/file-writer.mjs +32 -0
  45. package/dist/utils/imports.d.mts +15 -0
  46. package/dist/utils/imports.mjs +25 -0
  47. package/dist/utils/index.d.mts +11 -38
  48. package/dist/utils/index.mjs +10 -287
  49. package/dist/utils/layers.d.mts +22 -0
  50. package/dist/utils/layers.mjs +28 -0
  51. package/dist/utils/ofetch-templates.d.mts +30 -0
  52. package/dist/utils/ofetch-templates.mjs +135 -0
  53. package/dist/utils/path-resolver.d.mts +2 -2
  54. package/dist/utils/path-resolver.mjs +2 -2
  55. package/dist/utils/scanning/common.d.mts +23 -0
  56. package/dist/utils/scanning/common.mjs +39 -0
  57. package/dist/utils/scanning/directives.d.mts +11 -0
  58. package/dist/utils/scanning/directives.mjs +43 -0
  59. package/dist/utils/scanning/documents.d.mts +15 -0
  60. package/dist/utils/scanning/documents.mjs +46 -0
  61. package/dist/utils/scanning/index.d.mts +6 -0
  62. package/dist/utils/scanning/index.mjs +7 -0
  63. package/dist/utils/scanning/resolvers.d.mts +11 -0
  64. package/dist/utils/scanning/resolvers.mjs +100 -0
  65. package/dist/utils/scanning/schemas.d.mts +15 -0
  66. package/dist/utils/scanning/schemas.mjs +29 -0
  67. package/dist/utils/schema-builder.d.mts +48 -0
  68. package/dist/utils/schema-builder.mjs +51 -0
  69. package/dist/utils/server-codegen.mjs +4 -27
  70. package/dist/utils/type-generation.d.mts +6 -12
  71. package/dist/utils/type-generation.mjs +6 -419
  72. package/dist/utils/validation.d.mts +11 -0
  73. package/dist/utils/validation.mjs +34 -0
  74. package/dist/virtual/generators/config.d.mts +22 -0
  75. package/dist/virtual/generators/config.mjs +36 -0
  76. package/dist/virtual/generators/debug.d.mts +14 -0
  77. package/dist/virtual/generators/debug.mjs +53 -0
  78. package/dist/virtual/generators/directives.d.mts +14 -0
  79. package/dist/virtual/generators/directives.mjs +52 -0
  80. package/dist/virtual/generators/index.d.mts +6 -0
  81. package/dist/virtual/generators/index.mjs +7 -0
  82. package/dist/virtual/generators/resolvers.d.mts +14 -0
  83. package/dist/virtual/generators/resolvers.mjs +55 -0
  84. package/dist/virtual/generators/schemas.d.mts +14 -0
  85. package/dist/virtual/generators/schemas.mjs +43 -0
  86. package/package.json +75 -57
package/dist/setup.mjs CHANGED
@@ -1,40 +1,51 @@
1
- import { generateDirectiveSchemas } from "./utils/directive-parser.mjs";
2
- import { generateLayerIgnorePatterns, getLayerAppDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanResolvers, scanSchemas, validateExternalServices } from "./utils/index.mjs";
3
- import { writeFileIfNotExists } from "./utils/file-generator.mjs";
4
- import { getScaffoldConfig, getTypesConfig, resolveFilePath, shouldGenerateScaffold } from "./utils/path-resolver.mjs";
5
- import { clientTypeGeneration, serverTypeGeneration } from "./utils/type-generation.mjs";
1
+ import { ENDPOINT_DEBUG, FRAMEWORK_NITRO, FRAMEWORK_NUXT, GRAPHQL_HTTP_METHODS, LOG_TAG } from "./constants.mjs";
2
+ import { getDefaultPaths } from "./utils/path-resolver.mjs";
3
+ import { generateServerTypes } from "./codegen/server-types.mjs";
4
+ import { generateClientTypes } from "./codegen/index.mjs";
5
+ import { DEFAULT_RUNTIME_CONFIG, DEFAULT_TYPESCRIPT_STRICT, DEFAULT_TYPES_CONFIG } from "./config/defaults.mjs";
6
+ import { validateExternalServices } from "./utils/validation.mjs";
6
7
  import { rollupConfig } from "./rollup.mjs";
8
+ import { getWatchDirectories, setupFileWatcher } from "./setup/file-watcher.mjs";
9
+ import { scanAllGraphQLFiles } from "./setup/graphql-scanner.mjs";
10
+ import { setupRollupChunking, setupRollupExternals } from "./setup/rollup-integration.mjs";
11
+ import { generateScaffoldFiles } from "./setup/scaffold-generator.mjs";
12
+ import { setupTypeScriptPaths } from "./setup/ts-config.mjs";
7
13
  import defu from "defu";
8
- import { existsSync, mkdirSync } from "node:fs";
9
14
  import { fileURLToPath } from "node:url";
10
- import { watch } from "chokidar";
11
15
  import consola from "consola";
12
- import { dirname, join, relative, resolve } from "pathe";
16
+ import { join, relative, resolve } from "pathe";
13
17
 
14
18
  //#region src/setup.ts
15
- const logger = consola.withTag("nitro-graphql");
19
+ const logger = consola.withTag(LOG_TAG);
16
20
  /**
17
- * Shared setup logic for nitro-graphql module
18
- * Used by both the direct Nitro module export and the Vite plugin's nitro: hook
21
+ * Main setup function for nitro-graphql
22
+ * Coordinates all initialization steps for the module
19
23
  */
20
24
  async function setupNitroGraphQL(nitro) {
25
+ initializeConfiguration(nitro);
26
+ validateConfiguration(nitro);
27
+ setupBuildDirectories(nitro);
28
+ setupRollupExternals(nitro);
29
+ setupRollupChunking(nitro);
30
+ initializeRuntimeConfig(nitro);
31
+ setupFileWatching(nitro);
32
+ await scanGraphQLFiles(nitro);
33
+ setupDevHooks(nitro);
34
+ await rollupConfig(nitro);
35
+ await generateTypes(nitro);
36
+ setupCloseHooks(nitro);
37
+ registerRouteHandlers(nitro);
38
+ setupTypeScriptConfiguration(nitro);
39
+ setupNuxtIntegration(nitro);
40
+ generateScaffoldFiles(nitro);
41
+ }
42
+ /**
43
+ * Initialize default configuration values
44
+ */
45
+ function initializeConfiguration(nitro) {
21
46
  nitro.options.graphql ||= {};
22
- nitro.options.graphql.types = defu(nitro.options.graphql.types, {
23
- server: ".graphql/nitro-graphql-server.d.ts",
24
- client: ".graphql/nitro-graphql-client.d.ts",
25
- enabled: true
26
- });
47
+ nitro.options.graphql.types = defu(nitro.options.graphql.types, DEFAULT_TYPES_CONFIG);
27
48
  if (!nitro.options.graphql?.framework) logger.warn("No GraphQL framework specified. Please set graphql.framework to \"graphql-yoga\" or \"apollo-server\".");
28
- if (nitro.options.graphql?.externalServices?.length) {
29
- const validationErrors = validateExternalServices(nitro.options.graphql.externalServices);
30
- if (validationErrors.length > 0) {
31
- logger.error("External services configuration errors:");
32
- for (const error of validationErrors) logger.error(` - ${error}`);
33
- throw new Error("Invalid external services configuration");
34
- }
35
- logger.info(`Configured ${nitro.options.graphql.externalServices.length} external GraphQL services`);
36
- }
37
- const { getDefaultPaths } = await import("./utils/path-resolver.mjs");
38
49
  const defaultPaths = getDefaultPaths(nitro);
39
50
  nitro.graphql ||= {
40
51
  buildDir: "",
@@ -47,143 +58,130 @@ async function setupNitroGraphQL(nitro) {
47
58
  server: "server"
48
59
  }
49
60
  };
50
- nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
51
- rollupConfig$1.external = rollupConfig$1.external || [];
52
- const allExternals = [...["oxc-parser", "@oxc-parser"]];
53
- if (!nitro.options.graphql?.federation?.enabled) allExternals.push(...[
54
- "@apollo/subgraph",
55
- "@apollo/federation-internals",
56
- "@apollo/cache-control-types"
57
- ]);
58
- if (Array.isArray(rollupConfig$1.external)) rollupConfig$1.external.push(...allExternals);
59
- else if (typeof rollupConfig$1.external === "function") {
60
- const originalExternal = rollupConfig$1.external;
61
- rollupConfig$1.external = (id, parent, isResolved) => {
62
- if (allExternals.some((external) => id.includes(external))) return true;
63
- return originalExternal(id, parent, isResolved);
64
- };
61
+ }
62
+ /**
63
+ * Validate external services configuration
64
+ */
65
+ function validateConfiguration(nitro) {
66
+ if (nitro.options.graphql?.externalServices?.length) {
67
+ const validationErrors = validateExternalServices(nitro.options.graphql.externalServices);
68
+ if (validationErrors.length > 0) {
69
+ logger.error("External services configuration errors:");
70
+ for (const error of validationErrors) logger.error(` - ${error}`);
71
+ throw new Error("Invalid external services configuration");
65
72
  }
66
- });
67
- nitro.options.runtimeConfig.graphql = defu(nitro.options.runtimeConfig.graphql || {}, {
68
- endpoint: {
69
- graphql: "/api/graphql",
70
- healthCheck: "/api/graphql/health"
71
- },
72
- playground: true
73
- });
73
+ logger.info(`Configured ${nitro.options.graphql.externalServices.length} external GraphQL services`);
74
+ }
74
75
  if (nitro.options.graphql?.federation?.enabled) logger.info(`Apollo Federation enabled for service: ${nitro.options.graphql.federation.serviceName || "unnamed"}`);
76
+ }
77
+ /**
78
+ * Setup build directories
79
+ */
80
+ function setupBuildDirectories(nitro) {
75
81
  const graphqlBuildDir = resolve(nitro.options.buildDir, "graphql");
76
82
  nitro.graphql.buildDir = graphqlBuildDir;
77
- const watchDirs = [];
78
83
  switch (nitro.options.framework.name) {
79
- case "nuxt": {
84
+ case FRAMEWORK_NUXT:
80
85
  nitro.graphql.dir.client = relative(nitro.options.rootDir, nitro.graphql.clientDir);
81
86
  nitro.graphql.dir.server = relative(nitro.options.rootDir, nitro.graphql.serverDir);
82
- watchDirs.push(nitro.graphql.clientDir);
83
- const layerServerDirs = getLayerServerDirectories(nitro);
84
- const layerAppDirs = getLayerAppDirectories(nitro);
85
- for (const layerServerDir of layerServerDirs) watchDirs.push(join(layerServerDir, "graphql"));
86
- for (const layerAppDir of layerAppDirs) watchDirs.push(join(layerAppDir, "graphql"));
87
87
  break;
88
- }
89
- case "nitro":
88
+ case FRAMEWORK_NITRO:
90
89
  nitro.graphql.dir.client = relative(nitro.options.rootDir, nitro.graphql.clientDir);
91
90
  nitro.graphql.dir.server = relative(nitro.options.rootDir, nitro.graphql.serverDir);
92
- watchDirs.push(nitro.graphql.clientDir);
93
- watchDirs.push(nitro.graphql.serverDir);
94
91
  break;
95
- default:
92
+ default: break;
96
93
  }
97
- if (nitro.options.graphql?.externalServices?.length) {
98
- for (const service of nitro.options.graphql.externalServices) if (service.documents?.length) for (const pattern of service.documents) {
99
- if (!pattern) continue;
100
- const baseDir = pattern.split("**")[0]?.replace(/\/$/, "") || ".";
101
- const resolvedDir = resolve(nitro.options.rootDir, baseDir);
102
- if (!watchDirs.includes(resolvedDir)) watchDirs.push(resolvedDir);
103
- }
104
- }
105
- const watcher = watch(watchDirs, {
106
- persistent: true,
107
- ignoreInitial: true,
108
- ignored: [...nitro.options.ignore, ...generateLayerIgnorePatterns()]
109
- }).on("all", async (_, path) => {
110
- const isGraphQLFile = path.endsWith(".graphql") || path.endsWith(".gql");
111
- const isResolverFile = path.endsWith(".resolver.ts") || path.endsWith(".resolver.js");
112
- const isDirectiveFile = path.endsWith(".directive.ts") || path.endsWith(".directive.js");
113
- if (isGraphQLFile || isResolverFile || isDirectiveFile) if (path.includes(nitro.graphql.serverDir) || path.includes("server/graphql") || path.includes("server\\graphql") || isResolverFile || isDirectiveFile) {
114
- await scanResolvers(nitro).then((r) => nitro.scanResolvers = r);
115
- await scanDirectives(nitro).then((d) => nitro.scanDirectives = d);
116
- logger.success("Types regenerated");
117
- await serverTypeGeneration(nitro, { silent: true });
118
- await clientTypeGeneration(nitro, { silent: true });
119
- await nitro.hooks.callHook("dev:reload");
120
- } else {
121
- logger.success("Types regenerated");
122
- await clientTypeGeneration(nitro, { silent: true });
123
- }
124
- });
94
+ }
95
+ /**
96
+ * Initialize runtime configuration
97
+ */
98
+ function initializeRuntimeConfig(nitro) {
99
+ nitro.options.runtimeConfig.graphql = defu(nitro.options.runtimeConfig.graphql || {}, DEFAULT_RUNTIME_CONFIG);
100
+ }
101
+ /**
102
+ * Setup file watching for development mode
103
+ */
104
+ function setupFileWatching(nitro) {
105
+ const watchDirs = getWatchDirectories(nitro);
106
+ nitro.graphql.watchDirs = watchDirs;
107
+ const watcher = setupFileWatcher(nitro, watchDirs);
125
108
  nitro.hooks.hook("close", () => {
126
109
  watcher.close();
127
110
  });
128
- const tsconfigDir = dirname(resolve(nitro.options.buildDir, nitro.options.typescript.tsconfigPath));
129
- nitro.scanSchemas = await scanSchemas(nitro);
130
- nitro.scanDocuments = await scanDocs(nitro);
131
- nitro.scanResolvers = await scanResolvers(nitro);
132
- const directives = await scanDirectives(nitro);
133
- nitro.scanDirectives = directives;
134
- await generateDirectiveSchemas(nitro, directives);
111
+ }
112
+ /**
113
+ * Scan all GraphQL files (schemas, resolvers, directives, documents)
114
+ */
115
+ async function scanGraphQLFiles(nitro) {
116
+ await scanAllGraphQLFiles(nitro);
117
+ }
118
+ /**
119
+ * Setup dev mode hooks for rescanning files
120
+ */
121
+ function setupDevHooks(nitro) {
135
122
  let hasShownInitialLogs = false;
136
123
  nitro.hooks.hook("dev:start", async () => {
137
- nitro.scanSchemas = await scanSchemas(nitro);
138
- const resolvers = await scanResolvers(nitro);
139
- nitro.scanResolvers = resolvers;
140
- const directives$1 = await scanDirectives(nitro);
141
- nitro.scanDirectives = directives$1;
142
- await generateDirectiveSchemas(nitro, directives$1);
143
- nitro.scanDocuments = await scanDocs(nitro);
124
+ await scanAllGraphQLFiles(nitro);
144
125
  if (nitro.options.dev && !hasShownInitialLogs) {
145
126
  hasShownInitialLogs = true;
146
- if (resolvers.length > 0) {
147
- const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0);
148
- const typeCount = {
149
- query: 0,
150
- mutation: 0,
151
- resolver: 0,
152
- type: 0,
153
- subscription: 0,
154
- directive: 0
155
- };
156
- for (const resolver of resolvers) for (const imp of resolver.imports) if (imp.type in typeCount) typeCount[imp.type]++;
157
- const breakdown = [];
158
- if (typeCount.query > 0) breakdown.push(`${typeCount.query} query`);
159
- if (typeCount.mutation > 0) breakdown.push(`${typeCount.mutation} mutation`);
160
- if (typeCount.resolver > 0) breakdown.push(`${typeCount.resolver} resolver`);
161
- if (typeCount.type > 0) breakdown.push(`${typeCount.type} type`);
162
- if (typeCount.subscription > 0) breakdown.push(`${typeCount.subscription} subscription`);
163
- if (typeCount.directive > 0) breakdown.push(`${typeCount.directive} directive`);
164
- if (breakdown.length > 0) logger.success(`${totalExports} resolver export(s): ${breakdown.join(", ")}`);
165
- } else logger.warn("No resolvers found. Check /_nitro/graphql/debug for details.");
127
+ logResolverDiagnostics(nitro);
166
128
  }
167
129
  });
168
- await rollupConfig(nitro);
169
- await serverTypeGeneration(nitro);
170
- await clientTypeGeneration(nitro, { isInitial: true });
130
+ }
131
+ /**
132
+ * Log resolver diagnostics for development
133
+ */
134
+ function logResolverDiagnostics(nitro) {
135
+ const resolvers = nitro.scanResolvers || [];
136
+ if (resolvers.length > 0) {
137
+ const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0);
138
+ const typeCount = {
139
+ query: 0,
140
+ mutation: 0,
141
+ resolver: 0,
142
+ type: 0,
143
+ subscription: 0,
144
+ directive: 0
145
+ };
146
+ for (const resolver of resolvers) for (const imp of resolver.imports) if (imp.type in typeCount) typeCount[imp.type]++;
147
+ const breakdown = [];
148
+ if (typeCount.query > 0) breakdown.push(`${typeCount.query} query`);
149
+ if (typeCount.mutation > 0) breakdown.push(`${typeCount.mutation} mutation`);
150
+ if (typeCount.resolver > 0) breakdown.push(`${typeCount.resolver} resolver`);
151
+ if (typeCount.type > 0) breakdown.push(`${typeCount.type} type`);
152
+ if (typeCount.subscription > 0) breakdown.push(`${typeCount.subscription} subscription`);
153
+ if (typeCount.directive > 0) breakdown.push(`${typeCount.directive} directive`);
154
+ if (breakdown.length > 0) logger.success(`${totalExports} resolver export(s): ${breakdown.join(", ")}`);
155
+ } else logger.warn("No resolvers found. Check /_nitro/graphql/debug for details.");
156
+ }
157
+ /**
158
+ * Generate server and client types
159
+ */
160
+ async function generateTypes(nitro) {
161
+ await generateServerTypes(nitro);
162
+ await generateClientTypes(nitro, { isInitial: true });
163
+ }
164
+ /**
165
+ * Setup close hooks for final type generation
166
+ */
167
+ function setupCloseHooks(nitro) {
171
168
  nitro.hooks.hook("close", async () => {
172
- await serverTypeGeneration(nitro, { silent: true });
173
- await clientTypeGeneration(nitro, { silent: true });
169
+ await generateServerTypes(nitro, { silent: true });
170
+ await generateClientTypes(nitro, { silent: true });
174
171
  });
172
+ }
173
+ /**
174
+ * Register GraphQL route handlers
175
+ */
176
+ function registerRouteHandlers(nitro) {
175
177
  const runtime = fileURLToPath(new URL("routes", import.meta.url));
176
- const methods = [
177
- "GET",
178
- "POST",
179
- "OPTIONS"
180
- ];
181
- if (nitro.options.graphql?.framework === "graphql-yoga") for (const method of methods) nitro.options.handlers.push({
178
+ const framework = nitro.options.graphql?.framework;
179
+ if (framework === "graphql-yoga") for (const method of GRAPHQL_HTTP_METHODS) nitro.options.handlers.push({
182
180
  route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
183
181
  handler: join(runtime, "graphql-yoga"),
184
182
  method
185
183
  });
186
- if (nitro.options.graphql?.framework === "apollo-server") for (const method of methods) nitro.options.handlers.push({
184
+ if (framework === "apollo-server") for (const method of GRAPHQL_HTTP_METHODS) nitro.options.handlers.push({
187
185
  route: nitro.options.runtimeConfig.graphql?.endpoint?.graphql || "/api/graphql",
188
186
  handler: join(runtime, "apollo-server"),
189
187
  method
@@ -194,182 +192,28 @@ async function setupNitroGraphQL(nitro) {
194
192
  method: "GET"
195
193
  });
196
194
  if (nitro.options.dev) nitro.options.handlers.push({
197
- route: "/_nitro/graphql/debug",
195
+ route: ENDPOINT_DEBUG,
198
196
  handler: join(runtime, "debug"),
199
197
  method: "GET"
200
198
  });
201
- nitro.hooks.hook("rollup:before", (_, rollupConfig$1) => {
202
- const manualChunks = rollupConfig$1.output?.manualChunks;
203
- const chunkFiles = rollupConfig$1.output?.chunkFileNames;
204
- if (!rollupConfig$1.output.inlineDynamicImports) {
205
- rollupConfig$1.output.manualChunks = (id, meta) => {
206
- if (id.endsWith(".graphql") || id.endsWith(".gql")) {
207
- let graphqlIndex = id.indexOf("server/graphql/");
208
- let baseLength = 15;
209
- if (graphqlIndex === -1) {
210
- graphqlIndex = id.indexOf("routes/graphql/");
211
- baseLength = 15;
212
- }
213
- if (graphqlIndex !== -1) return id.slice(graphqlIndex + baseLength).replace(/\.(?:graphql|gql)$/, "-schema");
214
- return "schemas";
215
- }
216
- if (id.endsWith(".resolver.ts")) {
217
- let graphqlIndex = id.indexOf("server/graphql/");
218
- let baseLength = 15;
219
- if (graphqlIndex === -1) {
220
- graphqlIndex = id.indexOf("routes/graphql/");
221
- baseLength = 15;
222
- }
223
- if (graphqlIndex !== -1) return id.slice(graphqlIndex + baseLength).replace(/\.resolver\.ts$/, "");
224
- return "resolvers";
225
- }
226
- if (typeof manualChunks === "function") return manualChunks(id, meta);
227
- };
228
- rollupConfig$1.output.advancedChunks = {
229
- groups: [{
230
- name: (moduleId) => {
231
- if (!moduleId.endsWith(".graphql") && !moduleId.endsWith(".gql")) return;
232
- let graphqlIndex = moduleId.indexOf("server/graphql/");
233
- let baseLength = 15;
234
- if (graphqlIndex === -1) {
235
- graphqlIndex = moduleId.indexOf("routes/graphql/");
236
- baseLength = 15;
237
- }
238
- if (graphqlIndex !== -1) return moduleId.slice(graphqlIndex + baseLength).replace(/\.(?:graphql|gql)$/, "-schema");
239
- return "schemas";
240
- },
241
- test: /\.(?:graphql|gql)$/
242
- }, {
243
- name: (moduleId) => {
244
- if (!moduleId.endsWith(".resolver.ts")) return;
245
- let graphqlIndex = moduleId.indexOf("server/graphql/");
246
- let baseLength = 15;
247
- if (graphqlIndex === -1) {
248
- graphqlIndex = moduleId.indexOf("routes/graphql/");
249
- baseLength = 15;
250
- }
251
- if (graphqlIndex !== -1) return moduleId.slice(graphqlIndex + baseLength).replace(/\.resolver\.ts$/, "");
252
- return "resolvers";
253
- },
254
- test: /\.resolver\.(?:ts|js)$/
255
- }],
256
- minSize: 0,
257
- minShareCount: 1
258
- };
259
- }
260
- rollupConfig$1.output.chunkFileNames = (chunkInfo) => {
261
- if (chunkInfo.moduleIds && chunkInfo.moduleIds.some((id) => id.endsWith(".graphql") || id.endsWith(".resolver.ts") || id.endsWith(".gql"))) return `chunks/graphql/[name].mjs`;
262
- if (typeof chunkFiles === "function") return chunkFiles(chunkInfo);
263
- return `chunks/_/[name].mjs`;
264
- };
265
- });
266
- nitro.options.typescript.strict = true;
199
+ }
200
+ /**
201
+ * Setup TypeScript configuration and path aliases
202
+ */
203
+ function setupTypeScriptConfiguration(nitro) {
204
+ nitro.options.typescript.strict = DEFAULT_TYPESCRIPT_STRICT;
267
205
  nitro.hooks.hook("types:extend", (types) => {
268
- types.tsConfig ||= {};
269
- types.tsConfig.compilerOptions ??= {};
270
- types.tsConfig.compilerOptions.paths ??= {};
271
- const placeholders = getDefaultPaths(nitro);
272
- const typesConfig = getTypesConfig(nitro);
273
- const serverTypesPath = resolveFilePath(typesConfig.server, typesConfig.enabled, true, "{typesDir}/nitro-graphql-server.d.ts", placeholders);
274
- if (serverTypesPath) types.tsConfig.compilerOptions.paths["#graphql/server"] = [relativeWithDot(tsconfigDir, serverTypesPath)];
275
- const clientTypesPath = resolveFilePath(typesConfig.client, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client.d.ts", placeholders);
276
- if (clientTypesPath) types.tsConfig.compilerOptions.paths["#graphql/client"] = [relativeWithDot(tsconfigDir, clientTypesPath)];
277
- types.tsConfig.compilerOptions.paths["#graphql/schema"] = [relativeWithDot(tsconfigDir, join(nitro.graphql.serverDir, "schema.ts"))];
278
- if (nitro.options.graphql?.externalServices?.length) for (const service of nitro.options.graphql.externalServices) {
279
- const servicePlaceholders = {
280
- ...placeholders,
281
- serviceName: service.name
282
- };
283
- const externalTypesPath = resolveFilePath(service.paths?.types ?? typesConfig.external, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client-{serviceName}.d.ts", servicePlaceholders);
284
- if (externalTypesPath) types.tsConfig.compilerOptions.paths[`#graphql/client/${service.name}`] = [relativeWithDot(tsconfigDir, externalTypesPath)];
285
- }
286
- types.tsConfig.include = types.tsConfig.include || [];
287
- if (serverTypesPath) types.tsConfig.include.push(relativeWithDot(tsconfigDir, serverTypesPath));
288
- if (clientTypesPath) types.tsConfig.include.push(relativeWithDot(tsconfigDir, clientTypesPath));
289
- types.tsConfig.include.push(relativeWithDot(tsconfigDir, join(placeholders.typesDir, "graphql.d.ts")));
290
- if (nitro.options.graphql?.externalServices?.length) for (const service of nitro.options.graphql.externalServices) {
291
- const servicePlaceholders = {
292
- ...placeholders,
293
- serviceName: service.name
294
- };
295
- const externalTypesPath = resolveFilePath(service.paths?.types ?? typesConfig.external, typesConfig.enabled, true, "{typesDir}/nitro-graphql-client-{serviceName}.d.ts", servicePlaceholders);
296
- if (externalTypesPath) types.tsConfig.include.push(relativeWithDot(tsconfigDir, externalTypesPath));
297
- }
206
+ setupTypeScriptPaths(nitro, types);
298
207
  });
299
- if (nitro.options.framework?.name === "nuxt" && nitro.options.graphql?.externalServices?.length) nitro.hooks.hook("build:before", () => {
208
+ }
209
+ /**
210
+ * Setup Nuxt-specific integration
211
+ */
212
+ function setupNuxtIntegration(nitro) {
213
+ if (nitro.options.framework?.name === FRAMEWORK_NUXT && nitro.options.graphql?.externalServices?.length) nitro.hooks.hook("build:before", () => {
300
214
  const nuxtOptions = nitro._nuxt?.options;
301
215
  if (nuxtOptions) nuxtOptions.nitroGraphqlExternalServices = nitro.options.graphql?.externalServices || [];
302
216
  });
303
- if (shouldGenerateScaffold(nitro)) {
304
- const placeholders = getDefaultPaths(nitro);
305
- const scaffoldConfig = getScaffoldConfig(nitro);
306
- const graphqlConfigPath = resolveFilePath(scaffoldConfig.graphqlConfig, scaffoldConfig.enabled, true, "graphql.config.ts", placeholders);
307
- if (graphqlConfigPath) writeFileIfNotExists(graphqlConfigPath, `
308
- import type { IGraphQLConfig } from 'graphql-config'
309
-
310
- export default <IGraphQLConfig> {
311
- projects: {
312
- default: {
313
- schema: [
314
- '${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.buildDir, "schema.graphql"))}',
315
- ],
316
- documents: [
317
- '${relativeWithDot(nitro.options.rootDir, resolve(nitro.graphql.clientDir, "**/*.{graphql,js,ts,jsx,tsx}"))}',
318
- ],
319
- },
320
- },
321
- }`, "graphql.config.ts");
322
- const serverSchemaPath = resolveFilePath(scaffoldConfig.serverSchema, scaffoldConfig.enabled, true, "{serverGraphql}/schema.ts", placeholders);
323
- const serverConfigPath = resolveFilePath(scaffoldConfig.serverConfig, scaffoldConfig.enabled, true, "{serverGraphql}/config.ts", placeholders);
324
- const serverContextPath = resolveFilePath(scaffoldConfig.serverContext, scaffoldConfig.enabled, true, "{serverGraphql}/context.d.ts", placeholders);
325
- if (serverSchemaPath || serverConfigPath || serverContextPath) {
326
- if (!existsSync(nitro.graphql.serverDir)) mkdirSync(nitro.graphql.serverDir, { recursive: true });
327
- }
328
- if (serverSchemaPath) writeFileIfNotExists(serverSchemaPath, `export default defineSchema({
329
-
330
- })
331
- `, "server schema.ts");
332
- if (serverConfigPath) writeFileIfNotExists(serverConfigPath, `// Example GraphQL config file please change it to your needs
333
- // import * as tables from '../drizzle/schema/index'
334
- // import { useDatabase } from '../utils/useDb'
335
- import { defineGraphQLConfig } from 'nitro-graphql/define'
336
-
337
- export default defineGraphQLConfig({
338
- // graphql-yoga example config
339
- // context: () => {
340
- // return {
341
- // context: {
342
- // useDatabase,
343
- // tables,
344
- // },
345
- // }
346
- // },
347
- })
348
- `, "server config.ts");
349
- if (serverContextPath) writeFileIfNotExists(serverContextPath, `// Example context definition - please change it to your needs
350
- // import type { Database } from '../utils/useDb'
351
-
352
- declare module 'nitro/h3' {
353
- interface H3EventContext {
354
- // Add your custom context properties here
355
- // useDatabase: () => Database
356
- // tables: typeof import('../drizzle/schema')
357
- // auth?: {
358
- // user?: {
359
- // id: string
360
- // role: 'admin' | 'user'
361
- // }
362
- // }
363
- }
364
- }
365
-
366
- export {}
367
- `, "server context.d.ts");
368
- if (existsSync(join(nitro.graphql.serverDir, "context.ts"))) {
369
- logger.warn("Found context.ts file. Please rename it to context.d.ts for type-only definitions.");
370
- logger.info("The context file should now be context.d.ts instead of context.ts");
371
- }
372
- } else logger.info("Scaffold file generation is disabled (library mode)");
373
217
  }
374
218
 
375
219
  //#endregion
@@ -1,10 +1,10 @@
1
1
  import { StandardSchemaV1 } from "./standard-schema.mjs";
2
- import { ESMCodeGenOptions } from "knitwork";
3
- import { IResolvers } from "@graphql-tools/utils";
4
2
  import { TypeScriptPluginConfig } from "@graphql-codegen/typescript";
5
3
  import { plugin as plugin$1 } from "@graphql-codegen/typescript-generic-sdk";
6
4
  import { TypeScriptDocumentsPluginConfig } from "@graphql-codegen/typescript-operations";
5
+ import { IResolvers } from "@graphql-tools/utils";
7
6
  import { TypeScriptResolversPluginConfig } from "@graphql-codegen/typescript-resolvers";
7
+ import { ESMCodeGenOptions } from "knitwork";
8
8
 
9
9
  //#region src/types/index.d.ts
10
10
  type CodegenServerConfig = TypeScriptPluginConfig & TypeScriptResolversPluginConfig;
@@ -1,7 +1,7 @@
1
1
  import { CodegenClientConfig, ExternalGraphQLService, GenericSdkConfig } from "../types/index.mjs";
2
2
  import { GraphQLSchema } from "graphql";
3
- import { Source } from "@graphql-tools/utils";
4
3
  import { LoadSchemaOptions, UnnormalizedTypeDefPointer } from "@graphql-tools/load";
4
+ import { Source } from "@graphql-tools/utils";
5
5
 
6
6
  //#region src/utils/client-codegen.d.ts
7
7
 
@@ -1,9 +1,10 @@
1
+ import { DEFAULT_GRAPHQL_SCALARS } from "../constants/scalars.mjs";
2
+ import { pluginContent } from "./codegen-plugin.mjs";
1
3
  import { defu as defu$1 } from "defu";
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
4
  import { consola as consola$1 } from "consola";
4
5
  import { dirname, resolve } from "pathe";
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
7
  import { parse } from "graphql";
6
- import { printSchemaWithDirectives } from "@graphql-tools/utils";
7
8
  import { createHash } from "node:crypto";
8
9
  import { codegen } from "@graphql-codegen/core";
9
10
  import { preset } from "@graphql-codegen/import-types-preset";
@@ -13,21 +14,9 @@ import { plugin as plugin$2 } 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";
16
- import { CurrencyResolver, DateTimeISOResolver, DateTimeResolver, JSONObjectResolver, JSONResolver, NonEmptyStringResolver, UUIDResolver } from "graphql-scalars";
17
+ import { printSchemaWithDirectives } from "@graphql-tools/utils";
17
18
 
18
19
  //#region src/utils/client-codegen.ts
19
- function pluginContent(_schema, _documents, _config, _info) {
20
- return {
21
- prepend: [
22
- "// THIS FILE IS GENERATED, DO NOT EDIT!",
23
- "/* eslint-disable eslint-comments/no-unlimited-disable */",
24
- "/* tslint:disable */",
25
- "/* eslint-disable */",
26
- "/* prettier-ignore */"
27
- ],
28
- content: ""
29
- };
30
- }
31
20
  async function graphQLLoadSchemaSync(schemaPointers, data = {}) {
32
21
  const filteredPointers = [...Array.isArray(schemaPointers) ? schemaPointers : [schemaPointers], "!**/vfs/**"];
33
22
  let result;
@@ -182,19 +171,7 @@ async function generateClientTypes(schema, docs, config = {}, sdkConfig = {}, ou
182
171
  pureMagicComment: true,
183
172
  dedupeOperationSuffix: true,
184
173
  rawRequest: true,
185
- scalars: {
186
- DateTime: DateTimeResolver.extensions.codegenScalarType,
187
- DateTimeISO: DateTimeISOResolver.extensions.codegenScalarType,
188
- UUID: UUIDResolver.extensions.codegenScalarType,
189
- JSON: JSONResolver.extensions.codegenScalarType,
190
- JSONObject: JSONObjectResolver.extensions.codegenScalarType,
191
- NonEmptyString: NonEmptyStringResolver.extensions.codegenScalarType,
192
- Currency: CurrencyResolver.extensions.codegenScalarType,
193
- File: {
194
- input: "File",
195
- output: "File"
196
- }
197
- }
174
+ scalars: DEFAULT_GRAPHQL_SCALARS
198
175
  }, config);
199
176
  const mergedSdkConfig = defu$1(mergedConfig, sdkConfig);
200
177
  try {
@@ -0,0 +1,20 @@
1
+ import { GraphQLSchema } from "graphql";
2
+ import { Source } from "@graphql-tools/utils";
3
+
4
+ //#region src/utils/codegen-plugin.d.ts
5
+
6
+ /**
7
+ * Plugin to add prepend comments to generated files
8
+ * Used by both server and client codegen
9
+ */
10
+ declare function pluginContent(_schema: GraphQLSchema, _documents: Source[], _config: Record<string, unknown> | undefined, _info: Record<string, unknown> | undefined): {
11
+ prepend: string[];
12
+ content: string;
13
+ };
14
+ /**
15
+ * Generate the prepend header for generated files
16
+ * Can be used when creating files manually without codegen
17
+ */
18
+ declare const GENERATED_FILE_HEADER = "// THIS FILE IS GENERATED, DO NOT EDIT!\n/* eslint-disable eslint-comments/no-unlimited-disable */\n/* tslint:disable */\n/* eslint-disable */\n/* prettier-ignore */\n";
19
+ //#endregion
20
+ export { GENERATED_FILE_HEADER, pluginContent };
@@ -0,0 +1,30 @@
1
+ //#region src/utils/codegen-plugin.ts
2
+ /**
3
+ * Plugin to add prepend comments to generated files
4
+ * Used by both server and client codegen
5
+ */
6
+ function pluginContent(_schema, _documents, _config, _info) {
7
+ return {
8
+ prepend: [
9
+ "// THIS FILE IS GENERATED, DO NOT EDIT!",
10
+ "/* eslint-disable eslint-comments/no-unlimited-disable */",
11
+ "/* tslint:disable */",
12
+ "/* eslint-disable */",
13
+ "/* prettier-ignore */"
14
+ ],
15
+ content: ""
16
+ };
17
+ }
18
+ /**
19
+ * Generate the prepend header for generated files
20
+ * Can be used when creating files manually without codegen
21
+ */
22
+ const GENERATED_FILE_HEADER = `// THIS FILE IS GENERATED, DO NOT EDIT!
23
+ /* eslint-disable eslint-comments/no-unlimited-disable */
24
+ /* tslint:disable */
25
+ /* eslint-disable */
26
+ /* prettier-ignore */
27
+ `;
28
+
29
+ //#endregion
30
+ export { GENERATED_FILE_HEADER, pluginContent };
@@ -70,8 +70,9 @@ declare class DirectiveParser {
70
70
  declare function generateDirectiveSchema(directive: ParsedDirective): string;
71
71
  /**
72
72
  * Generate directive schemas file from scanned directives
73
+ * @returns The path to the generated _directives.graphql file, or null if no directives
73
74
  */
74
- declare function generateDirectiveSchemas(nitro: any, directives: any[]): Promise<void>;
75
+ declare function generateDirectiveSchemas(nitro: any, directives: any[]): Promise<string | null>;
75
76
  /**
76
77
  * Singleton instance for reuse
77
78
  */