nitro-graphql 2.0.0-beta.1 → 2.0.0-beta.10

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.
@@ -57,6 +57,18 @@ declare module 'nitro/types' {
57
57
  graphql?: NitroGraphQLOptions;
58
58
  }
59
59
  }
60
+ /**
61
+ * Service-specific path overrides for external GraphQL services
62
+ * These paths override global config for this specific service
63
+ */
64
+ interface ExternalServicePaths {
65
+ /** SDK file path (overrides global sdk.external config) */
66
+ sdk?: FileGenerationConfig;
67
+ /** Type definitions file path (overrides global types.external config) */
68
+ types?: FileGenerationConfig;
69
+ /** ofetch client wrapper path (overrides global clientUtils.ofetch config) */
70
+ ofetch?: FileGenerationConfig;
71
+ }
60
72
  interface ExternalGraphQLService {
61
73
  /** Unique name for this service (used for file naming and type generation) */
62
74
  name: string;
@@ -83,6 +95,12 @@ interface ExternalGraphQLService {
83
95
  client?: CodegenClientConfig;
84
96
  clientSDK?: GenericSdkConfig;
85
97
  };
98
+ /**
99
+ * Optional: Service-specific path overrides
100
+ * These paths take precedence over global config (sdk, types, clientUtils)
101
+ * Supports placeholders: {serviceName}, {buildDir}, {rootDir}, {framework}, {typesDir}, {clientGraphql}
102
+ */
103
+ paths?: ExternalServicePaths;
86
104
  }
87
105
  interface FederationConfig {
88
106
  /** Enable Apollo Federation subgraph support */
@@ -94,6 +112,81 @@ interface FederationConfig {
94
112
  /** Service URL for federation gateway */
95
113
  serviceUrl?: string;
96
114
  }
115
+ /**
116
+ * File generation control:
117
+ * - false: Do not generate this file
118
+ * - true: Generate at default location
119
+ * - string: Generate at custom path (supports placeholders: {serviceName}, {buildDir}, {rootDir}, {framework})
120
+ */
121
+ type FileGenerationConfig = boolean | string;
122
+ /**
123
+ * Scaffold files configuration
124
+ * Control auto-generation of scaffold/boilerplate files
125
+ */
126
+ interface ScaffoldConfig {
127
+ /** Enable/disable all scaffold files */
128
+ enabled?: boolean;
129
+ /** graphql.config.ts - GraphQL Config file for IDE tooling */
130
+ graphqlConfig?: FileGenerationConfig;
131
+ /** server/graphql/schema.ts - Schema definition file */
132
+ serverSchema?: FileGenerationConfig;
133
+ /** server/graphql/config.ts - GraphQL server configuration */
134
+ serverConfig?: FileGenerationConfig;
135
+ /** server/graphql/context.ts - H3 context augmentation */
136
+ serverContext?: FileGenerationConfig;
137
+ }
138
+ /**
139
+ * Client utilities configuration
140
+ * Control auto-generation of client-side utility files (Nuxt only)
141
+ */
142
+ interface ClientUtilsConfig {
143
+ /** Enable/disable all client utilities */
144
+ enabled?: boolean;
145
+ /** app/graphql/index.ts - Main exports file */
146
+ index?: FileGenerationConfig;
147
+ /** app/graphql/{serviceName}/ofetch.ts - ofetch client wrapper */
148
+ ofetch?: FileGenerationConfig;
149
+ }
150
+ /**
151
+ * SDK files configuration
152
+ * Control auto-generation of GraphQL SDK files
153
+ */
154
+ interface SdkConfig {
155
+ /** Enable/disable all SDK files */
156
+ enabled?: boolean;
157
+ /** app/graphql/default/sdk.ts - Main service SDK */
158
+ main?: FileGenerationConfig;
159
+ /** app/graphql/{serviceName}/sdk.ts - External service SDKs */
160
+ external?: FileGenerationConfig;
161
+ }
162
+ /**
163
+ * Type files configuration
164
+ * Control auto-generation of TypeScript type definition files
165
+ */
166
+ interface TypesConfig {
167
+ /** Enable/disable all type files */
168
+ enabled?: boolean;
169
+ /** .nitro/types/nitro-graphql-server.d.ts - Server-side types */
170
+ server?: FileGenerationConfig;
171
+ /** .nitro/types/nitro-graphql-client.d.ts - Client-side types */
172
+ client?: FileGenerationConfig;
173
+ /** .nitro/types/nitro-graphql-client-{serviceName}.d.ts - External service types */
174
+ external?: FileGenerationConfig;
175
+ }
176
+ /**
177
+ * Global path overrides
178
+ * Set base directories for file generation
179
+ */
180
+ interface PathsConfig {
181
+ /** Server GraphQL directory (default: 'server/graphql') */
182
+ serverGraphql?: string;
183
+ /** Client GraphQL directory (default: 'app/graphql' for Nuxt, 'graphql' for Nitro) */
184
+ clientGraphql?: string;
185
+ /** Build directory (default: '.nitro' or '.nuxt') */
186
+ buildDir?: string;
187
+ /** Types directory (default: '{buildDir}/types') */
188
+ typesDir?: string;
189
+ }
97
190
  interface NitroGraphQLOptions {
98
191
  framework: 'graphql-yoga' | 'apollo-server';
99
192
  endpoint?: {
@@ -123,6 +216,31 @@ interface NitroGraphQLOptions {
123
216
  layerDirectories?: string[];
124
217
  layerServerDirs?: string[];
125
218
  layerAppDirs?: string[];
219
+ /**
220
+ * Scaffold files configuration
221
+ * Set to false to disable all scaffold file generation (library mode)
222
+ */
223
+ scaffold?: false | ScaffoldConfig;
224
+ /**
225
+ * Client utilities configuration
226
+ * Set to false to disable all client utility generation
227
+ */
228
+ clientUtils?: false | ClientUtilsConfig;
229
+ /**
230
+ * SDK files configuration
231
+ * Set to false to disable all SDK generation
232
+ */
233
+ sdk?: false | SdkConfig;
234
+ /**
235
+ * Type files configuration
236
+ * Set to false to disable all type generation
237
+ */
238
+ types?: false | TypesConfig;
239
+ /**
240
+ * Global path overrides
241
+ * Customize base directories for file generation
242
+ */
243
+ paths?: PathsConfig;
126
244
  }
127
245
  //#endregion
128
- export { CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, FederationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions };
246
+ export { ClientUtilsConfig, CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, ExternalServicePaths, FederationConfig, FileGenerationConfig, GenImport, GenericSdkConfig, NitroGraphQLOptions, PathsConfig, ScaffoldConfig, SdkConfig, TypesConfig };
@@ -18,13 +18,9 @@ var DirectiveParser = class {
18
18
  sourceType: "module",
19
19
  astType: "ts"
20
20
  });
21
- if (result.errors.length > 0) {
22
- console.warn(`Parse errors in ${filePath}:`, result.errors.map((e) => e.message));
23
- return [];
24
- }
21
+ if (result.errors.length > 0) return [];
25
22
  return this.extractDirectiveDefinitions(result.program);
26
- } catch (error) {
27
- console.warn(`Failed to parse ${filePath} with oxc:`, error);
23
+ } catch {
28
24
  return [];
29
25
  }
30
26
  }
@@ -205,7 +201,7 @@ async function generateDirectiveSchemas(nitro, directives) {
205
201
  }
206
202
  }
207
203
  if (directiveSchemas.length > 0) {
208
- const directivesPath = resolve(nitro.graphql.serverDir, "_directives.graphql");
204
+ const directivesPath = resolve(nitro.graphql.buildDir, "_directives.graphql");
209
205
  const content = `# WARNING: This file is auto-generated by nitro-graphql
210
206
  # Do not modify this file directly. It will be overwritten.
211
207
  # To define custom directives, create .directive.ts files using defineDirective()
@@ -0,0 +1,37 @@
1
+ import { Nitro } from "nitropack/types";
2
+
3
+ //#region src/utils/file-generator.d.ts
4
+
5
+ /**
6
+ * Safely write a file to disk, creating parent directories if needed
7
+ */
8
+ declare function writeFile(filePath: string, content: string, description?: string): void;
9
+ /**
10
+ * Write a file only if it doesn't already exist
11
+ * Returns true if file was created, false if it already existed
12
+ */
13
+ declare function writeFileIfNotExists(filePath: string, content: string, description?: string): boolean;
14
+ /**
15
+ * Write a file and always overwrite (used for generated files like SDK)
16
+ * This is for files that are auto-generated and should be updated on every build
17
+ */
18
+ declare function writeGeneratedFile(filePath: string, content: string, description?: string): void;
19
+ /**
20
+ * Check if a path is configured and should be generated
21
+ * Returns the resolved path if should generate, null otherwise
22
+ */
23
+ declare function getGenerationPath(resolvedPath: string | null, description?: string): string | null;
24
+ /**
25
+ * Log skipped file generation (helpful for debugging library mode)
26
+ */
27
+ declare function logSkipped(fileName: string, reason?: string): void;
28
+ /**
29
+ * Log generated file path
30
+ */
31
+ declare function logGenerated(fileName: string, path: string): void;
32
+ /**
33
+ * Validate that a Nitro instance has the required GraphQL configuration
34
+ */
35
+ declare function validateGraphQLConfig(nitro: Nitro): boolean;
36
+ //#endregion
37
+ export { getGenerationPath, logGenerated, logSkipped, validateGraphQLConfig, writeFile, writeFileIfNotExists, writeGeneratedFile };
@@ -0,0 +1,72 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import consola from "consola";
3
+ import { dirname } from "pathe";
4
+
5
+ //#region src/utils/file-generator.ts
6
+ /**
7
+ * Safely write a file to disk, creating parent directories if needed
8
+ */
9
+ function writeFile(filePath, content, description) {
10
+ try {
11
+ const dir = dirname(filePath);
12
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
13
+ writeFileSync(filePath, content, "utf-8");
14
+ if (description) consola.success(`[nitro-graphql] Generated: ${description}`);
15
+ } catch (error) {
16
+ consola.error(`[nitro-graphql] Failed to write file: ${filePath}`, error);
17
+ throw error;
18
+ }
19
+ }
20
+ /**
21
+ * Write a file only if it doesn't already exist
22
+ * Returns true if file was created, false if it already existed
23
+ */
24
+ function writeFileIfNotExists(filePath, content, description) {
25
+ if (existsSync(filePath)) return false;
26
+ writeFile(filePath, content, description);
27
+ return true;
28
+ }
29
+ /**
30
+ * Write a file and always overwrite (used for generated files like SDK)
31
+ * This is for files that are auto-generated and should be updated on every build
32
+ */
33
+ function writeGeneratedFile(filePath, content, description) {
34
+ writeFile(filePath, content, description);
35
+ }
36
+ /**
37
+ * Check if a path is configured and should be generated
38
+ * Returns the resolved path if should generate, null otherwise
39
+ */
40
+ function getGenerationPath(resolvedPath, description) {
41
+ if (!resolvedPath) {
42
+ if (description) consola.debug(`[nitro-graphql] Skipping generation: ${description} (disabled in config)`);
43
+ return null;
44
+ }
45
+ return resolvedPath;
46
+ }
47
+ /**
48
+ * Log skipped file generation (helpful for debugging library mode)
49
+ */
50
+ function logSkipped(fileName, reason) {
51
+ const message = reason ? `Skipped ${fileName}: ${reason}` : `Skipped ${fileName}`;
52
+ consola.debug(`[nitro-graphql] ${message}`);
53
+ }
54
+ /**
55
+ * Log generated file path
56
+ */
57
+ function logGenerated(fileName, path) {
58
+ consola.info(`[nitro-graphql] Generated ${fileName} at: ${path}`);
59
+ }
60
+ /**
61
+ * Validate that a Nitro instance has the required GraphQL configuration
62
+ */
63
+ function validateGraphQLConfig(nitro) {
64
+ if (!nitro.options.graphql?.framework) {
65
+ consola.warn("[nitro-graphql] No GraphQL framework specified. Some features may not work correctly.");
66
+ return false;
67
+ }
68
+ return true;
69
+ }
70
+
71
+ //#endregion
72
+ export { getGenerationPath, logGenerated, logSkipped, validateGraphQLConfig, writeFile, writeFileIfNotExists, writeGeneratedFile };
@@ -19,13 +19,12 @@ declare function getLayerAppDirectories(nitro: Nitro): string[];
19
19
  /**
20
20
  * Generate layer-aware ignore patterns for auto-generated files
21
21
  */
22
- declare function generateLayerIgnorePatterns(nitro: Nitro): string[];
22
+ declare function generateLayerIgnorePatterns(): string[];
23
23
  declare function getImportId(p: string, lazy?: boolean): string;
24
24
  declare function relativeWithDot(from: string, to: string): string;
25
25
  declare function scanGraphql(nitro: Nitro): Promise<string[]>;
26
26
  declare function scanResolvers(nitro: Nitro): Promise<GenImport[]>;
27
27
  declare function scanDirectives(nitro: Nitro): Promise<GenImport[]>;
28
- declare function scanTypeDefs(nitro: Nitro): Promise<string[]>;
29
28
  declare function scanSchemas(nitro: Nitro): Promise<string[]>;
30
29
  declare function scanDocs(nitro: Nitro): Promise<string[]>;
31
30
  /**
@@ -37,4 +36,4 @@ declare function scanExternalServiceDocs(nitro: Nitro, serviceName: string, patt
37
36
  */
38
37
  declare function validateExternalServices(services: unknown[]): string[];
39
38
  //#endregion
40
- export { GLOB_SCAN_PATTERN, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, scanTypeDefs, validateExternalServices };
39
+ export { GLOB_SCAN_PATTERN, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, validateExternalServices };
@@ -28,12 +28,8 @@ function getLayerAppDirectories(nitro) {
28
28
  /**
29
29
  * Generate layer-aware ignore patterns for auto-generated files
30
30
  */
31
- function generateLayerIgnorePatterns(nitro) {
32
- const patterns = [];
33
- patterns.push(`${nitro.graphql.serverDir}/_directives.graphql`);
34
- const layerServerDirs = nitro.options.graphql?.layerServerDirs || [];
35
- for (const layerServerDir of layerServerDirs) patterns.push(`${layerServerDir}/graphql/_directives.graphql`);
36
- return patterns;
31
+ function generateLayerIgnorePatterns() {
32
+ return [];
37
33
  }
38
34
  function getImportId(p, lazy) {
39
35
  return (lazy ? "_lazy_" : "_") + hash(p).replace(/-/g, "").slice(0, 6);
@@ -44,60 +40,118 @@ function relativeWithDot(from, to) {
44
40
  return RELATIVE_RE.test(rel) ? rel : `./${rel}`;
45
41
  }
46
42
  async function scanGraphql(nitro) {
47
- return (await scanFiles(nitro, "graphql")).map((f) => f.fullPath);
43
+ const serverDirRelative = relative(nitro.options.rootDir, nitro.graphql.serverDir);
44
+ const files = await scanDir(nitro, nitro.options.rootDir, serverDirRelative, "**/*.{graphql,gql}");
45
+ const layerServerDirs = getLayerServerDirectories(nitro);
46
+ const layerFiles = await Promise.all(layerServerDirs.map((layerServerDir) => scanDir(nitro, layerServerDir, "graphql", "**/*.{graphql,gql}"))).then((r) => r.flat());
47
+ const allFiles = [...files, ...layerFiles];
48
+ const seenPaths = /* @__PURE__ */ new Set();
49
+ return allFiles.filter((file) => {
50
+ if (seenPaths.has(file.fullPath)) return false;
51
+ seenPaths.add(file.fullPath);
52
+ return true;
53
+ }).map((f) => f.fullPath);
48
54
  }
49
55
  async function scanResolvers(nitro) {
50
- const files = await scanFiles(nitro, "graphql", "**/*.resolver.{ts,js}");
56
+ const serverDirRelative = relative(nitro.options.rootDir, nitro.graphql.serverDir);
57
+ const regularFiles = await scanDir(nitro, nitro.options.rootDir, serverDirRelative, "**/*.resolver.{ts,js}");
58
+ const layerServerDirs = getLayerServerDirectories(nitro);
59
+ const layerFiles = await Promise.all(layerServerDirs.map((layerServerDir) => scanDir(nitro, layerServerDir, "graphql", "**/*.resolver.{ts,js}"))).then((r) => r.flat());
60
+ const allFiles = [...regularFiles, ...layerFiles];
61
+ const seenPaths = /* @__PURE__ */ new Set();
62
+ const files = allFiles.filter((file) => {
63
+ if (seenPaths.has(file.fullPath)) return false;
64
+ seenPaths.add(file.fullPath);
65
+ return true;
66
+ });
51
67
  const exportName = [];
52
- for (const file of files) {
68
+ const VALID_DEFINE_FUNCTIONS = [
69
+ "defineResolver",
70
+ "defineQuery",
71
+ "defineMutation",
72
+ "defineType",
73
+ "defineSubscription",
74
+ "defineDirective"
75
+ ];
76
+ for (const file of files) try {
53
77
  const fileContent = await readFile(file.fullPath, "utf-8");
54
78
  const parsed = await parseAsync(file.fullPath, fileContent);
55
79
  const exports = {
56
80
  imports: [],
57
81
  specifier: file.fullPath
58
82
  };
59
- for (const node of parsed.program.body) if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") {
60
- for (const decl of node.declaration.declarations) if (decl.type === "VariableDeclarator" && decl.init && decl.id.type === "Identifier") {
61
- if (decl.init && decl.init.type === "CallExpression") {
62
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineResolver") exports.imports.push({
63
- name: decl.id.name,
64
- type: "resolver",
65
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
66
- });
67
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineQuery") exports.imports.push({
68
- name: decl.id.name,
69
- type: "query",
70
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
71
- });
72
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineMutation") exports.imports.push({
73
- name: decl.id.name,
74
- type: "mutation",
75
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
76
- });
77
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineType") exports.imports.push({
78
- name: decl.id.name,
79
- type: "type",
80
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
81
- });
82
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineSubscription") exports.imports.push({
83
- name: decl.id.name,
84
- type: "subscription",
85
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
86
- });
87
- if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineDirective") exports.imports.push({
88
- name: decl.id.name,
89
- type: "directive",
90
- as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
91
- });
83
+ let hasDefaultExport = false;
84
+ let hasNamedExport = false;
85
+ const namedExports = [];
86
+ for (const node of parsed.program.body) {
87
+ if (node.type === "ExportDefaultDeclaration") hasDefaultExport = true;
88
+ if (node.type === "ExportNamedDeclaration" && node.declaration && node.declaration.type === "VariableDeclaration") {
89
+ for (const decl of node.declaration.declarations) if (decl.type === "VariableDeclarator" && decl.init && decl.id.type === "Identifier") {
90
+ hasNamedExport = true;
91
+ namedExports.push(decl.id.name);
92
+ if (decl.init && decl.init.type === "CallExpression") {
93
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineResolver") exports.imports.push({
94
+ name: decl.id.name,
95
+ type: "resolver",
96
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
97
+ });
98
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineQuery") exports.imports.push({
99
+ name: decl.id.name,
100
+ type: "query",
101
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
102
+ });
103
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineMutation") exports.imports.push({
104
+ name: decl.id.name,
105
+ type: "mutation",
106
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
107
+ });
108
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineType") exports.imports.push({
109
+ name: decl.id.name,
110
+ type: "type",
111
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
112
+ });
113
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineSubscription") exports.imports.push({
114
+ name: decl.id.name,
115
+ type: "subscription",
116
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
117
+ });
118
+ if (decl.init.callee.type === "Identifier" && decl.init.callee.name === "defineDirective") exports.imports.push({
119
+ name: decl.id.name,
120
+ type: "directive",
121
+ as: `_${hash(decl.id.name + file.fullPath).replace(/-/g, "").slice(0, 6)}`
122
+ });
123
+ }
92
124
  }
93
125
  }
94
126
  }
127
+ if (nitro.options.dev) {
128
+ const relPath = relative(nitro.options.rootDir, file.fullPath);
129
+ if (hasDefaultExport && !hasNamedExport) nitro.logger.warn(`[nitro-graphql] ${relPath}: Using default export instead of named export. Resolvers must use named exports like "export const myResolver = defineQuery(...)". Default exports are not detected.`);
130
+ if (exports.imports.length === 0 && hasNamedExport) {
131
+ const validFunctions = VALID_DEFINE_FUNCTIONS.join(", ");
132
+ nitro.logger.warn(`[nitro-graphql] ${relPath}: File has named exports [${namedExports.join(", ")}] but none use the required define functions (${validFunctions}). Exports will not be registered.`);
133
+ }
134
+ if (!hasDefaultExport && !hasNamedExport) nitro.logger.warn(`[nitro-graphql] ${relPath}: No exports found. Resolver files must export resolvers using defineResolver, defineQuery, defineMutation, etc.`);
135
+ }
95
136
  if (exports.imports.length > 0) exportName.push(exports);
137
+ } catch (error) {
138
+ const relPath = relative(nitro.options.rootDir, file.fullPath);
139
+ nitro.logger.error(`[nitro-graphql] Failed to parse resolver file ${relPath}:`, error);
96
140
  }
97
141
  return exportName;
98
142
  }
99
143
  async function scanDirectives(nitro) {
100
- const files = await scanFiles(nitro, "graphql", "**/*.directive.{ts,js}");
144
+ const serverDirRelative = relative(nitro.options.rootDir, nitro.graphql.serverDir);
145
+ const regularFiles = await scanDir(nitro, nitro.options.rootDir, serverDirRelative, "**/*.directive.{ts,js}");
146
+ const layerServerDirs = getLayerServerDirectories(nitro);
147
+ const layerFiles = await Promise.all(layerServerDirs.map((layerServerDir) => scanDir(nitro, layerServerDir, "graphql", "**/*.directive.{ts,js}"))).then((r) => r.flat());
148
+ const allFiles = [...regularFiles, ...layerFiles];
149
+ const seenPaths = /* @__PURE__ */ new Set();
150
+ const files = allFiles.filter((file) => {
151
+ if (seenPaths.has(file.fullPath)) return false;
152
+ seenPaths.add(file.fullPath);
153
+ return true;
154
+ });
101
155
  const exportName = [];
102
156
  for (const file of files) {
103
157
  const fileContent = await readFile(file.fullPath, "utf-8");
@@ -121,11 +175,18 @@ async function scanDirectives(nitro) {
121
175
  }
122
176
  return exportName;
123
177
  }
124
- async function scanTypeDefs(nitro) {
125
- return (await scanFiles(nitro, "graphql", "**/*.typedef.{ts,js}")).map((f) => f.fullPath);
126
- }
127
178
  async function scanSchemas(nitro) {
128
- return (await scanFiles(nitro, "graphql", "**/*.graphql")).map((f) => f.fullPath);
179
+ const serverDirRelative = relative(nitro.options.rootDir, nitro.graphql.serverDir);
180
+ const files = await scanDir(nitro, nitro.options.rootDir, serverDirRelative, "**/*.graphql");
181
+ const layerServerDirs = getLayerServerDirectories(nitro);
182
+ const layerFiles = await Promise.all(layerServerDirs.map((layerServerDir) => scanDir(nitro, layerServerDir, "graphql", "**/*.graphql"))).then((r) => r.flat());
183
+ const allFiles = [...files, ...layerFiles];
184
+ const seenPaths = /* @__PURE__ */ new Set();
185
+ return allFiles.filter((file) => {
186
+ if (seenPaths.has(file.fullPath)) return false;
187
+ seenPaths.add(file.fullPath);
188
+ return true;
189
+ }).map((f) => f.fullPath);
129
190
  }
130
191
  async function scanDocs(nitro) {
131
192
  const files = await scanDir(nitro, nitro.options.rootDir, nitro.graphql.dir.client, "**/*.graphql");
@@ -193,18 +254,6 @@ function validateExternalServices(services) {
193
254
  }
194
255
  return errors;
195
256
  }
196
- async function scanFiles(nitro, name, globPattern = GLOB_SCAN_PATTERN) {
197
- const regularFiles = await Promise.all(nitro.options.scanDirs.map((dir) => scanDir(nitro, dir, name, globPattern))).then((r) => r.flat());
198
- const layerDirectories = getLayerDirectories(nitro);
199
- const layerFiles = await Promise.all(layerDirectories.map((layerDir) => scanDir(nitro, layerDir, `server/${name}`, globPattern))).then((r) => r.flat());
200
- const allFiles = [...regularFiles, ...layerFiles];
201
- const seenPaths = /* @__PURE__ */ new Set();
202
- return allFiles.filter((file) => {
203
- if (seenPaths.has(file.fullPath)) return false;
204
- seenPaths.add(file.fullPath);
205
- return true;
206
- });
207
- }
208
257
  async function scanDir(nitro, dir, name, globPattern = GLOB_SCAN_PATTERN) {
209
258
  return (await glob(join(name, globPattern), {
210
259
  cwd: dir,
@@ -226,4 +275,4 @@ async function scanDir(nitro, dir, name, globPattern = GLOB_SCAN_PATTERN) {
226
275
  }
227
276
 
228
277
  //#endregion
229
- export { GLOB_SCAN_PATTERN, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, scanTypeDefs, validateExternalServices };
278
+ export { GLOB_SCAN_PATTERN, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, validateExternalServices };
@@ -0,0 +1,70 @@
1
+ import { ClientUtilsConfig, FileGenerationConfig, ScaffoldConfig, SdkConfig, TypesConfig } from "../types/index.js";
2
+ import { Nitro } from "nitropack/types";
3
+
4
+ //#region src/utils/path-resolver.d.ts
5
+
6
+ /**
7
+ * Placeholder values for path resolution
8
+ */
9
+ interface PathPlaceholders {
10
+ serviceName?: string;
11
+ buildDir: string;
12
+ rootDir: string;
13
+ framework: 'nuxt' | 'nitro';
14
+ typesDir: string;
15
+ serverGraphql: string;
16
+ clientGraphql: string;
17
+ }
18
+ /**
19
+ * Replace placeholders in a path string
20
+ * Supports: {serviceName}, {buildDir}, {rootDir}, {framework}, {typesDir}, {serverGraphql}, {clientGraphql}
21
+ */
22
+ declare function replacePlaceholders(path: string, placeholders: PathPlaceholders): string;
23
+ /**
24
+ * Get default paths based on framework and user configuration
25
+ */
26
+ declare function getDefaultPaths(nitro: Nitro): Required<PathPlaceholders>;
27
+ /**
28
+ * Check if a file should be generated based on config
29
+ * Returns: true if should generate, false if should skip
30
+ */
31
+ declare function shouldGenerateFile(config: FileGenerationConfig | undefined, categoryEnabled: boolean | undefined, topLevelEnabled: boolean): boolean;
32
+ /**
33
+ * Resolve the file path based on configuration
34
+ * Returns: resolved absolute path or null if file should not be generated
35
+ */
36
+ declare function resolveFilePath(config: FileGenerationConfig | undefined, categoryEnabled: boolean | undefined, topLevelEnabled: boolean, defaultPath: string, placeholders: PathPlaceholders): string | null;
37
+ /**
38
+ * Check if scaffold files should be generated (category-level check)
39
+ */
40
+ declare function shouldGenerateScaffold(nitro: Nitro): boolean;
41
+ /**
42
+ * Get scaffold configuration (handles false case)
43
+ */
44
+ declare function getScaffoldConfig(nitro: Nitro): ScaffoldConfig;
45
+ /**
46
+ * Check if client utilities should be generated (category-level check)
47
+ */
48
+ declare function shouldGenerateClientUtils(nitro: Nitro): boolean;
49
+ /**
50
+ * Get client utilities configuration (handles false case)
51
+ */
52
+ declare function getClientUtilsConfig(nitro: Nitro): ClientUtilsConfig;
53
+ /**
54
+ * Check if SDK files should be generated (category-level check)
55
+ */
56
+ declare function shouldGenerateSDK(nitro: Nitro): boolean;
57
+ /**
58
+ * Get SDK configuration (handles false case)
59
+ */
60
+ declare function getSdkConfig(nitro: Nitro): SdkConfig;
61
+ /**
62
+ * Check if type files should be generated (category-level check)
63
+ */
64
+ declare function shouldGenerateTypes(nitro: Nitro): boolean;
65
+ /**
66
+ * Get types configuration (handles false case)
67
+ */
68
+ declare function getTypesConfig(nitro: Nitro): TypesConfig;
69
+ //#endregion
70
+ export { PathPlaceholders, getClientUtilsConfig, getDefaultPaths, getScaffoldConfig, getSdkConfig, getTypesConfig, replacePlaceholders, resolveFilePath, shouldGenerateClientUtils, shouldGenerateFile, shouldGenerateSDK, shouldGenerateScaffold, shouldGenerateTypes };