nitro-graphql 2.0.0-beta.1 → 2.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +829 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +110 -38
- package/dist/rollup.js +216 -59
- package/dist/routes/apollo-server.d.ts +2 -2
- package/dist/routes/apollo-server.js +5 -5
- package/dist/routes/debug.d.ts +61 -0
- package/dist/routes/debug.js +449 -0
- package/dist/routes/graphql-yoga.d.ts +2 -2
- package/dist/routes/graphql-yoga.js +5 -5
- package/dist/routes/health.d.ts +5 -1
- package/dist/types/index.d.ts +119 -1
- package/dist/utils/directive-parser.js +3 -7
- package/dist/utils/file-generator.d.ts +37 -0
- package/dist/utils/file-generator.js +72 -0
- package/dist/utils/index.d.ts +2 -3
- package/dist/utils/index.js +109 -60
- package/dist/utils/path-resolver.d.ts +70 -0
- package/dist/utils/path-resolver.js +127 -0
- package/dist/utils/type-generation.js +84 -34
- package/dist/virtual/debug-info.d.ts +9 -0
- package/dist/virtual/debug-info.js +26 -0
- package/dist/virtual/graphql-config.d.ts +9 -0
- package/dist/virtual/graphql-config.js +10 -0
- package/dist/virtual/module-config.d.ts +9 -0
- package/dist/virtual/module-config.js +10 -0
- package/dist/virtual/server-directives.d.ts +11 -0
- package/dist/virtual/server-directives.js +10 -0
- package/dist/virtual/server-resolvers.d.ts +11 -0
- package/dist/virtual/server-resolvers.js +10 -0
- package/dist/virtual/server-schemas.d.ts +11 -0
- package/dist/virtual/server-schemas.js +10 -0
- package/dist/vite.d.ts +25 -0
- package/dist/vite.js +40 -0
- package/package.json +54 -22
package/dist/types/index.d.ts
CHANGED
|
@@ -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
|
|
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.
|
|
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 };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -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(
|
|
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,
|
|
39
|
+
export { GLOB_SCAN_PATTERN, directiveParser, generateDirectiveSchema, generateDirectiveSchemas, generateLayerIgnorePatterns, getImportId, getLayerAppDirectories, getLayerDirectories, getLayerServerDirectories, relativeWithDot, scanDirectives, scanDocs, scanExternalServiceDocs, scanGraphql, scanResolvers, scanSchemas, validateExternalServices };
|
package/dist/utils/index.js
CHANGED
|
@@ -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(
|
|
32
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
type
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
type
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
type
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
type
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
type
|
|
90
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
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 };
|