nitro-graphql 2.0.0-beta.4 → 2.0.0-beta.41

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 (168) hide show
  1. package/README.md +438 -27
  2. package/dist/cli/commands/generate.d.mts +26 -0
  3. package/dist/cli/commands/generate.mjs +196 -0
  4. package/dist/cli/commands/index.d.mts +4 -0
  5. package/dist/cli/commands/index.mjs +5 -0
  6. package/dist/cli/commands/init.d.mts +46 -0
  7. package/dist/cli/commands/init.mjs +195 -0
  8. package/dist/cli/commands/validate.d.mts +10 -0
  9. package/dist/cli/commands/validate.mjs +69 -0
  10. package/dist/cli/completions.d.mts +7 -0
  11. package/dist/cli/completions.mjs +34 -0
  12. package/dist/cli/config.d.mts +75 -0
  13. package/dist/cli/config.mjs +20 -0
  14. package/dist/cli/index.d.mts +24 -0
  15. package/dist/cli/index.mjs +253 -0
  16. package/dist/config.d.mts +2 -0
  17. package/dist/config.mjs +3 -0
  18. package/dist/core/codegen/client.d.mts +23 -0
  19. package/dist/core/codegen/client.mjs +150 -0
  20. package/dist/core/codegen/document-loader.d.mts +10 -0
  21. package/dist/core/codegen/document-loader.mjs +18 -0
  22. package/dist/core/codegen/index.d.mts +8 -0
  23. package/dist/core/codegen/index.mjs +9 -0
  24. package/dist/core/codegen/plugin.d.mts +20 -0
  25. package/dist/core/codegen/plugin.mjs +30 -0
  26. package/dist/core/codegen/runtime.d.mts +20 -0
  27. package/dist/core/codegen/runtime.mjs +60 -0
  28. package/dist/core/codegen/schema-loader.d.mts +28 -0
  29. package/dist/core/codegen/schema-loader.mjs +128 -0
  30. package/dist/core/codegen/server.d.mts +28 -0
  31. package/dist/core/codegen/server.mjs +143 -0
  32. package/dist/core/codegen/validation.d.mts +13 -0
  33. package/dist/core/codegen/validation.mjs +96 -0
  34. package/dist/core/config.d.mts +50 -0
  35. package/dist/core/config.mjs +82 -0
  36. package/dist/core/constants.d.mts +188 -0
  37. package/dist/core/constants.mjs +210 -0
  38. package/dist/core/index.d.mts +33 -0
  39. package/dist/core/index.mjs +27 -0
  40. package/dist/core/manifest.d.mts +46 -0
  41. package/dist/core/manifest.mjs +76 -0
  42. package/dist/core/scanning/ast-scanner.d.mts +28 -0
  43. package/dist/core/scanning/ast-scanner.mjs +122 -0
  44. package/dist/core/scanning/common.d.mts +37 -0
  45. package/dist/core/scanning/common.mjs +60 -0
  46. package/dist/core/scanning/directives.d.mts +10 -0
  47. package/dist/core/scanning/directives.mjs +29 -0
  48. package/dist/core/scanning/documents.d.mts +21 -0
  49. package/dist/core/scanning/documents.mjs +43 -0
  50. package/dist/core/scanning/index.d.mts +7 -0
  51. package/dist/core/scanning/index.mjs +8 -0
  52. package/dist/core/scanning/resolvers.d.mts +15 -0
  53. package/dist/core/scanning/resolvers.mjs +59 -0
  54. package/dist/core/scanning/schemas.d.mts +14 -0
  55. package/dist/core/scanning/schemas.mjs +64 -0
  56. package/dist/core/schema/builder.d.mts +53 -0
  57. package/dist/core/schema/builder.mjs +70 -0
  58. package/dist/core/schema/federation.d.mts +34 -0
  59. package/dist/core/schema/federation.mjs +40 -0
  60. package/dist/core/schema/index.d.mts +3 -0
  61. package/dist/core/schema/index.mjs +4 -0
  62. package/dist/core/types/adapter.d.mts +58 -0
  63. package/dist/core/types/codegen.d.mts +133 -0
  64. package/dist/core/types/config.d.mts +210 -0
  65. package/dist/core/types/config.mjs +1 -0
  66. package/dist/{utils/define.d.ts → core/types/define.d.mts} +3 -30
  67. package/dist/core/types/define.mjs +1 -0
  68. package/dist/core/types/index.d.mts +5 -0
  69. package/dist/core/types/index.mjs +1 -0
  70. package/dist/core/types/scanning.d.mts +69 -0
  71. package/dist/core/types/scanning.mjs +1 -0
  72. package/dist/{utils/directive-parser.d.ts → core/utils/directive-parser.d.mts} +21 -4
  73. package/dist/{utils/directive-parser.js → core/utils/directive-parser.mjs} +25 -34
  74. package/dist/core/utils/errors.d.mts +77 -0
  75. package/dist/core/utils/errors.mjs +93 -0
  76. package/dist/core/utils/file-io.d.mts +24 -0
  77. package/dist/core/utils/file-io.mjs +47 -0
  78. package/dist/core/utils/imports.d.mts +15 -0
  79. package/dist/core/utils/imports.mjs +25 -0
  80. package/dist/core/utils/index.d.mts +7 -0
  81. package/dist/core/utils/index.mjs +8 -0
  82. package/dist/core/utils/logger.d.mts +19 -0
  83. package/dist/core/utils/logger.mjs +38 -0
  84. package/dist/core/utils/ofetch-templates.d.mts +30 -0
  85. package/dist/core/utils/ofetch-templates.mjs +135 -0
  86. package/dist/core/validation/external-services.d.mts +11 -0
  87. package/dist/core/validation/external-services.mjs +34 -0
  88. package/dist/core/validation/index.d.mts +2 -0
  89. package/dist/core/validation/index.mjs +3 -0
  90. package/dist/define.d.mts +294 -0
  91. package/dist/define.mjs +323 -0
  92. package/dist/index.d.mts +6 -0
  93. package/dist/index.mjs +6 -0
  94. package/dist/nitro/adapter.d.mts +30 -0
  95. package/dist/nitro/adapter.mjs +97 -0
  96. package/dist/{utils/apollo.d.ts → nitro/apollo.d.mts} +3 -3
  97. package/dist/nitro/apollo.mjs +59 -0
  98. package/dist/nitro/codegen.d.mts +19 -0
  99. package/dist/nitro/codegen.mjs +141 -0
  100. package/dist/nitro/config.d.mts +51 -0
  101. package/dist/nitro/config.mjs +57 -0
  102. package/dist/nitro/index.d.mts +46 -0
  103. package/dist/nitro/index.mjs +65 -0
  104. package/dist/nitro/paths.d.mts +54 -0
  105. package/dist/nitro/paths.mjs +92 -0
  106. package/dist/nitro/rollup.d.mts +6 -0
  107. package/dist/nitro/rollup.mjs +95 -0
  108. package/dist/nitro/routes/apollo-server.d.mts +6 -0
  109. package/dist/nitro/routes/apollo-server.mjs +71 -0
  110. package/dist/nitro/routes/debug-template.d.mts +15 -0
  111. package/dist/nitro/routes/debug-template.mjs +385 -0
  112. package/dist/nitro/routes/debug.d.mts +55 -0
  113. package/dist/nitro/routes/debug.mjs +102 -0
  114. package/dist/nitro/routes/graphql-yoga.d.mts +6 -0
  115. package/dist/nitro/routes/graphql-yoga.mjs +62 -0
  116. package/dist/nitro/routes/health.d.mts +10 -0
  117. package/dist/{routes/health.js → nitro/routes/health.mjs} +4 -3
  118. package/dist/nitro/setup/extend-loader.d.mts +19 -0
  119. package/dist/nitro/setup/extend-loader.mjs +129 -0
  120. package/dist/nitro/setup/file-watcher.d.mts +16 -0
  121. package/dist/nitro/setup/file-watcher.mjs +98 -0
  122. package/dist/nitro/setup/logging.d.mts +17 -0
  123. package/dist/nitro/setup/logging.mjs +66 -0
  124. package/dist/nitro/setup/rollup-integration.d.mts +16 -0
  125. package/dist/nitro/setup/rollup-integration.mjs +90 -0
  126. package/dist/nitro/setup/routes.d.mts +10 -0
  127. package/dist/nitro/setup/routes.mjs +35 -0
  128. package/dist/nitro/setup/ts-config.d.mts +11 -0
  129. package/dist/nitro/setup/ts-config.mjs +69 -0
  130. package/dist/nitro/setup.d.mts +12 -0
  131. package/dist/nitro/setup.mjs +234 -0
  132. package/dist/nitro/types.d.mts +374 -0
  133. package/dist/nitro/types.mjs +1 -0
  134. package/dist/nitro/virtual/generators.d.mts +31 -0
  135. package/dist/nitro/virtual/generators.mjs +113 -0
  136. package/dist/nitro/virtual/stubs.d.mts +20 -0
  137. package/dist/nitro/virtual/stubs.mjs +31 -0
  138. package/dist/{ecosystem/nuxt.d.ts → nuxt.d.mts} +1 -1
  139. package/dist/nuxt.mjs +109 -0
  140. package/dist/{graphql/server.d.ts → stubs/index.d.mts} +5 -1
  141. package/dist/stubs/index.mjs +1 -0
  142. package/package.json +102 -77
  143. package/dist/ecosystem/nuxt.js +0 -67
  144. package/dist/graphql/index.d.ts +0 -5
  145. package/dist/index.d.ts +0 -8
  146. package/dist/index.js +0 -264
  147. package/dist/rollup.js +0 -119
  148. package/dist/routes/apollo-server.d.ts +0 -6
  149. package/dist/routes/apollo-server.js +0 -89
  150. package/dist/routes/graphql-yoga.d.ts +0 -6
  151. package/dist/routes/graphql-yoga.js +0 -91
  152. package/dist/routes/health.d.ts +0 -6
  153. package/dist/types/index.d.ts +0 -128
  154. package/dist/types/standard-schema.d.ts +0 -59
  155. package/dist/utils/apollo.js +0 -61
  156. package/dist/utils/client-codegen.d.ts +0 -38
  157. package/dist/utils/client-codegen.js +0 -290
  158. package/dist/utils/define.js +0 -57
  159. package/dist/utils/index.d.ts +0 -39
  160. package/dist/utils/index.js +0 -250
  161. package/dist/utils/server-codegen.d.ts +0 -7
  162. package/dist/utils/server-codegen.js +0 -136
  163. package/dist/utils/type-generation.d.ts +0 -7
  164. package/dist/utils/type-generation.js +0 -287
  165. package/dist/vite.d.ts +0 -25
  166. package/dist/vite.js +0 -40
  167. /package/dist/{graphql/index.js → core/types/adapter.mjs} +0 -0
  168. /package/dist/{graphql/server.js → core/types/codegen.mjs} +0 -0
@@ -1,4 +1,4 @@
1
- //#region src/utils/directive-parser.ts
1
+ //#region src/core/utils/directive-parser.ts
2
2
  /**
3
3
  * Clean AST-based directive parser using oxc-parser
4
4
  */
@@ -180,45 +180,36 @@ function generateDirectiveSchema(directive) {
180
180
  return `directive @${directive.name}${args} on ${locations}`;
181
181
  }
182
182
  /**
183
- * Generate directive schemas file from scanned directives
183
+ * Get the file path from a directive reference
184
184
  */
185
- async function generateDirectiveSchemas(nitro, directives) {
186
- if (directives.length === 0) return;
187
- const { existsSync, readFileSync, writeFileSync, mkdirSync } = await import("node:fs");
188
- const { readFile } = await import("node:fs/promises");
189
- const { resolve, dirname } = await import("pathe");
190
- const directiveSchemas = [];
191
- const seenDirectives = /* @__PURE__ */ new Set();
192
- const parser = new DirectiveParser();
193
- for (const dir of directives) for (const _imp of dir.imports) {
194
- const fileContent = await readFile(dir.specifier, "utf-8");
195
- const directiveDefs = await parser.parseDirectives(fileContent, dir.specifier);
196
- for (const def of directiveDefs) {
197
- if (seenDirectives.has(def.name)) continue;
198
- seenDirectives.add(def.name);
199
- const schema = generateDirectiveSchema(def);
200
- directiveSchemas.push(schema);
201
- }
202
- }
203
- if (directiveSchemas.length > 0) {
204
- const directivesPath = resolve(nitro.graphql.buildDir, "_directives.graphql");
205
- const content = `# WARNING: This file is auto-generated by nitro-graphql
206
- # Do not modify this file directly. It will be overwritten.
207
- # To define custom directives, create .directive.ts files using defineDirective()
208
-
209
- ${directiveSchemas.join("\n\n")}`;
210
- const targetDir = dirname(directivesPath);
211
- if (!existsSync(targetDir)) mkdirSync(targetDir, { recursive: true });
212
- let shouldWrite = true;
213
- if (existsSync(directivesPath)) shouldWrite = readFileSync(directivesPath, "utf-8") !== content;
214
- if (shouldWrite) writeFileSync(directivesPath, content, "utf-8");
215
- if (!nitro.scanSchemas.includes(directivesPath)) nitro.scanSchemas.push(directivesPath);
216
- }
185
+ function getFilePath(ref) {
186
+ return "fullPath" in ref ? ref.fullPath : ref.specifier;
217
187
  }
218
188
  /**
219
189
  * Singleton instance for reuse
220
190
  */
221
191
  const directiveParser = new DirectiveParser();
192
+ /**
193
+ * Generate GraphQL schemas from an array of parsed directives
194
+ */
195
+ async function generateDirectiveSchemas(nitro, directives) {
196
+ if (directives.length === 0) return null;
197
+ const fs = await import("node:fs");
198
+ const path = await import("pathe");
199
+ const allParsedDirectives = [];
200
+ for (const directive of directives) try {
201
+ const filePath = getFilePath(directive);
202
+ const content = fs.readFileSync(filePath, "utf-8");
203
+ const parsed = await directiveParser.parseDirectives(content, filePath);
204
+ allParsedDirectives.push(...parsed);
205
+ } catch {}
206
+ if (allParsedDirectives.length === 0) return null;
207
+ const schemaContent = allParsedDirectives.map((d) => generateDirectiveSchema(d)).join("\n\n");
208
+ const directivesPath = path.join(nitro.graphql.buildDir, "_directives.graphql");
209
+ fs.mkdirSync(path.dirname(directivesPath), { recursive: true });
210
+ fs.writeFileSync(directivesPath, schemaContent, "utf-8");
211
+ return directivesPath;
212
+ }
222
213
 
223
214
  //#endregion
224
215
  export { DirectiveParser, directiveParser, generateDirectiveSchema, generateDirectiveSchemas };
@@ -0,0 +1,77 @@
1
+ //#region src/core/utils/errors.d.ts
2
+ /**
3
+ * Error handling utilities for GraphQL
4
+ * Framework-agnostic error masking and handling
5
+ */
6
+ interface MaskErrorOptions {
7
+ /**
8
+ * Default HTTP status code for validation errors (ZodError)
9
+ * @default 400
10
+ */
11
+ validationStatusCode?: number;
12
+ /**
13
+ * Default HTTP status code for HTTP errors when status is not provided
14
+ * @default 500
15
+ */
16
+ defaultHttpStatusCode?: number;
17
+ }
18
+ /**
19
+ * Default error masking function for GraphQL Yoga
20
+ * Handles common error types like ZodError and HTTPError
21
+ *
22
+ * @param options - Configuration options for error handling
23
+ *
24
+ * @example Basic usage
25
+ * ```ts
26
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
27
+ * import { createDefaultMaskError } from 'nitro-graphql/core'
28
+ *
29
+ * export default defineGraphQLConfig({
30
+ * maskedErrors: {
31
+ * maskError: createDefaultMaskError()
32
+ * }
33
+ * })
34
+ * ```
35
+ *
36
+ * @example Custom status codes
37
+ * ```ts
38
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
39
+ * import { createDefaultMaskError } from 'nitro-graphql/core'
40
+ *
41
+ * export default defineGraphQLConfig({
42
+ * maskedErrors: {
43
+ * maskError: createDefaultMaskError({
44
+ * validationStatusCode: 422, // Use 422 for validation errors
45
+ * defaultHttpStatusCode: 500 // Use 500 for unknown HTTP errors
46
+ * })
47
+ * }
48
+ * })
49
+ * ```
50
+ *
51
+ * @example Custom error handling with fallback to default
52
+ * ```ts
53
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
54
+ * import { createDefaultMaskError } from 'nitro-graphql/core'
55
+ *
56
+ * const defaultMaskError = createDefaultMaskError()
57
+ *
58
+ * export default defineGraphQLConfig({
59
+ * maskedErrors: {
60
+ * maskError: (error: unknown) => {
61
+ * // Handle custom errors first
62
+ * if (error instanceof MyCustomError) {
63
+ * return new GraphQLError(error.message, {
64
+ * extensions: { code: 'CUSTOM_ERROR' }
65
+ * })
66
+ * }
67
+ *
68
+ * // Fall back to default handling
69
+ * return defaultMaskError(error)
70
+ * }
71
+ * }
72
+ * })
73
+ * ```
74
+ */
75
+ declare function createDefaultMaskError(options?: MaskErrorOptions): (error: unknown) => Error;
76
+ //#endregion
77
+ export { MaskErrorOptions, createDefaultMaskError };
@@ -0,0 +1,93 @@
1
+ import { GraphQLError } from "graphql";
2
+
3
+ //#region src/core/utils/errors.ts
4
+ /**
5
+ * Error handling utilities for GraphQL
6
+ * Framework-agnostic error masking and handling
7
+ */
8
+ /**
9
+ * Default error masking function for GraphQL Yoga
10
+ * Handles common error types like ZodError and HTTPError
11
+ *
12
+ * @param options - Configuration options for error handling
13
+ *
14
+ * @example Basic usage
15
+ * ```ts
16
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
17
+ * import { createDefaultMaskError } from 'nitro-graphql/core'
18
+ *
19
+ * export default defineGraphQLConfig({
20
+ * maskedErrors: {
21
+ * maskError: createDefaultMaskError()
22
+ * }
23
+ * })
24
+ * ```
25
+ *
26
+ * @example Custom status codes
27
+ * ```ts
28
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
29
+ * import { createDefaultMaskError } from 'nitro-graphql/core'
30
+ *
31
+ * export default defineGraphQLConfig({
32
+ * maskedErrors: {
33
+ * maskError: createDefaultMaskError({
34
+ * validationStatusCode: 422, // Use 422 for validation errors
35
+ * defaultHttpStatusCode: 500 // Use 500 for unknown HTTP errors
36
+ * })
37
+ * }
38
+ * })
39
+ * ```
40
+ *
41
+ * @example Custom error handling with fallback to default
42
+ * ```ts
43
+ * import { defineGraphQLConfig } from 'nitro-graphql/define'
44
+ * import { createDefaultMaskError } from 'nitro-graphql/core'
45
+ *
46
+ * const defaultMaskError = createDefaultMaskError()
47
+ *
48
+ * export default defineGraphQLConfig({
49
+ * maskedErrors: {
50
+ * maskError: (error: unknown) => {
51
+ * // Handle custom errors first
52
+ * if (error instanceof MyCustomError) {
53
+ * return new GraphQLError(error.message, {
54
+ * extensions: { code: 'CUSTOM_ERROR' }
55
+ * })
56
+ * }
57
+ *
58
+ * // Fall back to default handling
59
+ * return defaultMaskError(error)
60
+ * }
61
+ * }
62
+ * })
63
+ * ```
64
+ */
65
+ function createDefaultMaskError(options) {
66
+ const validationStatusCode = options?.validationStatusCode ?? 400;
67
+ const defaultHttpStatusCode = options?.defaultHttpStatusCode ?? 500;
68
+ return (error) => {
69
+ if (error && typeof error === "object" && "originalError" in error) {
70
+ const graphqlError = error;
71
+ if (graphqlError.originalError && typeof graphqlError.originalError === "object" && "issues" in graphqlError.originalError && Array.isArray(graphqlError.originalError.issues)) return new GraphQLError("Validation failed", { extensions: {
72
+ code: "BAD_USER_INPUT",
73
+ validationErrors: graphqlError.originalError.issues.map((issue) => ({
74
+ field: issue.path.join("."),
75
+ message: issue.message
76
+ })),
77
+ http: { status: validationStatusCode }
78
+ } });
79
+ if (graphqlError.originalError && typeof graphqlError.originalError === "object" && "statusCode" in graphqlError.originalError && "statusMessage" in graphqlError.originalError) {
80
+ const httpError = graphqlError.originalError;
81
+ const statusCode = httpError.statusCode ?? defaultHttpStatusCode;
82
+ return new GraphQLError(httpError.statusMessage || httpError.message || "Internal Server Error", { extensions: {
83
+ code: statusCode,
84
+ http: { status: statusCode }
85
+ } });
86
+ }
87
+ }
88
+ return error instanceof Error ? error : new Error(String(error));
89
+ };
90
+ }
91
+
92
+ //#endregion
93
+ export { createDefaultMaskError };
@@ -0,0 +1,24 @@
1
+ //#region src/core/utils/file-io.d.ts
2
+ /**
3
+ * Unified file I/O utilities
4
+ * Centralizes file writing patterns used across the codebase
5
+ */
6
+ /**
7
+ * Write file with automatic directory creation
8
+ */
9
+ declare function writeFile(path: string, content: string): void;
10
+ /**
11
+ * Write file only if content changed (for dev mode optimization)
12
+ * Returns true if file was written, false if unchanged
13
+ */
14
+ declare function writeFileIfChanged(path: string, content: string): boolean;
15
+ /**
16
+ * Ensure directory exists
17
+ */
18
+ declare function ensureDir(path: string): void;
19
+ /**
20
+ * Read file safely, returns undefined if file doesn't exist
21
+ */
22
+ declare function readFileSafe(path: string): string | undefined;
23
+ //#endregion
24
+ export { ensureDir, readFileSafe, writeFile, writeFileIfChanged };
@@ -0,0 +1,47 @@
1
+ import { dirname } from "pathe";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+
4
+ //#region src/core/utils/file-io.ts
5
+ /**
6
+ * Unified file I/O utilities
7
+ * Centralizes file writing patterns used across the codebase
8
+ */
9
+ /**
10
+ * Write file with automatic directory creation
11
+ */
12
+ function writeFile(path, content) {
13
+ mkdirSync(dirname(path), { recursive: true });
14
+ writeFileSync(path, content, "utf-8");
15
+ }
16
+ /**
17
+ * Write file only if content changed (for dev mode optimization)
18
+ * Returns true if file was written, false if unchanged
19
+ */
20
+ function writeFileIfChanged(path, content) {
21
+ try {
22
+ if (existsSync(path)) {
23
+ if (readFileSync(path, "utf-8") === content) return false;
24
+ }
25
+ } catch {}
26
+ writeFile(path, content);
27
+ return true;
28
+ }
29
+ /**
30
+ * Ensure directory exists
31
+ */
32
+ function ensureDir(path) {
33
+ mkdirSync(path, { recursive: true });
34
+ }
35
+ /**
36
+ * Read file safely, returns undefined if file doesn't exist
37
+ */
38
+ function readFileSafe(path) {
39
+ try {
40
+ return readFileSync(path, "utf-8");
41
+ } catch {
42
+ return;
43
+ }
44
+ }
45
+
46
+ //#endregion
47
+ export { ensureDir, readFileSafe, writeFile, writeFileIfChanged };
@@ -0,0 +1,15 @@
1
+ //#region src/core/utils/imports.d.ts
2
+ /**
3
+ * Import utilities
4
+ * Helpers for generating import IDs and relative paths
5
+ */
6
+ /**
7
+ * Generate a unique import ID for a file path
8
+ */
9
+ declare function getImportId(p: string, lazy?: boolean): string;
10
+ /**
11
+ * Get relative path with a leading dot for module resolution
12
+ */
13
+ declare function relativeWithDot(from: string, to: string): string;
14
+ //#endregion
15
+ export { getImportId, relativeWithDot };
@@ -0,0 +1,25 @@
1
+ import { relative } from "pathe";
2
+ import { hash } from "ohash";
3
+
4
+ //#region src/core/utils/imports.ts
5
+ /**
6
+ * Import utilities
7
+ * Helpers for generating import IDs and relative paths
8
+ */
9
+ /**
10
+ * Generate a unique import ID for a file path
11
+ */
12
+ function getImportId(p, lazy) {
13
+ return (lazy ? "_lazy_" : "_") + hash(p).replace(/-/g, "").slice(0, 6);
14
+ }
15
+ const RELATIVE_RE = /^\.{1,2}\//;
16
+ /**
17
+ * Get relative path with a leading dot for module resolution
18
+ */
19
+ function relativeWithDot(from, to) {
20
+ const rel = relative(from, to);
21
+ return RELATIVE_RE.test(rel) ? rel : `./${rel}`;
22
+ }
23
+
24
+ //#endregion
25
+ export { getImportId, relativeWithDot };
@@ -0,0 +1,7 @@
1
+ import { DirectiveFileRef, DirectiveParser, ParsedDirective, directiveParser, generateDirectiveSchema, generateDirectiveSchemas } from "./directive-parser.mjs";
2
+ import { MaskErrorOptions, createDefaultMaskError } from "./errors.mjs";
3
+ import { ensureDir, readFileSafe, writeFile, writeFileIfChanged } from "./file-io.mjs";
4
+ import { getImportId, relativeWithDot } from "./imports.mjs";
5
+ import { createLogger, createSilentLogger, defaultLogger } from "./logger.mjs";
6
+ import { OfetchTemplateOptions, generateOfetchTemplate } from "./ofetch-templates.mjs";
7
+ export { DirectiveFileRef, DirectiveParser, MaskErrorOptions, OfetchTemplateOptions, ParsedDirective, createDefaultMaskError, createLogger, createSilentLogger, defaultLogger, directiveParser, ensureDir, generateDirectiveSchema, generateDirectiveSchemas, generateOfetchTemplate, getImportId, readFileSafe, relativeWithDot, writeFile, writeFileIfChanged };
@@ -0,0 +1,8 @@
1
+ import { ensureDir, readFileSafe, writeFile, writeFileIfChanged } from "./file-io.mjs";
2
+ import { createLogger, createSilentLogger, defaultLogger } from "./logger.mjs";
3
+ import { DirectiveParser, directiveParser, generateDirectiveSchema, generateDirectiveSchemas } from "./directive-parser.mjs";
4
+ import { createDefaultMaskError } from "./errors.mjs";
5
+ import { getImportId, relativeWithDot } from "./imports.mjs";
6
+ import { generateOfetchTemplate } from "./ofetch-templates.mjs";
7
+
8
+ export { DirectiveParser, createDefaultMaskError, createLogger, createSilentLogger, defaultLogger, directiveParser, ensureDir, generateDirectiveSchema, generateDirectiveSchemas, generateOfetchTemplate, getImportId, readFileSafe, relativeWithDot, writeFile, writeFileIfChanged };
@@ -0,0 +1,19 @@
1
+ import { CoreLogger } from "../types/config.mjs";
2
+
3
+ //#region src/core/utils/logger.d.ts
4
+
5
+ /**
6
+ * Create a logger instance with the nitro-graphql tag
7
+ */
8
+ declare function createLogger(tag?: string): CoreLogger;
9
+ /**
10
+ * Default logger instance
11
+ */
12
+ declare const defaultLogger: CoreLogger;
13
+ /**
14
+ * Create a silent logger (no output)
15
+ * Useful for testing or when logging should be suppressed
16
+ */
17
+ declare function createSilentLogger(): CoreLogger;
18
+ //#endregion
19
+ export { createLogger, createSilentLogger, defaultLogger };
@@ -0,0 +1,38 @@
1
+ import { LOG_TAG } from "../constants.mjs";
2
+ import { consola as consola$1 } from "consola";
3
+
4
+ //#region src/core/utils/logger.ts
5
+ /**
6
+ * Create a logger instance with the nitro-graphql tag
7
+ */
8
+ function createLogger(tag = LOG_TAG) {
9
+ const logger = consola$1.withTag(tag);
10
+ return {
11
+ info: (message, ...args) => logger.info(message, ...args),
12
+ warn: (message, ...args) => logger.warn(message, ...args),
13
+ error: (message, ...args) => logger.error(message, ...args),
14
+ success: (message, ...args) => logger.success(message, ...args),
15
+ debug: (message, ...args) => logger.debug(message, ...args)
16
+ };
17
+ }
18
+ /**
19
+ * Default logger instance
20
+ */
21
+ const defaultLogger = createLogger();
22
+ /**
23
+ * Create a silent logger (no output)
24
+ * Useful for testing or when logging should be suppressed
25
+ */
26
+ function createSilentLogger() {
27
+ const noop = () => {};
28
+ return {
29
+ info: noop,
30
+ warn: noop,
31
+ error: noop,
32
+ success: noop,
33
+ debug: noop
34
+ };
35
+ }
36
+
37
+ //#endregion
38
+ export { createLogger, createSilentLogger, defaultLogger };
@@ -0,0 +1,30 @@
1
+ //#region src/core/utils/ofetch-templates.d.ts
2
+ /**
3
+ * Shared ofetch template generation utilities
4
+ * Used by both main client and external service code generation
5
+ */
6
+ interface OfetchTemplateOptions {
7
+ /** Service name (e.g., 'default', 'github') */
8
+ serviceName: string;
9
+ /** Whether to use Nuxt composables ($fetch, useRequestHeaders) */
10
+ isNuxt: boolean;
11
+ /** Endpoint URL for the GraphQL service */
12
+ endpoint: string;
13
+ /** Whether this is an external service (affects naming convention) */
14
+ isExternal?: boolean;
15
+ }
16
+ /**
17
+ * Generate ofetch client template content
18
+ *
19
+ * For main (default) service:
20
+ * - SDK exported as `$sdk`
21
+ * - Client function is `createGraphQLClient`
22
+ *
23
+ * For external services:
24
+ * - SDK exported as `$${serviceName}Sdk`
25
+ * - Client function is `create${ServiceName}GraphQLClient`
26
+ * - Endpoint has default value
27
+ */
28
+ declare function generateOfetchTemplate(options: OfetchTemplateOptions): string;
29
+ //#endregion
30
+ export { OfetchTemplateOptions, generateOfetchTemplate };
@@ -0,0 +1,135 @@
1
+ //#region src/core/utils/ofetch-templates.ts
2
+ /**
3
+ * Capitalize first letter of a string
4
+ */
5
+ function capitalize(str) {
6
+ return str.charAt(0).toUpperCase() + str.slice(1);
7
+ }
8
+ /**
9
+ * Generate ofetch client template content
10
+ *
11
+ * For main (default) service:
12
+ * - SDK exported as `$sdk`
13
+ * - Client function is `createGraphQLClient`
14
+ *
15
+ * For external services:
16
+ * - SDK exported as `$${serviceName}Sdk`
17
+ * - Client function is `create${ServiceName}GraphQLClient`
18
+ * - Endpoint has default value
19
+ */
20
+ function generateOfetchTemplate(options) {
21
+ const { serviceName, isNuxt, endpoint, isExternal = false } = options;
22
+ if (isExternal) return generateExternalOfetchTemplate({
23
+ serviceName,
24
+ isNuxt,
25
+ endpoint
26
+ });
27
+ return generateMainOfetchTemplate({
28
+ isNuxt,
29
+ endpoint
30
+ });
31
+ }
32
+ /**
33
+ * Generate ofetch template for main (default) GraphQL service
34
+ */
35
+ function generateMainOfetchTemplate(options) {
36
+ const { isNuxt, endpoint } = options;
37
+ if (isNuxt) return `// This file is auto-generated once by nitro-graphql for quick start
38
+ // You can modify this file according to your needs
39
+ import type { Requester } from './sdk'
40
+ import { getSdk } from './sdk'
41
+
42
+ export function createGraphQLClient(endpoint: string): Requester {
43
+ return async <R>(doc: string, vars?: any): Promise<R> => {
44
+ const headers = import.meta.server ? useRequestHeaders() : undefined
45
+
46
+ const result = await $fetch(endpoint, {
47
+ method: 'POST',
48
+ body: { query: doc, variables: vars },
49
+ headers: {
50
+ 'Content-Type': 'application/json',
51
+ ...headers,
52
+ },
53
+ })
54
+
55
+ return result as R
56
+ }
57
+ }
58
+
59
+ export const $sdk = getSdk(createGraphQLClient('${endpoint}'))`;
60
+ return `// This file is auto-generated once by nitro-graphql for quick start
61
+ // You can modify this file according to your needs
62
+ import type { Requester } from './sdk'
63
+ import { ofetch } from 'ofetch'
64
+ import { getSdk } from './sdk'
65
+
66
+ export function createGraphQLClient(endpoint: string): Requester {
67
+ return async <R>(doc: string, vars?: any): Promise<R> => {
68
+ const result = await ofetch(endpoint, {
69
+ method: 'POST',
70
+ body: { query: doc, variables: vars },
71
+ headers: {
72
+ 'Content-Type': 'application/json',
73
+ },
74
+ })
75
+
76
+ return result as R
77
+ }
78
+ }
79
+
80
+ export const $sdk = getSdk(createGraphQLClient('${endpoint}'))`;
81
+ }
82
+ /**
83
+ * Generate ofetch template for external GraphQL service
84
+ */
85
+ function generateExternalOfetchTemplate(options) {
86
+ const { serviceName, isNuxt, endpoint } = options;
87
+ const capitalizedName = capitalize(serviceName);
88
+ if (isNuxt) return `// This file is auto-generated once by nitro-graphql for quick start
89
+ // You can modify this file according to your needs
90
+ import type { Sdk, Requester } from './sdk'
91
+ import { getSdk } from './sdk'
92
+
93
+ export function create${capitalizedName}GraphQLClient(endpoint: string = '${endpoint}'): Requester {
94
+ return async <R>(doc: string, vars?: any): Promise<R> => {
95
+ const headers = import.meta.server ? useRequestHeaders() : undefined
96
+
97
+ const result = await $fetch(endpoint, {
98
+ method: 'POST',
99
+ body: { query: doc, variables: vars },
100
+ headers: {
101
+ 'Content-Type': 'application/json',
102
+ ...headers,
103
+ },
104
+ })
105
+
106
+ return result as R
107
+ }
108
+ }
109
+
110
+ export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedName}GraphQLClient())`;
111
+ return `// This file is auto-generated once by nitro-graphql for quick start
112
+ // You can modify this file according to your needs
113
+ import type { Sdk, Requester } from './sdk'
114
+ import { ofetch } from 'ofetch'
115
+ import { getSdk } from './sdk'
116
+
117
+ export function create${capitalizedName}GraphQLClient(endpoint: string = '${endpoint}'): Requester {
118
+ return async <R>(doc: string, vars?: any): Promise<R> => {
119
+ const result = await ofetch(endpoint, {
120
+ method: 'POST',
121
+ body: { query: doc, variables: vars },
122
+ headers: {
123
+ 'Content-Type': 'application/json',
124
+ },
125
+ })
126
+
127
+ return result as R
128
+ }
129
+ }
130
+
131
+ export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedName}GraphQLClient())`;
132
+ }
133
+
134
+ //#endregion
135
+ export { generateOfetchTemplate };
@@ -0,0 +1,11 @@
1
+ //#region src/core/validation/external-services.d.ts
2
+ /**
3
+ * External services validation utilities
4
+ * Framework-agnostic validation helpers
5
+ */
6
+ /**
7
+ * Validate external GraphQL service configuration
8
+ */
9
+ declare function validateExternalServices(services: unknown[]): string[];
10
+ //#endregion
11
+ export { validateExternalServices };
@@ -0,0 +1,34 @@
1
+ //#region src/core/validation/external-services.ts
2
+ /**
3
+ * External services validation utilities
4
+ * Framework-agnostic validation helpers
5
+ */
6
+ /**
7
+ * Validate external GraphQL service configuration
8
+ */
9
+ function validateExternalServices(services) {
10
+ const errors = [];
11
+ const serviceNames = /* @__PURE__ */ new Set();
12
+ for (const [index, service] of services.entries()) {
13
+ const prefix = `externalServices[${index}]`;
14
+ if (!service || typeof service !== "object") {
15
+ errors.push(`${prefix} must be an object`);
16
+ continue;
17
+ }
18
+ if (!("name" in service) || typeof service.name !== "string") errors.push(`${prefix}.name is required and must be a string`);
19
+ else if (serviceNames.has(service.name)) errors.push(`${prefix}.name "${service.name}" must be unique`);
20
+ else serviceNames.add(service.name);
21
+ if (!("schema" in service) || !service.schema) errors.push(`${prefix}.schema is required`);
22
+ if (!("endpoint" in service) || typeof service.endpoint !== "string") errors.push(`${prefix}.endpoint is required and must be a string`);
23
+ else try {
24
+ new URL(service.endpoint);
25
+ } catch {
26
+ errors.push(`${prefix}.endpoint "${service.endpoint}" must be a valid URL`);
27
+ }
28
+ if ("name" in service && service.name && typeof service.name === "string" && !/^[a-z]\w*$/i.test(service.name)) errors.push(`${prefix}.name "${service.name}" must be a valid identifier (letters, numbers, underscore, starting with letter)`);
29
+ }
30
+ return errors;
31
+ }
32
+
33
+ //#endregion
34
+ export { validateExternalServices };
@@ -0,0 +1,2 @@
1
+ import { validateExternalServices } from "./external-services.mjs";
2
+ export { validateExternalServices };
@@ -0,0 +1,3 @@
1
+ import { validateExternalServices } from "./external-services.mjs";
2
+
3
+ export { validateExternalServices };