nitro-graphql 1.1.2 → 1.2.0

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.
@@ -1,4 +1,4 @@
1
- import { generateClientTypes, loadGraphQLDocuments } from "./client-codegen.js";
1
+ import { downloadAndSaveSchema, generateClientTypes, generateExternalClientTypes, loadExternalSchema, loadGraphQLDocuments } from "./client-codegen.js";
2
2
  import { generateTypes } from "./server-codegen.js";
3
3
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
4
  import consola from "consola";
@@ -9,8 +9,27 @@ import { mergeTypeDefs } from "@graphql-tools/merge";
9
9
  import { printSchemaWithDirectives } from "@graphql-tools/utils";
10
10
 
11
11
  //#region src/utils/type-generation.ts
12
- function generateNuxtOfetchClient(clientDir) {
13
- const ofetchPath = resolve(clientDir, "ofetch.ts");
12
+ function generateGraphQLIndexFile(clientDir, externalServices = []) {
13
+ const indexPath = resolve(clientDir, "index.ts");
14
+ if (!existsSync(indexPath)) {
15
+ let indexContent = `// This file is auto-generated once by nitro-graphql for quick start
16
+ // You can modify this file according to your needs
17
+ //
18
+ // Export your main GraphQL service (auto-generated)
19
+ export * from './default/ofetch'
20
+
21
+ // Export external GraphQL services (auto-generated for existing services)
22
+ // When you add new external services, don't forget to add their exports here:
23
+ // export * from './yourServiceName/ofetch'
24
+ `;
25
+ for (const service of externalServices) indexContent += `export * from './${service.name}/ofetch'\n`;
26
+ writeFileSync(indexPath, indexContent, "utf-8");
27
+ }
28
+ }
29
+ function generateNuxtOfetchClient(clientDir, serviceName = "default") {
30
+ const serviceDir = resolve(clientDir, serviceName);
31
+ const ofetchPath = resolve(serviceDir, "ofetch.ts");
32
+ if (!existsSync(serviceDir)) mkdirSync(serviceDir, { recursive: true });
14
33
  if (!existsSync(ofetchPath)) {
15
34
  const ofetchContent = `// This file is auto-generated once by nitro-graphql for quick start
16
35
  // You can modify this file according to your needs
@@ -38,6 +57,38 @@ export const $sdk = getSdk(createGraphQLClient('/api/graphql'))`;
38
57
  writeFileSync(ofetchPath, ofetchContent, "utf-8");
39
58
  }
40
59
  }
60
+ function generateExternalOfetchClient(clientDir, serviceName, endpoint) {
61
+ const serviceDir = resolve(clientDir, serviceName);
62
+ const ofetchPath = resolve(serviceDir, "ofetch.ts");
63
+ if (!existsSync(serviceDir)) mkdirSync(serviceDir, { recursive: true });
64
+ if (!existsSync(ofetchPath)) {
65
+ const capitalizedServiceName = serviceName.charAt(0).toUpperCase() + serviceName.slice(1);
66
+ const ofetchContent = `// This file is auto-generated once by nitro-graphql for quick start
67
+ // You can modify this file according to your needs
68
+ import type { Sdk, Requester } from './sdk'
69
+ import { getSdk } from './sdk'
70
+
71
+ export function create${capitalizedServiceName}GraphQLClient(endpoint: string = '${endpoint}'): Requester {
72
+ return async <R>(doc: string, vars?: any): Promise<R> => {
73
+ const headers = import.meta.server ? useRequestHeaders() : undefined
74
+
75
+ const result = await $fetch(endpoint, {
76
+ method: 'POST',
77
+ body: { query: doc, variables: vars },
78
+ headers: {
79
+ 'Content-Type': 'application/json',
80
+ ...headers,
81
+ },
82
+ })
83
+
84
+ return result as R
85
+ }
86
+ }
87
+
88
+ export const $${serviceName}Sdk: Sdk = getSdk(create${capitalizedServiceName}GraphQLClient())`;
89
+ writeFileSync(ofetchPath, ofetchContent, "utf-8");
90
+ }
91
+ }
41
92
  async function serverTypeGeneration(app) {
42
93
  try {
43
94
  const schemas = app.scanSchemas || [];
@@ -65,28 +116,101 @@ async function serverTypeGeneration(app) {
65
116
  }
66
117
  async function clientTypeGeneration(nitro) {
67
118
  try {
68
- const docs = nitro.scanDocuments;
69
- const loadDocs = await loadGraphQLDocuments(docs);
70
- const schemaFilePath = join(nitro.graphql.buildDir, "schema.graphql");
71
- if (!existsSync(schemaFilePath)) {
72
- consola.info("Schema file not ready yet for client type generation. Server types need to be generated first.");
73
- return;
74
- }
75
- const graphqlString = readFileSync(schemaFilePath, "utf-8");
76
- const schema = buildSchema(graphqlString);
77
- const types = await generateClientTypes(schema, loadDocs, nitro.options.graphql?.codegen?.client ?? {}, nitro.options.graphql?.codegen?.clientSDK ?? {});
78
- if (types === false) return;
79
- const clientTypesPath = resolve(nitro.options.buildDir, "types", "nitro-graphql-client.d.ts");
80
- const sdkTypesPath = resolve(nitro.graphql.clientDir, "sdk.ts");
81
- mkdirSync(dirname(clientTypesPath), { recursive: true });
82
- writeFileSync(clientTypesPath, types.types, "utf-8");
83
- mkdirSync(dirname(sdkTypesPath), { recursive: true });
84
- writeFileSync(sdkTypesPath, types.sdk, "utf-8");
85
- if (nitro.options.framework?.name === "nuxt") generateNuxtOfetchClient(nitro.graphql.clientDir);
119
+ await generateMainClientTypes(nitro);
120
+ if (nitro.options.graphql?.externalServices?.length) await generateExternalServicesTypes(nitro);
86
121
  } catch (error) {
87
122
  consola.error("Client schema generation error:", error);
88
123
  }
89
124
  }
125
+ /**
126
+ * Check for old structure files and warn user about manual migration
127
+ */
128
+ function checkOldStructure(clientDir) {
129
+ const oldOfetchPath = resolve(clientDir, "ofetch.ts");
130
+ const oldSdkPath = resolve(clientDir, "sdk.ts");
131
+ if (existsSync(oldOfetchPath) || existsSync(oldSdkPath)) {
132
+ const foundFiles = [];
133
+ if (existsSync(oldOfetchPath)) foundFiles.push("app/graphql/ofetch.ts");
134
+ if (existsSync(oldSdkPath)) foundFiles.push("app/graphql/sdk.ts");
135
+ consola.error(`⚠️ OLD GRAPHQL STRUCTURE DETECTED!
136
+
137
+ 📁 Found old files in app/graphql/ directory that need to be moved:
138
+ • ${foundFiles.join("\n • ")}
139
+
140
+ 🔄 Please manually move these files to the new structure:
141
+ • app/graphql/ofetch.ts → app/graphql/default/ofetch.ts
142
+ • app/graphql/sdk.ts → app/graphql/default/sdk.ts
143
+
144
+ 📝 Also update your app/graphql/index.ts to include:
145
+ export * from './default/ofetch'
146
+
147
+ 💡 After moving, update your imports to use:
148
+ import { $sdk } from "#graphql/client"
149
+
150
+ 🚫 The old files will cause import conflicts until moved!`);
151
+ }
152
+ }
153
+ async function generateMainClientTypes(nitro) {
154
+ checkOldStructure(nitro.graphql.clientDir);
155
+ const docs = nitro.scanDocuments;
156
+ const loadDocs = await loadGraphQLDocuments(docs);
157
+ const schemaFilePath = join(nitro.graphql.buildDir, "schema.graphql");
158
+ if (!existsSync(schemaFilePath)) {
159
+ consola.info("Schema file not ready yet for client type generation. Server types need to be generated first.");
160
+ return;
161
+ }
162
+ const graphqlString = readFileSync(schemaFilePath, "utf-8");
163
+ const schema = buildSchema(graphqlString);
164
+ const types = await generateClientTypes(schema, loadDocs, nitro.options.graphql?.codegen?.client ?? {}, nitro.options.graphql?.codegen?.clientSDK ?? {});
165
+ if (types === false) return;
166
+ const clientTypesPath = resolve(nitro.options.buildDir, "types", "nitro-graphql-client.d.ts");
167
+ const defaultServiceDir = resolve(nitro.graphql.clientDir, "default");
168
+ const sdkTypesPath = resolve(defaultServiceDir, "sdk.ts");
169
+ mkdirSync(dirname(clientTypesPath), { recursive: true });
170
+ writeFileSync(clientTypesPath, types.types, "utf-8");
171
+ mkdirSync(defaultServiceDir, { recursive: true });
172
+ writeFileSync(sdkTypesPath, types.sdk, "utf-8");
173
+ if (nitro.options.framework?.name === "nuxt") {
174
+ generateNuxtOfetchClient(nitro.graphql.clientDir, "default");
175
+ const externalServices = nitro.options.graphql?.externalServices || [];
176
+ generateGraphQLIndexFile(nitro.graphql.clientDir, externalServices);
177
+ }
178
+ }
179
+ async function generateExternalServicesTypes(nitro) {
180
+ const externalServices = nitro.options.graphql?.externalServices || [];
181
+ for (const service of externalServices) try {
182
+ consola.info(`[graphql:${service.name}] Processing external service`);
183
+ await downloadAndSaveSchema(service, nitro.options.buildDir);
184
+ const schema = await loadExternalSchema(service, nitro.options.buildDir);
185
+ if (!schema) {
186
+ consola.warn(`[graphql:${service.name}] Failed to load schema, skipping`);
187
+ continue;
188
+ }
189
+ const documentPatterns = service.documents || [];
190
+ let loadDocs = [];
191
+ if (documentPatterns.length > 0) try {
192
+ loadDocs = await loadGraphQLDocuments(documentPatterns);
193
+ } catch (error) {
194
+ consola.warn(`[graphql:${service.name}] No documents found:`, error);
195
+ }
196
+ const types = await generateExternalClientTypes(service, schema, loadDocs);
197
+ if (types === false) {
198
+ consola.warn(`[graphql:${service.name}] Type generation failed`);
199
+ continue;
200
+ }
201
+ const serviceTypesPath = resolve(nitro.options.buildDir, "types", `nitro-graphql-client-${service.name}.d.ts`);
202
+ const serviceDir = resolve(nitro.graphql.clientDir, service.name);
203
+ const serviceSdkPath = resolve(serviceDir, "sdk.ts");
204
+ mkdirSync(dirname(serviceTypesPath), { recursive: true });
205
+ writeFileSync(serviceTypesPath, types.types, "utf-8");
206
+ mkdirSync(serviceDir, { recursive: true });
207
+ writeFileSync(serviceSdkPath, types.sdk, "utf-8");
208
+ if (nitro.options.framework?.name === "nuxt") generateExternalOfetchClient(nitro.graphql.clientDir, service.name, service.endpoint);
209
+ consola.success(`[graphql:${service.name}] External service types generated successfully`);
210
+ } catch (error) {
211
+ consola.error(`[graphql:${service.name}] External service generation failed:`, error);
212
+ }
213
+ }
90
214
 
91
215
  //#endregion
92
216
  export { clientTypeGeneration, serverTypeGeneration };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nitro-graphql",
3
3
  "type": "module",
4
- "version": "1.1.2",
4
+ "version": "1.2.0",
5
5
  "description": "GraphQL integration for Nitro",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,
@@ -72,6 +72,7 @@
72
72
  "@graphql-tools/load-files": "^7.0.1",
73
73
  "@graphql-tools/merge": "^9.1.0",
74
74
  "@graphql-tools/schema": "^10.0.24",
75
+ "@graphql-tools/url-loader": "^8.0.33",
75
76
  "@graphql-tools/utils": "^10.9.0",
76
77
  "chokidar": "^4.0.3",
77
78
  "consola": "^3.4.2",
@@ -88,8 +89,8 @@
88
89
  "@antfu/eslint-config": "^4.17.0",
89
90
  "@apollo/server": "^5.0.0",
90
91
  "@graphql-codegen/import-types-preset": "^3.0.1",
91
- "@nuxt/kit": "4.0.0-rc.0",
92
- "@nuxt/schema": "4.0.0-rc.0",
92
+ "@nuxt/kit": "^4.0.3",
93
+ "@nuxt/schema": "^4.0.3",
93
94
  "@types/node": "^20.19.9",
94
95
  "bumpp": "^10.2.0",
95
96
  "changelogen": "^0.6.2",