nitro-graphql 1.2.0 → 1.2.2
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/dist/ecosystem/nuxt.d.ts +2 -2
- package/dist/ecosystem/nuxt.js +22 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/routes/apollo-server.d.ts +2 -2
- package/dist/routes/graphql-yoga.d.ts +2 -2
- package/dist/utils/client-codegen.js +104 -32
- package/dist/utils/type-generation.js +5 -2
- package/package.json +1 -1
package/dist/ecosystem/nuxt.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _nuxt_schema0 from "@nuxt/schema";
|
|
2
2
|
|
|
3
3
|
//#region src/ecosystem/nuxt.d.ts
|
|
4
4
|
interface ModuleOptions {}
|
|
5
|
-
declare const _default:
|
|
5
|
+
declare const _default: _nuxt_schema0.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { ModuleOptions, _default as default };
|
package/dist/ecosystem/nuxt.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
1
2
|
import { join, resolve } from "pathe";
|
|
2
3
|
import { defineNuxtModule } from "@nuxt/kit";
|
|
3
4
|
|
|
@@ -31,6 +32,27 @@ var nuxt_default = defineNuxtModule({
|
|
|
31
32
|
nuxt.hook("imports:dirs", (dirs) => {
|
|
32
33
|
dirs.push(resolve(nuxt.options.srcDir, "graphql"));
|
|
33
34
|
});
|
|
35
|
+
nuxt.hook("nitro:config", () => {
|
|
36
|
+
const clientDir = join(nuxt.options.buildDir, "graphql");
|
|
37
|
+
const appGraphqlDir = resolve(nuxt.options.rootDir, "app/graphql");
|
|
38
|
+
const hasAppGraphqlDir = existsSync(appGraphqlDir);
|
|
39
|
+
if (!hasAppGraphqlDir) {
|
|
40
|
+
const defaultDir = join(clientDir, "default");
|
|
41
|
+
if (!existsSync(defaultDir)) mkdirSync(defaultDir, { recursive: true });
|
|
42
|
+
const sampleQueryFile = join(defaultDir, "queries.graphql");
|
|
43
|
+
if (!existsSync(sampleQueryFile)) writeFileSync(sampleQueryFile, `# Example GraphQL queries
|
|
44
|
+
# Add your GraphQL queries here
|
|
45
|
+
|
|
46
|
+
# query GetUser($id: ID!) {
|
|
47
|
+
# user(id: $id) {
|
|
48
|
+
# id
|
|
49
|
+
# name
|
|
50
|
+
# email
|
|
51
|
+
# }
|
|
52
|
+
# }
|
|
53
|
+
`, "utf-8");
|
|
54
|
+
}
|
|
55
|
+
});
|
|
34
56
|
}
|
|
35
57
|
});
|
|
36
58
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { StandardSchemaV1 } from "./types/standard-schema.js";
|
|
2
2
|
import { CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, GenImport, GenericSdkConfig, NitroGraphQLOptions } from "./types/index.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as nitropack1 from "nitropack";
|
|
4
4
|
|
|
5
5
|
//#region src/index.d.ts
|
|
6
|
-
declare const _default:
|
|
6
|
+
declare const _default: nitropack1.NitroModule;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { CodegenClientConfig, CodegenServerConfig, ExternalGraphQLService, GenImport, GenericSdkConfig, NitroGraphQLOptions, StandardSchemaV1, _default as default };
|
package/dist/index.js
CHANGED
|
@@ -71,7 +71,8 @@ var src_default = defineNitroModule({
|
|
|
71
71
|
}
|
|
72
72
|
if (nitro.options.graphql?.externalServices?.length) {
|
|
73
73
|
for (const service of nitro.options.graphql.externalServices) if (service.documents?.length) for (const pattern of service.documents) {
|
|
74
|
-
|
|
74
|
+
if (!pattern) continue;
|
|
75
|
+
const baseDir = pattern.split("**")[0]?.replace(/\/$/, "") || ".";
|
|
75
76
|
const resolvedDir = resolve(nitro.options.rootDir, baseDir);
|
|
76
77
|
if (!watchDirs.includes(resolvedDir)) watchDirs.push(resolvedDir);
|
|
77
78
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h32 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/apollo-server.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h32.EventHandler<h32.EventHandlerRequest, any>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { _default as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as h36 from "h3";
|
|
2
2
|
|
|
3
3
|
//#region src/routes/graphql-yoga.d.ts
|
|
4
|
-
declare const _default:
|
|
4
|
+
declare const _default: h36.EventHandler<h36.EventHandlerRequest, Promise<Response>>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { _default as default };
|
|
@@ -57,23 +57,23 @@ async function loadExternalSchema(service, buildDir) {
|
|
|
57
57
|
if (service.downloadSchema && buildDir) {
|
|
58
58
|
const defaultPath = resolve(buildDir, "graphql", "schemas", `${service.name}.graphql`);
|
|
59
59
|
const schemaFilePath = service.downloadPath ? resolve(service.downloadPath) : defaultPath;
|
|
60
|
-
if (existsSync(schemaFilePath)) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return result$1;
|
|
66
|
-
} catch (localError) {
|
|
67
|
-
consola$1.warn(`[graphql:${service.name}] Failed to load local schema, falling back to remote:`, localError);
|
|
68
|
-
}
|
|
60
|
+
if (existsSync(schemaFilePath)) try {
|
|
61
|
+
const result$1 = loadSchemaSync([schemaFilePath], { loaders: [new GraphQLFileLoader()] });
|
|
62
|
+
return result$1;
|
|
63
|
+
} catch {
|
|
64
|
+
consola$1.warn(`[graphql:${service.name}] Cached schema invalid, loading from source`);
|
|
69
65
|
}
|
|
70
66
|
}
|
|
71
|
-
|
|
67
|
+
const hasUrls = schemas.some((schema) => isUrl(schema));
|
|
68
|
+
const hasLocalFiles = schemas.some((schema) => !isUrl(schema));
|
|
69
|
+
const loaders = [];
|
|
70
|
+
if (hasLocalFiles) loaders.push(new GraphQLFileLoader());
|
|
71
|
+
if (hasUrls) loaders.push(new UrlLoader());
|
|
72
|
+
if (loaders.length === 0) throw new Error("No appropriate loaders found for schema sources");
|
|
72
73
|
const result = loadSchemaSync(schemas, {
|
|
73
|
-
loaders
|
|
74
|
+
loaders,
|
|
74
75
|
...Object.keys(headers).length > 0 && { headers }
|
|
75
76
|
});
|
|
76
|
-
consola$1.info(`[graphql:${service.name}] External schema loaded successfully`);
|
|
77
77
|
return result;
|
|
78
78
|
} catch (error) {
|
|
79
79
|
consola$1.error(`[graphql:${service.name}] Failed to load external schema:`, error);
|
|
@@ -81,6 +81,12 @@ async function loadExternalSchema(service, buildDir) {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
|
+
* Check if a path is a URL (http/https)
|
|
85
|
+
*/
|
|
86
|
+
function isUrl(path) {
|
|
87
|
+
return path.startsWith("http://") || path.startsWith("https://");
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
84
90
|
* Download and save schema from external service
|
|
85
91
|
*/
|
|
86
92
|
async function downloadAndSaveSchema(service, buildDir) {
|
|
@@ -91,12 +97,14 @@ async function downloadAndSaveSchema(service, buildDir) {
|
|
|
91
97
|
try {
|
|
92
98
|
const headers = typeof service.headers === "function" ? service.headers() : service.headers || {};
|
|
93
99
|
const schemas = Array.isArray(service.schema) ? service.schema : [service.schema];
|
|
100
|
+
const hasUrlSchemas = schemas.some((schema) => isUrl(schema));
|
|
101
|
+
const hasLocalSchemas = schemas.some((schema) => !isUrl(schema));
|
|
94
102
|
let shouldDownload = false;
|
|
95
103
|
const fileExists = existsSync(schemaFilePath);
|
|
96
104
|
if (downloadMode === "always") {
|
|
97
105
|
shouldDownload = true;
|
|
98
|
-
if (fileExists) try {
|
|
99
|
-
const remoteSchema = loadSchemaSync(schemas, {
|
|
106
|
+
if (fileExists && hasUrlSchemas) try {
|
|
107
|
+
const remoteSchema = loadSchemaSync(schemas.filter(isUrl), {
|
|
100
108
|
loaders: [new UrlLoader()],
|
|
101
109
|
...Object.keys(headers).length > 0 && { headers }
|
|
102
110
|
});
|
|
@@ -112,24 +120,48 @@ async function downloadAndSaveSchema(service, buildDir) {
|
|
|
112
120
|
consola$1.warn(`[graphql:${service.name}] Unable to compare with remote schema, updating local cache`);
|
|
113
121
|
shouldDownload = true;
|
|
114
122
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
else if (fileExists && hasLocalSchemas) {
|
|
124
|
+
const localFiles = schemas.filter((schema) => !isUrl(schema));
|
|
125
|
+
let sourceIsNewer = false;
|
|
126
|
+
for (const localFile of localFiles) if (existsSync(localFile)) {
|
|
127
|
+
const { statSync } = await import("node:fs");
|
|
128
|
+
const sourceStats = statSync(localFile);
|
|
129
|
+
const cachedStats = statSync(schemaFilePath);
|
|
130
|
+
if (sourceStats.mtime > cachedStats.mtime) {
|
|
131
|
+
sourceIsNewer = true;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (!sourceIsNewer) shouldDownload = false;
|
|
136
|
+
}
|
|
137
|
+
} else if (downloadMode === true || downloadMode === "once") shouldDownload = !fileExists;
|
|
119
138
|
if (shouldDownload) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
139
|
+
if (hasUrlSchemas && hasLocalSchemas) {
|
|
140
|
+
const schema = loadSchemaSync(schemas, {
|
|
141
|
+
loaders: [new GraphQLFileLoader(), new UrlLoader()],
|
|
142
|
+
...Object.keys(headers).length > 0 && { headers }
|
|
143
|
+
});
|
|
144
|
+
const schemaString = printSchemaWithDirectives(schema);
|
|
145
|
+
mkdirSync(dirname(schemaFilePath), { recursive: true });
|
|
146
|
+
writeFileSync(schemaFilePath, schemaString, "utf-8");
|
|
147
|
+
} else if (hasUrlSchemas) {
|
|
148
|
+
const schema = loadSchemaSync(schemas, {
|
|
149
|
+
loaders: [new UrlLoader()],
|
|
150
|
+
...Object.keys(headers).length > 0 && { headers }
|
|
151
|
+
});
|
|
152
|
+
const schemaString = printSchemaWithDirectives(schema);
|
|
153
|
+
mkdirSync(dirname(schemaFilePath), { recursive: true });
|
|
154
|
+
writeFileSync(schemaFilePath, schemaString, "utf-8");
|
|
155
|
+
} else if (hasLocalSchemas) {
|
|
156
|
+
const schema = loadSchemaSync(schemas, { loaders: [new GraphQLFileLoader()] });
|
|
157
|
+
const schemaString = printSchemaWithDirectives(schema);
|
|
158
|
+
mkdirSync(dirname(schemaFilePath), { recursive: true });
|
|
159
|
+
writeFileSync(schemaFilePath, schemaString, "utf-8");
|
|
160
|
+
}
|
|
129
161
|
}
|
|
130
162
|
return schemaFilePath;
|
|
131
163
|
} catch (error) {
|
|
132
|
-
consola$1.error(`[graphql:${service.name}] Failed to download schema:`, error);
|
|
164
|
+
consola$1.error(`[graphql:${service.name}] Failed to download/copy schema:`, error);
|
|
133
165
|
return void 0;
|
|
134
166
|
}
|
|
135
167
|
}
|
|
@@ -143,13 +175,11 @@ async function loadGraphQLDocuments(patterns) {
|
|
|
143
175
|
}
|
|
144
176
|
}
|
|
145
177
|
async function generateClientTypes(schema, docs, config = {}, sdkConfig = {}, outputPath, serviceName) {
|
|
146
|
-
if (docs.length === 0) {
|
|
147
|
-
|
|
148
|
-
consola$1.info(`[graphql${serviceLabel$1}] No client GraphQL files found. Skipping client type generation.`);
|
|
178
|
+
if (docs.length === 0 && !serviceName) {
|
|
179
|
+
consola$1.info("No client GraphQL files found. Skipping client type generation.");
|
|
149
180
|
return false;
|
|
150
181
|
}
|
|
151
182
|
const serviceLabel = serviceName ? `:${serviceName}` : "";
|
|
152
|
-
consola$1.info(`[graphql${serviceLabel}] Found ${docs.length} client GraphQL documents`);
|
|
153
183
|
const defaultConfig = {
|
|
154
184
|
emitLegacyCommonJSImports: false,
|
|
155
185
|
useTypeImports: true,
|
|
@@ -178,6 +208,48 @@ async function generateClientTypes(schema, docs, config = {}, sdkConfig = {}, ou
|
|
|
178
208
|
const mergedConfig = defu$1(defaultConfig, config);
|
|
179
209
|
const mergedSdkConfig = defu$1(mergedConfig, sdkConfig);
|
|
180
210
|
try {
|
|
211
|
+
if (docs.length === 0) {
|
|
212
|
+
const output$1 = await codegen({
|
|
213
|
+
filename: outputPath || "client-types.generated.ts",
|
|
214
|
+
schema: parse(printSchemaWithDirectives(schema)),
|
|
215
|
+
documents: [],
|
|
216
|
+
config: mergedConfig,
|
|
217
|
+
plugins: [{ pluginContent: {} }, { typescript: {} }],
|
|
218
|
+
pluginMap: {
|
|
219
|
+
pluginContent: { plugin: pluginContent },
|
|
220
|
+
typescript: { plugin }
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
const sdkContent$1 = `// THIS FILE IS GENERATED, DO NOT EDIT!
|
|
224
|
+
/* eslint-disable eslint-comments/no-unlimited-disable */
|
|
225
|
+
/* tslint:disable */
|
|
226
|
+
/* eslint-disable */
|
|
227
|
+
/* prettier-ignore */
|
|
228
|
+
|
|
229
|
+
import type { GraphQLResolveInfo } from 'graphql'
|
|
230
|
+
export type RequireFields<T, K extends keyof T> = Omit<T, K> & { [P in K]-?: NonNullable<T[P]> }
|
|
231
|
+
|
|
232
|
+
export interface Requester<C = {}, E = unknown> {
|
|
233
|
+
<R, V>(doc: string, vars?: V, options?: C): Promise<R> | AsyncIterable<R>
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export type Sdk = {
|
|
237
|
+
request: <R, V = Record<string, any>>(document: string, variables?: V) => Promise<R>
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function getSdk(requester: Requester): Sdk {
|
|
241
|
+
return {
|
|
242
|
+
request: <R, V = Record<string, any>>(document: string, variables?: V): Promise<R> => {
|
|
243
|
+
return requester<R, V>(document, variables)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
`;
|
|
248
|
+
return {
|
|
249
|
+
types: output$1,
|
|
250
|
+
sdk: sdkContent$1
|
|
251
|
+
};
|
|
252
|
+
}
|
|
181
253
|
const output = await codegen({
|
|
182
254
|
filename: outputPath || "client-types.generated.ts",
|
|
183
255
|
schema: parse(printSchemaWithDirectives(schema)),
|
|
@@ -116,7 +116,8 @@ async function serverTypeGeneration(app) {
|
|
|
116
116
|
}
|
|
117
117
|
async function clientTypeGeneration(nitro) {
|
|
118
118
|
try {
|
|
119
|
-
|
|
119
|
+
const hasServerSchema = nitro.scanSchemas && nitro.scanSchemas.length > 0;
|
|
120
|
+
if (hasServerSchema) await generateMainClientTypes(nitro);
|
|
120
121
|
if (nitro.options.graphql?.externalServices?.length) await generateExternalServicesTypes(nitro);
|
|
121
122
|
} catch (error) {
|
|
122
123
|
consola.error("Client schema generation error:", error);
|
|
@@ -171,7 +172,9 @@ async function generateMainClientTypes(nitro) {
|
|
|
171
172
|
mkdirSync(defaultServiceDir, { recursive: true });
|
|
172
173
|
writeFileSync(sdkTypesPath, types.sdk, "utf-8");
|
|
173
174
|
if (nitro.options.framework?.name === "nuxt") {
|
|
174
|
-
|
|
175
|
+
const appGraphqlDir = resolve(nitro.options.rootDir, "app/graphql");
|
|
176
|
+
const hasUserGraphqlSetup = existsSync(appGraphqlDir);
|
|
177
|
+
if (!hasUserGraphqlSetup) generateNuxtOfetchClient(nitro.graphql.clientDir, "default");
|
|
175
178
|
const externalServices = nitro.options.graphql?.externalServices || [];
|
|
176
179
|
generateGraphQLIndexFile(nitro.graphql.clientDir, externalServices);
|
|
177
180
|
}
|