nuxt-graphql-middleware 5.0.0-alpha.1 → 5.0.0-alpha.12
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/client/200.html +11 -0
- package/dist/client/404.html +11 -0
- package/dist/client/_nuxt/AZpplOcD.js +1 -0
- package/dist/client/_nuxt/B2Rg1ezw.js +1 -0
- package/dist/client/_nuxt/Bt6N0bOg.js +2 -0
- package/dist/client/_nuxt/M311G39J.js +25 -0
- package/dist/client/_nuxt/builds/latest.json +1 -0
- package/dist/client/_nuxt/builds/meta/88c25798-8ea2-4139-90f2-506f3146e7b3.json +1 -0
- package/dist/client/_nuxt/entry.Cn9qfNGa.css +1 -0
- package/dist/client/_nuxt/error-404.ehK72JOs.css +1 -0
- package/dist/client/_nuxt/error-500._g0akJim.css +1 -0
- package/dist/client/_nuxt/index.DGEN-H8t.css +1 -0
- package/dist/client/_nuxt/u9er1db2.js +1 -0
- package/dist/client/index.html +11 -0
- package/dist/module.d.mts +57 -205
- package/dist/module.d.ts +57 -205
- package/dist/module.json +2 -2
- package/dist/module.mjs +1138 -563
- package/dist/runtime/components/CodeFrame.vue +61 -0
- package/dist/runtime/components/DevModeOverlay.vue +60 -0
- package/dist/runtime/components/ErrorExtensions.vue +23 -0
- package/dist/runtime/components/ErrorGroup.vue +89 -0
- package/dist/runtime/composables/nuxtApp.d.ts +2 -2
- package/dist/runtime/composables/nuxtApp.js +21 -1
- package/dist/runtime/composables/useAsyncGraphqlQuery.d.ts +7 -7
- package/dist/runtime/composables/useAsyncGraphqlQuery.js +10 -2
- package/dist/runtime/composables/useGraphqlMutation.d.ts +4 -4
- package/dist/runtime/composables/useGraphqlMutation.js +1 -1
- package/dist/runtime/composables/useGraphqlQuery.d.ts +4 -4
- package/dist/runtime/composables/useGraphqlQuery.js +1 -1
- package/dist/runtime/composables/useGraphqlState.d.ts +1 -1
- package/dist/runtime/composables/useGraphqlState.js +1 -1
- package/dist/runtime/composables/useGraphqlUploadMutation.d.ts +4 -4
- package/dist/runtime/composables/useGraphqlUploadMutation.js +2 -2
- package/dist/runtime/css/output.css +1 -0
- package/dist/runtime/helpers/composables.d.ts +17 -20
- package/dist/runtime/helpers/composables.js +0 -5
- package/dist/runtime/plugins/devMode.d.ts +2 -0
- package/dist/runtime/plugins/devMode.js +23 -0
- package/dist/runtime/plugins/provideState.d.ts +1 -1
- package/dist/runtime/{serverHandler → server/api}/debug.js +3 -7
- package/dist/runtime/server/api/mutation.js +28 -0
- package/dist/runtime/server/api/query.js +29 -0
- package/dist/runtime/server/api/upload.d.ts +2 -0
- package/dist/runtime/{serverHandler → server/api}/upload.js +13 -11
- package/dist/runtime/{serverHandler → server}/helpers/index.d.ts +10 -12
- package/dist/runtime/{serverHandler → server}/helpers/index.js +9 -26
- package/dist/runtime/server/utils/doGraphqlRequest.d.ts +18 -0
- package/dist/runtime/server/utils/doGraphqlRequest.js +67 -0
- package/dist/runtime/server/utils/index.d.ts +1 -1
- package/dist/runtime/server/utils/index.js +1 -1
- package/dist/runtime/server/utils/useGraphqlMutation.d.ts +4 -4
- package/dist/runtime/server/utils/useGraphqlQuery.d.ts +4 -4
- package/dist/runtime/serverOptions/defineGraphqlServerOptions.d.ts +4 -3
- package/dist/runtime/settings/index.d.ts +0 -14
- package/dist/runtime/settings/index.js +0 -6
- package/dist/runtime/types.d.ts +204 -3
- package/dist/types.d.mts +5 -5
- package/dist/types.d.ts +5 -5
- package/package.json +39 -36
- package/dist/runtime/serverHandler/index.js +0 -78
- package/dist/runtime/serverHandler/tsconfig.json +0 -3
- /package/dist/runtime/{serverHandler → server/api}/debug.d.ts +0 -0
- /package/dist/runtime/{serverHandler/index.d.ts → server/api/mutation.d.ts} +0 -0
- /package/dist/runtime/{serverHandler/upload.d.ts → server/api/query.d.ts} +0 -0
package/dist/module.mjs
CHANGED
|
@@ -1,92 +1,25 @@
|
|
|
1
|
-
import { loadSchema } from '@graphql-tools/load';
|
|
2
1
|
import { fileURLToPath } from 'url';
|
|
2
|
+
import { useLogger, addTemplate, addServerTemplate, addTypeTemplate, createResolver, resolveAlias, resolveFiles, addPlugin, addServerHandler, addImports, addServerImports, useNitro, defineNuxtModule } from '@nuxt/kit';
|
|
3
|
+
import { existsSync, promises } from 'node:fs';
|
|
3
4
|
import { relative } from 'pathe';
|
|
4
|
-
import { defu } from 'defu';
|
|
5
|
-
import { useLogger, resolveFiles, defineNuxtModule, resolveAlias, createResolver, addImports, addServerImports, addTemplate, addServerHandler, addPlugin } from '@nuxt/kit';
|
|
6
|
-
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
7
|
-
import { existsSync } from 'fs';
|
|
8
|
-
import { GraphqlMiddlewareTemplate } from '../dist/runtime/settings/index.js';
|
|
9
|
-
import { promises, existsSync as existsSync$1 } from 'node:fs';
|
|
10
|
-
import { generate } from '@graphql-codegen/cli';
|
|
11
|
-
import * as PluginSchemaAst from '@graphql-codegen/schema-ast';
|
|
12
5
|
import { basename } from 'node:path';
|
|
13
|
-
import {
|
|
14
|
-
import { Generator } from 'graphql-typescript-deluxe';
|
|
15
|
-
import
|
|
16
|
-
import colors from 'picocolors';
|
|
6
|
+
import { printSourceLocation, parse, Source, OperationTypeNode } from 'graphql';
|
|
7
|
+
import { Generator, FieldNotFoundError, TypeNotFoundError, FragmentNotFoundError } from 'graphql-typescript-deluxe';
|
|
8
|
+
import color from 'picocolors';
|
|
17
9
|
import { validateGraphQlDocuments } from '@graphql-tools/utils';
|
|
10
|
+
import fs from 'node:fs/promises';
|
|
11
|
+
import { generate } from '@graphql-codegen/cli';
|
|
12
|
+
import * as PluginSchemaAst from '@graphql-codegen/schema-ast';
|
|
13
|
+
import { loadSchema } from '@graphql-tools/load';
|
|
14
|
+
import { defu } from 'defu';
|
|
15
|
+
import micromatch from 'micromatch';
|
|
16
|
+
import { ConfirmPrompt } from '@clack/core';
|
|
17
|
+
import isUnicodeSupported from 'is-unicode-supported';
|
|
18
|
+
import { existsSync as existsSync$1 } from 'fs';
|
|
19
|
+
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
18
20
|
|
|
19
21
|
const name = "nuxt-graphql-middleware";
|
|
20
|
-
const version = "5.0.0-alpha.
|
|
21
|
-
|
|
22
|
-
const DEVTOOLS_UI_ROUTE = "/__nuxt-graphql-middleware";
|
|
23
|
-
const DEVTOOLS_UI_LOCAL_PORT = 3300;
|
|
24
|
-
function setupDevToolsUI(nuxt, clientPath) {
|
|
25
|
-
const isProductionBuild = existsSync(clientPath);
|
|
26
|
-
if (isProductionBuild) {
|
|
27
|
-
nuxt.hook("vite:serverCreated", async (server) => {
|
|
28
|
-
const sirv = await import('sirv').then((r) => r.default || r);
|
|
29
|
-
server.middlewares.use(
|
|
30
|
-
DEVTOOLS_UI_ROUTE,
|
|
31
|
-
sirv(clientPath, { dev: true, single: true })
|
|
32
|
-
);
|
|
33
|
-
});
|
|
34
|
-
} else {
|
|
35
|
-
nuxt.hook("vite:extendConfig", (config) => {
|
|
36
|
-
config.server = config.server || {};
|
|
37
|
-
config.server.proxy = config.server.proxy || {};
|
|
38
|
-
config.server.proxy[DEVTOOLS_UI_ROUTE] = {
|
|
39
|
-
target: "http://localhost:" + DEVTOOLS_UI_LOCAL_PORT + DEVTOOLS_UI_ROUTE,
|
|
40
|
-
changeOrigin: true,
|
|
41
|
-
followRedirects: true,
|
|
42
|
-
rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
|
|
43
|
-
};
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
nuxt.hook("devtools:customTabs", (tabs) => {
|
|
47
|
-
tabs.push({
|
|
48
|
-
// unique identifier
|
|
49
|
-
name: "nuxt-graphql-middleware",
|
|
50
|
-
// title to display in the tab
|
|
51
|
-
title: "GraphQL Middleware",
|
|
52
|
-
// any icon from Iconify, or a URL to an image
|
|
53
|
-
icon: "akar-icons:graphql-fill",
|
|
54
|
-
// iframe view
|
|
55
|
-
view: {
|
|
56
|
-
type: "iframe",
|
|
57
|
-
src: DEVTOOLS_UI_ROUTE
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function pluginLoader(name) {
|
|
64
|
-
switch (name) {
|
|
65
|
-
case "@graphql-codegen/schema-ast":
|
|
66
|
-
return Promise.resolve(PluginSchemaAst);
|
|
67
|
-
}
|
|
68
|
-
throw new Error(`graphql-codegen plugin not found: ${name}`);
|
|
69
|
-
}
|
|
70
|
-
function generateSchema(moduleOptions, dest, writeToDisk) {
|
|
71
|
-
const pluginConfig = moduleOptions.codegenSchemaConfig?.urlSchemaOptions;
|
|
72
|
-
const schemaAstConfig = moduleOptions.codegenSchemaConfig?.schemaAstConfig || {
|
|
73
|
-
sort: true
|
|
74
|
-
};
|
|
75
|
-
const config = {
|
|
76
|
-
schema: moduleOptions.graphqlEndpoint,
|
|
77
|
-
pluginLoader,
|
|
78
|
-
silent: true,
|
|
79
|
-
errorsOnly: true,
|
|
80
|
-
config: pluginConfig,
|
|
81
|
-
generates: {
|
|
82
|
-
[dest]: {
|
|
83
|
-
plugins: ["schema-ast"],
|
|
84
|
-
config: schemaAstConfig
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
return generate(config, writeToDisk).then((v) => v[0]);
|
|
89
|
-
}
|
|
22
|
+
const version = "5.0.0-alpha.12";
|
|
90
23
|
|
|
91
24
|
const logger = useLogger(name);
|
|
92
25
|
const defaultOptions = {
|
|
@@ -97,150 +30,29 @@ const defaultOptions = {
|
|
|
97
30
|
debug: false,
|
|
98
31
|
includeComposables: true,
|
|
99
32
|
documents: [],
|
|
100
|
-
devtools: true
|
|
33
|
+
devtools: true,
|
|
34
|
+
errorOverlay: true,
|
|
35
|
+
graphqlConfigFilePath: "./graphql.config.ts"
|
|
101
36
|
};
|
|
102
37
|
function validateOptions(options) {
|
|
103
38
|
if (!options.graphqlEndpoint) {
|
|
104
39
|
throw new Error("Missing graphqlEndpoint.");
|
|
105
40
|
}
|
|
106
41
|
}
|
|
107
|
-
async function getSchemaPath(schemaPath, options, resolver, writeToDisk = false) {
|
|
108
|
-
const dest = resolver(schemaPath);
|
|
109
|
-
if (!options.downloadSchema) {
|
|
110
|
-
const fileExists2 = await promises.access(dest).then(() => true).catch(() => false);
|
|
111
|
-
if (!fileExists2) {
|
|
112
|
-
logger.error(
|
|
113
|
-
'"downloadSchema" is set to false but no schema exists at ' + dest
|
|
114
|
-
);
|
|
115
|
-
throw new Error("Missing GraphQL schema.");
|
|
116
|
-
}
|
|
117
|
-
const schemaContent = await promises.readFile(dest).then((v) => v.toString());
|
|
118
|
-
return { schemaPath, schemaContent };
|
|
119
|
-
}
|
|
120
|
-
if (!options.graphqlEndpoint) {
|
|
121
|
-
throw new Error("Missing graphqlEndpoint config.");
|
|
122
|
-
}
|
|
123
|
-
const result = await generateSchema(options, dest, writeToDisk);
|
|
124
|
-
return { schemaPath, schemaContent: result.content };
|
|
125
|
-
}
|
|
126
42
|
const fileExists = (path, extensions = ["js", "ts", "mjs"]) => {
|
|
127
43
|
if (!path) {
|
|
128
44
|
return null;
|
|
129
|
-
} else if (existsSync
|
|
45
|
+
} else if (existsSync(path)) {
|
|
130
46
|
return path;
|
|
131
47
|
}
|
|
132
48
|
const extension = extensions.find(
|
|
133
|
-
(extension2) => existsSync
|
|
49
|
+
(extension2) => existsSync(`${path}.${extension2}`)
|
|
134
50
|
);
|
|
135
51
|
return extension ? `${path}.${extension}` : null;
|
|
136
52
|
};
|
|
137
53
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
query: {},
|
|
141
|
-
mutation: {},
|
|
142
|
-
subscription: {}
|
|
143
|
-
};
|
|
144
|
-
for (const op of ops) {
|
|
145
|
-
result[op.operationType][op.graphqlName] = {
|
|
146
|
-
hasVariables: op.hasVariables,
|
|
147
|
-
variablesOptional: !op.needsVariables
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
return result;
|
|
151
|
-
}
|
|
152
|
-
function buildOperationTypeCode(operationMetadata, typeName, serverApiPrefix) {
|
|
153
|
-
const imports = [];
|
|
154
|
-
const resultTypes = [];
|
|
155
|
-
let code = "";
|
|
156
|
-
let nitroCode = "";
|
|
157
|
-
const operationNames = Object.keys(operationMetadata);
|
|
158
|
-
if (operationNames.length === 0) {
|
|
159
|
-
return { code, nitroCode, imports, resultTypes };
|
|
160
|
-
}
|
|
161
|
-
const lines = [];
|
|
162
|
-
const nitroLines = [];
|
|
163
|
-
for (const name of operationNames) {
|
|
164
|
-
const nameResult = pascalCase(`${name}${typeName}`);
|
|
165
|
-
const nameVariables = pascalCase(`${name}${typeName}Variables`);
|
|
166
|
-
resultTypes.push(nameResult);
|
|
167
|
-
imports.push(nameResult);
|
|
168
|
-
const { hasVariables, variablesOptional } = operationMetadata[name];
|
|
169
|
-
if (hasVariables) {
|
|
170
|
-
imports.push(nameVariables);
|
|
171
|
-
}
|
|
172
|
-
const variablesType = hasVariables ? nameVariables : "null";
|
|
173
|
-
lines.push(
|
|
174
|
-
` ${name}: [${variablesType}, ${variablesOptional ? "true" : "false"}, ${nameResult}]`
|
|
175
|
-
);
|
|
176
|
-
nitroLines.push(`
|
|
177
|
-
'${serverApiPrefix}/${typeName.toLowerCase()}/${name}': {
|
|
178
|
-
'default': GraphqlResponse<${nameResult}>
|
|
179
|
-
}`);
|
|
180
|
-
}
|
|
181
|
-
code += ` export type GraphqlMiddleware${typeName} = {
|
|
182
|
-
${lines.join(",\n")}
|
|
183
|
-
}
|
|
184
|
-
`;
|
|
185
|
-
nitroCode += nitroLines.join("\n");
|
|
186
|
-
return { code, nitroCode, imports, resultTypes };
|
|
187
|
-
}
|
|
188
|
-
function generateContextTemplate(collectedOperations, serverApiPrefix) {
|
|
189
|
-
const grouped = groupOperationsByType(collectedOperations);
|
|
190
|
-
const queryResult = buildOperationTypeCode(
|
|
191
|
-
grouped.query,
|
|
192
|
-
"Query",
|
|
193
|
-
serverApiPrefix
|
|
194
|
-
);
|
|
195
|
-
const mutationResult = buildOperationTypeCode(
|
|
196
|
-
grouped.mutation,
|
|
197
|
-
"Mutation",
|
|
198
|
-
serverApiPrefix
|
|
199
|
-
);
|
|
200
|
-
const subscriptionResult = buildOperationTypeCode(
|
|
201
|
-
grouped.subscription,
|
|
202
|
-
"Subscription",
|
|
203
|
-
serverApiPrefix
|
|
204
|
-
);
|
|
205
|
-
const allImports = [
|
|
206
|
-
...queryResult.imports,
|
|
207
|
-
...mutationResult.imports,
|
|
208
|
-
...subscriptionResult.imports
|
|
209
|
-
];
|
|
210
|
-
const allResultTypes = [
|
|
211
|
-
...queryResult.resultTypes,
|
|
212
|
-
...mutationResult.resultTypes,
|
|
213
|
-
...subscriptionResult.resultTypes
|
|
214
|
-
];
|
|
215
|
-
const combinedCode = [
|
|
216
|
-
queryResult.code,
|
|
217
|
-
mutationResult.code,
|
|
218
|
-
subscriptionResult.code
|
|
219
|
-
].join("\n");
|
|
220
|
-
const combinedNitroCode = [
|
|
221
|
-
queryResult.nitroCode,
|
|
222
|
-
mutationResult.nitroCode,
|
|
223
|
-
subscriptionResult.nitroCode
|
|
224
|
-
].join("\n");
|
|
225
|
-
return `
|
|
226
|
-
import type { GraphqlResponse } from '#graphql-middleware-server-options-build'
|
|
227
|
-
import type {
|
|
228
|
-
${allImports.join(",\n ")}
|
|
229
|
-
} from './../graphql-operations'
|
|
230
|
-
|
|
231
|
-
declare module '#nuxt-graphql-middleware/generated-types' {
|
|
232
|
-
export type GraphqlMiddlewareResponseUnion = ${allResultTypes.join(" | ")}
|
|
233
|
-
${combinedCode}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
declare module 'nitropack' {
|
|
237
|
-
interface InternalApi {
|
|
238
|
-
${combinedNitroCode}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
`;
|
|
242
|
-
}
|
|
243
|
-
|
|
54
|
+
const SYMBOL_CROSS = "x";
|
|
55
|
+
const SYMBOL_CHECK = "\u2714";
|
|
244
56
|
function getMaxLengths(entries) {
|
|
245
57
|
let name = 0;
|
|
246
58
|
let path = 0;
|
|
@@ -263,11 +75,11 @@ function logAllEntries(entries) {
|
|
|
263
75
|
let prevHadError = false;
|
|
264
76
|
for (const entry of entries) {
|
|
265
77
|
const hasErrors = entry.errors.length > 0;
|
|
266
|
-
const icon = hasErrors ?
|
|
78
|
+
const icon = hasErrors ? color.red(SYMBOL_CROSS) : color.green(SYMBOL_CHECK);
|
|
267
79
|
const type = entry.type.padEnd(lengths.type);
|
|
268
|
-
const namePadded =
|
|
269
|
-
const name = hasErrors ?
|
|
270
|
-
const path =
|
|
80
|
+
const namePadded = color.bold(entry.name.padEnd(lengths.name));
|
|
81
|
+
const name = hasErrors ? color.red(namePadded) : color.green(namePadded);
|
|
82
|
+
const path = color.dim(entry.path);
|
|
271
83
|
const parts = [icon, type, name, path];
|
|
272
84
|
if (hasErrors && !prevHadError) {
|
|
273
85
|
process.stdout.write("-".repeat(process.stdout.columns) + "\n");
|
|
@@ -276,10 +88,10 @@ function logAllEntries(entries) {
|
|
|
276
88
|
if (hasErrors) {
|
|
277
89
|
const errorLines = [];
|
|
278
90
|
entry.errors.forEach((error) => {
|
|
279
|
-
let output =
|
|
91
|
+
let output = color.red(error.message);
|
|
280
92
|
if (error.source && error.locations) {
|
|
281
93
|
for (const location of error.locations) {
|
|
282
|
-
output += "\n\n" +
|
|
94
|
+
output += "\n\n" + color.red(printSourceLocation(error.source, location));
|
|
283
95
|
}
|
|
284
96
|
}
|
|
285
97
|
errorLines.push(output);
|
|
@@ -293,6 +105,7 @@ function logAllEntries(entries) {
|
|
|
293
105
|
}
|
|
294
106
|
logger.restoreStd();
|
|
295
107
|
}
|
|
108
|
+
|
|
296
109
|
class CollectedFile {
|
|
297
110
|
filePath;
|
|
298
111
|
fileContents;
|
|
@@ -324,12 +137,21 @@ class CollectedFile {
|
|
|
324
137
|
return false;
|
|
325
138
|
}
|
|
326
139
|
}
|
|
140
|
+
|
|
327
141
|
class Collector {
|
|
328
|
-
constructor(schema,
|
|
142
|
+
constructor(schema, helper) {
|
|
329
143
|
this.schema = schema;
|
|
330
|
-
this.
|
|
331
|
-
|
|
332
|
-
|
|
144
|
+
this.helper = helper;
|
|
145
|
+
const mappedOptions = { ...helper.options.codegenConfig };
|
|
146
|
+
if (!mappedOptions.output) {
|
|
147
|
+
mappedOptions.output = {};
|
|
148
|
+
}
|
|
149
|
+
if (!mappedOptions.output.buildTypeDocFilePath) {
|
|
150
|
+
mappedOptions.output.buildTypeDocFilePath = (filePath) => {
|
|
151
|
+
return this.filePathToBuildRelative(filePath);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
this.generator = new Generator(schema, mappedOptions);
|
|
333
155
|
}
|
|
334
156
|
/**
|
|
335
157
|
* All collected files.
|
|
@@ -344,32 +166,50 @@ class Collector {
|
|
|
344
166
|
*/
|
|
345
167
|
operationTimestamps = /* @__PURE__ */ new Map();
|
|
346
168
|
/**
|
|
347
|
-
* The generated
|
|
169
|
+
* The generated operations and fragments.
|
|
348
170
|
*/
|
|
349
|
-
|
|
171
|
+
rpcItems = /* @__PURE__ */ new Map();
|
|
350
172
|
/**
|
|
351
|
-
* The
|
|
173
|
+
* The registered templates.
|
|
352
174
|
*/
|
|
353
|
-
|
|
175
|
+
templates = [];
|
|
354
176
|
/**
|
|
355
|
-
* The generated
|
|
177
|
+
* The generated template contents.
|
|
356
178
|
*/
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
179
|
+
templateResult = /* @__PURE__ */ new Map();
|
|
180
|
+
async reset() {
|
|
181
|
+
this.files.clear();
|
|
182
|
+
this.generator.reset();
|
|
183
|
+
this.operationTimestamps.clear();
|
|
184
|
+
this.rpcItems.clear();
|
|
185
|
+
}
|
|
186
|
+
async updateSchema(schema) {
|
|
187
|
+
this.schema = schema;
|
|
188
|
+
this.generator.updateSchema(schema);
|
|
189
|
+
await this.reset();
|
|
190
|
+
await this.initDocuments();
|
|
191
|
+
}
|
|
192
|
+
filePathToBuildRelative(filePath) {
|
|
193
|
+
return "./" + this.helper.toBuildRelative(filePath);
|
|
194
|
+
}
|
|
195
|
+
filePathToSourceRelative(filePath) {
|
|
196
|
+
return "./" + relative(process.cwd(), filePath);
|
|
364
197
|
}
|
|
365
198
|
operationToLogEntry(operation, errors) {
|
|
366
199
|
return {
|
|
367
200
|
name: operation.graphqlName,
|
|
368
201
|
type: operation.operationType,
|
|
369
|
-
path: this.
|
|
202
|
+
path: this.filePathToSourceRelative(operation.filePath),
|
|
370
203
|
errors
|
|
371
204
|
};
|
|
372
205
|
}
|
|
206
|
+
getTemplate(template) {
|
|
207
|
+
const content = this.templateResult.get(template);
|
|
208
|
+
if (content === void 0) {
|
|
209
|
+
throw new Error(`Missing template content: ${template}`);
|
|
210
|
+
}
|
|
211
|
+
return content;
|
|
212
|
+
}
|
|
373
213
|
/**
|
|
374
214
|
* Executes code gen and performs validation for operations.
|
|
375
215
|
*/
|
|
@@ -377,12 +217,22 @@ class Collector {
|
|
|
377
217
|
const output = this.generator.build();
|
|
378
218
|
const operations = output.getCollectedOperations();
|
|
379
219
|
const generatedCode = output.getGeneratedCode();
|
|
380
|
-
this.
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
220
|
+
this.templates.forEach((template) => {
|
|
221
|
+
if (template.build) {
|
|
222
|
+
const filename = template.options.path + ".js";
|
|
223
|
+
this.templateResult.set(
|
|
224
|
+
filename,
|
|
225
|
+
template.build(output, this.helper).trim()
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
if (template.buildTypes) {
|
|
229
|
+
const filename = template.options.path + ".d.ts";
|
|
230
|
+
this.templateResult.set(
|
|
231
|
+
filename,
|
|
232
|
+
template.buildTypes(output, this.helper).trim()
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
386
236
|
const fragmentMap = /* @__PURE__ */ new Map();
|
|
387
237
|
const operationSourceMap = /* @__PURE__ */ new Map();
|
|
388
238
|
for (const code of generatedCode) {
|
|
@@ -401,9 +251,7 @@ class Collector {
|
|
|
401
251
|
if (previousTimestamp === operation.timestamp) {
|
|
402
252
|
continue;
|
|
403
253
|
}
|
|
404
|
-
const fragments = operation.
|
|
405
|
-
(v) => v.type === "fragment-name" ? fragmentMap.get(v.value) || "" : ""
|
|
406
|
-
).join("\n");
|
|
254
|
+
const fragments = operation.getGraphQLFragmentDependencies().map((v) => fragmentMap.get(v) || "").join("\n");
|
|
407
255
|
const fullOperation = operationSourceMap.get(operation.graphqlName) + fragments;
|
|
408
256
|
const source = new Source(fullOperation, basename(operation.filePath));
|
|
409
257
|
const document = parse(source);
|
|
@@ -413,72 +261,153 @@ class Collector {
|
|
|
413
261
|
} else {
|
|
414
262
|
this.operationTimestamps.set(operation.graphqlName, operation.timestamp);
|
|
415
263
|
}
|
|
416
|
-
|
|
264
|
+
const shouldLog = errors.length || !this.helper.options.logOnlyErrors;
|
|
265
|
+
if (shouldLog) {
|
|
266
|
+
logEntries.push(this.operationToLogEntry(operation, errors));
|
|
267
|
+
}
|
|
417
268
|
}
|
|
418
269
|
logAllEntries(logEntries);
|
|
419
270
|
if (hasErrors) {
|
|
420
271
|
throw new Error("GraphQL errors");
|
|
421
272
|
}
|
|
273
|
+
if (this.helper.isDev) {
|
|
274
|
+
for (const code of generatedCode) {
|
|
275
|
+
const id = `${code.identifier}_${code.graphqlName}`;
|
|
276
|
+
if (code.identifier === "fragment" || code.identifier === "mutation" || code.identifier === "query") {
|
|
277
|
+
if (this.rpcItems.get(id)?.timestamp === code.timestamp) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
const fragmentDepdendencies = code.getGraphQLFragmentDependencies().map((name) => fragmentMap.get(name) || "").join("\n\n");
|
|
281
|
+
this.rpcItems.set(id, {
|
|
282
|
+
id,
|
|
283
|
+
timestamp: code.timestamp,
|
|
284
|
+
source: code.source + "\n\n" + fragmentDepdendencies,
|
|
285
|
+
name: code.graphqlName,
|
|
286
|
+
filePath: code.filePath,
|
|
287
|
+
identifier: code.identifier
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
buildErrorMessage(error) {
|
|
294
|
+
let output = "";
|
|
295
|
+
if (error instanceof FieldNotFoundError || error instanceof TypeNotFoundError || error instanceof FragmentNotFoundError) {
|
|
296
|
+
const filePath = error.context?.filePath;
|
|
297
|
+
const file = filePath ? this.files.get(filePath) : null;
|
|
298
|
+
if (filePath) {
|
|
299
|
+
output += ` | ${this.filePathToSourceRelative(filePath)}
|
|
300
|
+
`;
|
|
301
|
+
}
|
|
302
|
+
output += "\n" + error.message + "\n\n";
|
|
303
|
+
if (file) {
|
|
304
|
+
output += file.fileContents;
|
|
305
|
+
}
|
|
306
|
+
} else if (error instanceof Error) {
|
|
307
|
+
output += "\n" + error.message;
|
|
308
|
+
}
|
|
309
|
+
return output;
|
|
310
|
+
}
|
|
311
|
+
logError(error) {
|
|
312
|
+
let output = `${SYMBOL_CROSS}`;
|
|
313
|
+
output += this.buildErrorMessage(error);
|
|
314
|
+
logger.error(color.red(output));
|
|
422
315
|
}
|
|
423
316
|
/**
|
|
424
|
-
*
|
|
317
|
+
* Initialise the collector.
|
|
318
|
+
*
|
|
319
|
+
* In dev mode, the method will call itself recursively until all documents
|
|
320
|
+
* are valid.
|
|
321
|
+
*
|
|
322
|
+
* If not in dev mode the method will throw an error when documents are not
|
|
323
|
+
* valid.
|
|
425
324
|
*/
|
|
426
|
-
async
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
325
|
+
async init() {
|
|
326
|
+
try {
|
|
327
|
+
await this.initDocuments();
|
|
328
|
+
} catch {
|
|
329
|
+
if (this.helper.isDev) {
|
|
330
|
+
const shouldRevalidate = await this.helper.prompt.confirm(
|
|
331
|
+
"Do you want to revalidate the GraphQL documents?"
|
|
332
|
+
);
|
|
333
|
+
if (shouldRevalidate === "yes") {
|
|
334
|
+
await this.reset();
|
|
335
|
+
return this.init();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
throw new Error("Graphql document validation failed.");
|
|
431
339
|
}
|
|
432
|
-
return [];
|
|
433
340
|
}
|
|
434
341
|
/**
|
|
435
342
|
* Initialise the collector.
|
|
436
343
|
*/
|
|
437
|
-
async
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
344
|
+
async initDocuments() {
|
|
345
|
+
try {
|
|
346
|
+
const files = await this.helper.getImportPatternFiles();
|
|
347
|
+
for (const filePath of files) {
|
|
348
|
+
await this.addFile(filePath);
|
|
349
|
+
}
|
|
350
|
+
const nuxtConfigDocuments = this.helper.options.documents.join("\n\n");
|
|
351
|
+
if (nuxtConfigDocuments.length) {
|
|
352
|
+
const filePath = this.helper.paths.nuxtConfig;
|
|
353
|
+
const file = new CollectedFile(filePath, nuxtConfigDocuments, false);
|
|
354
|
+
this.files.set(filePath, file);
|
|
355
|
+
this.generator.add({
|
|
356
|
+
filePath,
|
|
357
|
+
documentNode: file.parsed
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
this.buildState();
|
|
361
|
+
logger.success("All GraphQL documents are valid.");
|
|
362
|
+
} catch (e) {
|
|
363
|
+
this.logError(e);
|
|
364
|
+
throw new Error("GraphQL document validation failed.");
|
|
365
|
+
}
|
|
452
366
|
}
|
|
453
367
|
/**
|
|
454
368
|
* Add a file.
|
|
455
369
|
*/
|
|
456
370
|
async addFile(filePath) {
|
|
457
371
|
const file = await CollectedFile.fromFilePath(filePath);
|
|
372
|
+
if (!file.fileContents) {
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
458
375
|
this.files.set(filePath, file);
|
|
459
376
|
this.generator.add({
|
|
460
|
-
filePath
|
|
377
|
+
filePath,
|
|
461
378
|
documentNode: file.parsed
|
|
462
379
|
});
|
|
463
380
|
return file;
|
|
464
381
|
}
|
|
465
382
|
async handleAdd(filePath) {
|
|
466
|
-
|
|
467
|
-
|
|
383
|
+
if (!this.helper.matchesImportPattern(filePath)) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
const result = await this.addFile(filePath);
|
|
387
|
+
return !!result;
|
|
468
388
|
}
|
|
469
389
|
async handleChange(filePath) {
|
|
390
|
+
const matchesImportPattern = this.helper.matchesImportPattern(filePath);
|
|
391
|
+
const fileExists = this.files.has(filePath);
|
|
392
|
+
if (!matchesImportPattern && !fileExists) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
470
395
|
const file = this.files.get(filePath);
|
|
471
396
|
if (!file) {
|
|
472
|
-
return
|
|
397
|
+
return this.handleAdd(filePath);
|
|
473
398
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
399
|
+
try {
|
|
400
|
+
const needsUpdate = await file.update();
|
|
401
|
+
if (!needsUpdate) {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
this.generator.update({
|
|
405
|
+
filePath,
|
|
406
|
+
documentNode: file.parsed
|
|
407
|
+
});
|
|
408
|
+
} catch {
|
|
409
|
+
return this.handleUnlink(filePath);
|
|
477
410
|
}
|
|
478
|
-
this.generator.update({
|
|
479
|
-
filePath: this.filePathToRelative(filePath),
|
|
480
|
-
documentNode: file.parsed
|
|
481
|
-
});
|
|
482
411
|
return true;
|
|
483
412
|
}
|
|
484
413
|
handleUnlink(filePath) {
|
|
@@ -487,7 +416,7 @@ class Collector {
|
|
|
487
416
|
return false;
|
|
488
417
|
}
|
|
489
418
|
this.files.delete(filePath);
|
|
490
|
-
this.generator.remove(
|
|
419
|
+
this.generator.remove(filePath);
|
|
491
420
|
return true;
|
|
492
421
|
}
|
|
493
422
|
handleUnlinkDir(folderPath) {
|
|
@@ -506,8 +435,9 @@ class Collector {
|
|
|
506
435
|
* Handle the watcher event for the given file path.
|
|
507
436
|
*/
|
|
508
437
|
async handleWatchEvent(event, filePath) {
|
|
438
|
+
let hasChanged = false;
|
|
439
|
+
const oldOperationTimestamps = new Map(this.operationTimestamps);
|
|
509
440
|
try {
|
|
510
|
-
let hasChanged = false;
|
|
511
441
|
if (event === "add") {
|
|
512
442
|
hasChanged = await this.handleAdd(filePath);
|
|
513
443
|
} else if (event === "change") {
|
|
@@ -516,357 +446,1002 @@ class Collector {
|
|
|
516
446
|
hasChanged = this.handleUnlink(filePath);
|
|
517
447
|
} else if (event === "unlinkDir") {
|
|
518
448
|
hasChanged = this.handleUnlinkDir(filePath);
|
|
519
|
-
} else if (event === "addDir") {
|
|
520
449
|
}
|
|
521
450
|
if (hasChanged) {
|
|
522
451
|
this.buildState();
|
|
523
452
|
}
|
|
524
453
|
} catch (e) {
|
|
525
454
|
this.generator.resetCaches();
|
|
526
|
-
|
|
455
|
+
logger.error("Failed to update GraphQL code.");
|
|
456
|
+
this.logError(e);
|
|
457
|
+
return {
|
|
458
|
+
hasChanged: false,
|
|
459
|
+
affectedOperations: [],
|
|
460
|
+
error: { message: this.buildErrorMessage(e) }
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
const affectedOperations = [];
|
|
464
|
+
if (hasChanged) {
|
|
465
|
+
logger.success("Finished GraphQL code update successfully.");
|
|
466
|
+
for (const [name, newTimestamp] of this.operationTimestamps) {
|
|
467
|
+
const oldTimestamp = oldOperationTimestamps.get(name);
|
|
468
|
+
if (!oldTimestamp || oldTimestamp !== newTimestamp) {
|
|
469
|
+
affectedOperations.push(name);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
527
472
|
}
|
|
473
|
+
return { hasChanged, affectedOperations };
|
|
528
474
|
}
|
|
529
475
|
/**
|
|
530
|
-
*
|
|
476
|
+
* Adds a virtual template (not written to disk) for both Nuxt and Nitro.
|
|
477
|
+
*
|
|
478
|
+
* For some reason a template written to disk works for both Nuxt and Nitro,
|
|
479
|
+
* but a virtual template requires adding two templates.
|
|
531
480
|
*/
|
|
532
|
-
|
|
533
|
-
|
|
481
|
+
addVirtualTemplate(template) {
|
|
482
|
+
const filename = template.options.path + ".js";
|
|
483
|
+
const getContents = () => this.getTemplate(filename);
|
|
484
|
+
addTemplate({
|
|
485
|
+
filename,
|
|
486
|
+
getContents
|
|
487
|
+
});
|
|
488
|
+
addServerTemplate({
|
|
489
|
+
// Since this is a virtual template, the name must match the final
|
|
490
|
+
// alias, example:
|
|
491
|
+
// - nuxt-graphql-middleware/foobar.mjs => #nuxt-graphql-middleware/foobar
|
|
492
|
+
//
|
|
493
|
+
// That way we can reference the same template using the alias in both
|
|
494
|
+
// Nuxt and Nitro environments.
|
|
495
|
+
filename: "#" + template.options.path,
|
|
496
|
+
getContents
|
|
497
|
+
});
|
|
534
498
|
}
|
|
535
499
|
/**
|
|
536
|
-
*
|
|
500
|
+
* Adds a template that dependes on Collector state.
|
|
537
501
|
*/
|
|
538
|
-
|
|
539
|
-
|
|
502
|
+
addTemplate(template) {
|
|
503
|
+
this.templates.push(template);
|
|
504
|
+
if (template.build) {
|
|
505
|
+
if (template.options.virtual) {
|
|
506
|
+
this.addVirtualTemplate(template);
|
|
507
|
+
} else {
|
|
508
|
+
const filename = template.options.path + ".js";
|
|
509
|
+
addTemplate({
|
|
510
|
+
filename,
|
|
511
|
+
write: true,
|
|
512
|
+
getContents: () => this.getTemplate(filename)
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (template.buildTypes) {
|
|
517
|
+
const filename = template.options.path + ".d.ts";
|
|
518
|
+
addTypeTemplate(
|
|
519
|
+
{
|
|
520
|
+
filename,
|
|
521
|
+
write: true,
|
|
522
|
+
getContents: () => this.getTemplate(filename)
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
nuxt: true,
|
|
526
|
+
nitro: true
|
|
527
|
+
}
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
class SchemaProvider {
|
|
534
|
+
constructor(helper) {
|
|
535
|
+
this.helper = helper;
|
|
540
536
|
}
|
|
541
537
|
/**
|
|
542
|
-
*
|
|
538
|
+
* The raw schema content.
|
|
543
539
|
*/
|
|
544
|
-
|
|
545
|
-
|
|
540
|
+
schemaContent = "";
|
|
541
|
+
/**
|
|
542
|
+
* The parsed schema object.
|
|
543
|
+
*/
|
|
544
|
+
schema = null;
|
|
545
|
+
async init() {
|
|
546
|
+
try {
|
|
547
|
+
await this.loadSchema();
|
|
548
|
+
} catch (error) {
|
|
549
|
+
logger.error(error);
|
|
550
|
+
const hasLoaded = await this.loadFromDiskFallback();
|
|
551
|
+
if (!hasLoaded) {
|
|
552
|
+
throw new Error("Failed to load GraphQL schema.");
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
async loadFromDiskFallback() {
|
|
557
|
+
const hasSchemaOnDisk = await this.hasSchemaOnDisk();
|
|
558
|
+
if (this.helper.isDev && hasSchemaOnDisk && this.helper.options.downloadSchema) {
|
|
559
|
+
const shouldUseFromDisk = await this.helper.prompt.confirm(
|
|
560
|
+
"Do you want to continue with the previously downloaded schema from disk?"
|
|
561
|
+
);
|
|
562
|
+
if (shouldUseFromDisk === "yes") {
|
|
563
|
+
await this.loadSchema({ forceDisk: true });
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return false;
|
|
546
568
|
}
|
|
547
569
|
/**
|
|
548
|
-
*
|
|
570
|
+
* Loads the schema from disk.
|
|
571
|
+
*
|
|
572
|
+
* @returns The schema contents from disk.
|
|
549
573
|
*/
|
|
550
|
-
|
|
574
|
+
async loadSchemaFromDisk() {
|
|
575
|
+
const fileExists = await this.hasSchemaOnDisk();
|
|
576
|
+
if (!fileExists) {
|
|
577
|
+
logger.error(
|
|
578
|
+
'"downloadSchema" is set to false but no schema exists at ' + this.helper.paths.schema
|
|
579
|
+
);
|
|
580
|
+
throw new Error("Missing GraphQL schema.");
|
|
581
|
+
}
|
|
582
|
+
logger.info(`Loading GraphQL schema from disk: ${this.helper.paths.schema}`);
|
|
583
|
+
return await fs.readFile(this.helper.paths.schema).then((v) => v.toString());
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Downloads the schema and saves it to disk.
|
|
587
|
+
*
|
|
588
|
+
* @returns The schema contents.
|
|
589
|
+
*/
|
|
590
|
+
downloadSchema() {
|
|
591
|
+
const endpoint = this.helper.options.graphqlEndpoint;
|
|
592
|
+
if (!endpoint) {
|
|
593
|
+
throw new Error("Missing graphqlEndpoint config.");
|
|
594
|
+
}
|
|
595
|
+
const pluginConfig = this.helper.options.codegenSchemaConfig?.urlSchemaOptions;
|
|
596
|
+
const schemaAstConfig = this.helper.options.codegenSchemaConfig?.schemaAstConfig || {
|
|
597
|
+
sort: true
|
|
598
|
+
};
|
|
599
|
+
const config = {
|
|
600
|
+
schema: endpoint,
|
|
601
|
+
pluginLoader: (name) => {
|
|
602
|
+
switch (name) {
|
|
603
|
+
case "@graphql-codegen/schema-ast":
|
|
604
|
+
return Promise.resolve(PluginSchemaAst);
|
|
605
|
+
}
|
|
606
|
+
throw new Error(`graphql-codegen plugin not found: ${name}`);
|
|
607
|
+
},
|
|
608
|
+
silent: true,
|
|
609
|
+
errorsOnly: true,
|
|
610
|
+
config: pluginConfig,
|
|
611
|
+
generates: {
|
|
612
|
+
[this.helper.paths.schema]: {
|
|
613
|
+
plugins: ["schema-ast"],
|
|
614
|
+
config: schemaAstConfig
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
logger.info(`Downloading GraphQL schema from "${endpoint}".`);
|
|
619
|
+
return generate(config, true).then((v) => v[0]?.content);
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Determine if the schema exists on disk.
|
|
623
|
+
*
|
|
624
|
+
* @returns True if the schema file exists on disk.
|
|
625
|
+
*/
|
|
626
|
+
hasSchemaOnDisk() {
|
|
627
|
+
return fs.access(this.helper.paths.schema).then(() => true).catch(() => false);
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Load the schema either from disk or by downloading it.
|
|
631
|
+
*
|
|
632
|
+
* @param forceDownload - Forces downloading the schema.
|
|
633
|
+
*/
|
|
634
|
+
async loadSchema(opts) {
|
|
635
|
+
if (opts?.forceDisk) {
|
|
636
|
+
this.schemaContent = await this.loadSchemaFromDisk();
|
|
637
|
+
} else if (this.helper.options.downloadSchema || opts?.forceDownload) {
|
|
638
|
+
this.schemaContent = await this.downloadSchema();
|
|
639
|
+
} else {
|
|
640
|
+
this.schemaContent = await this.loadSchemaFromDisk();
|
|
641
|
+
}
|
|
642
|
+
this.schema = await loadSchema(this.schemaContent, {
|
|
643
|
+
loaders: []
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Get the schema.
|
|
648
|
+
*
|
|
649
|
+
* @returns The parsed GraphQL schema object.
|
|
650
|
+
*/
|
|
651
|
+
getSchema() {
|
|
652
|
+
if (!this.schema) {
|
|
653
|
+
throw new Error("Failed to load schema.");
|
|
654
|
+
}
|
|
655
|
+
return this.schema;
|
|
551
656
|
}
|
|
552
657
|
}
|
|
553
658
|
|
|
554
|
-
const
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
659
|
+
const unicode = isUnicodeSupported();
|
|
660
|
+
const s = (c, fallback) => unicode ? c : fallback;
|
|
661
|
+
const S_BAR = s("\u2502", "|");
|
|
662
|
+
const S_STEP_ACTIVE = s("\u25C6", "*");
|
|
663
|
+
const S_STEP_CANCEL = s("\u25A0", "x");
|
|
664
|
+
const S_STEP_ERROR = s("\u25B2", "x");
|
|
665
|
+
const S_STEP_SUBMIT = s("\u25C7", "o");
|
|
666
|
+
const S_RADIO_ACTIVE = s("\u25CF", ">");
|
|
667
|
+
const S_RADIO_INACTIVE = s("\u25CB", " ");
|
|
668
|
+
const S_BAR_END = s("\u2514", "\u2014");
|
|
669
|
+
const symbol = (state) => {
|
|
670
|
+
switch (state) {
|
|
671
|
+
case "initial":
|
|
672
|
+
case "active":
|
|
673
|
+
return color.cyan(S_STEP_ACTIVE);
|
|
674
|
+
case "cancel":
|
|
675
|
+
return color.red(S_STEP_CANCEL);
|
|
676
|
+
case "error":
|
|
677
|
+
return color.yellow(S_STEP_ERROR);
|
|
678
|
+
case "submit":
|
|
679
|
+
return color.green(S_STEP_SUBMIT);
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
class ConsolePrompt {
|
|
683
|
+
abortController = null;
|
|
684
|
+
confirm(message) {
|
|
685
|
+
this.abort();
|
|
686
|
+
this.abortController = new AbortController();
|
|
687
|
+
const active = "Yes";
|
|
688
|
+
const inactive = "No";
|
|
689
|
+
return new ConfirmPrompt({
|
|
690
|
+
active,
|
|
691
|
+
inactive,
|
|
692
|
+
initialValue: true,
|
|
693
|
+
signal: this.abortController.signal,
|
|
694
|
+
render() {
|
|
695
|
+
const title = `${color.gray(S_BAR)}
|
|
696
|
+
${symbol(this.state)} ${message}
|
|
697
|
+
`;
|
|
698
|
+
const value = this.value ? active : inactive;
|
|
699
|
+
switch (this.state) {
|
|
700
|
+
case "submit":
|
|
701
|
+
return `${title}${color.gray(S_BAR)} ${color.dim(value)}`;
|
|
702
|
+
case "cancel":
|
|
703
|
+
return `${title}${color.gray(S_BAR)} ${color.strikethrough(
|
|
704
|
+
color.dim(value)
|
|
705
|
+
)}
|
|
706
|
+
${color.gray(S_BAR)}`;
|
|
707
|
+
default: {
|
|
708
|
+
return `${title}${color.cyan(S_BAR)} ${this.value ? `${color.green(S_RADIO_ACTIVE)} ${active}` : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(active)}`} ${color.dim("/")} ${!this.value ? `${color.green(S_RADIO_ACTIVE)} ${inactive}` : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(inactive)}`}
|
|
709
|
+
${color.cyan(S_BAR_END)}
|
|
710
|
+
`;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}).prompt().then((v) => {
|
|
715
|
+
const result = v;
|
|
716
|
+
if (result === true) {
|
|
717
|
+
return "yes";
|
|
718
|
+
} else if (result === false) {
|
|
719
|
+
return "no";
|
|
720
|
+
}
|
|
721
|
+
return "cancel";
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
abort() {
|
|
725
|
+
if (this.abortController) {
|
|
726
|
+
this.abortController.abort();
|
|
727
|
+
this.abortController = null;
|
|
569
728
|
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
class ModuleHelper {
|
|
733
|
+
constructor(nuxt, moduleUrl, options) {
|
|
734
|
+
this.nuxt = nuxt;
|
|
570
735
|
const isModuleBuild = process.env.MODULE_BUILD === "true" && nuxt.options._prepare;
|
|
736
|
+
const mergedOptions = defu({}, options, defaultOptions);
|
|
737
|
+
if (!mergedOptions.autoImportPatterns) {
|
|
738
|
+
mergedOptions.autoImportPatterns = [
|
|
739
|
+
"~~/**/*.{gql,graphql}",
|
|
740
|
+
"!node_modules"
|
|
741
|
+
];
|
|
742
|
+
}
|
|
571
743
|
if (isModuleBuild) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
744
|
+
mergedOptions.graphqlEndpoint = "http://localhost";
|
|
745
|
+
mergedOptions.downloadSchema = false;
|
|
746
|
+
mergedOptions.schemaPath = "~~/schema.graphql";
|
|
747
|
+
mergedOptions.autoImportPatterns = [
|
|
576
748
|
"~~/playground/**/*.{gql,graphql}",
|
|
577
749
|
"!node_modules"
|
|
578
750
|
];
|
|
579
751
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
(pattern) => {
|
|
585
|
-
return resolveAlias(pattern);
|
|
752
|
+
const srcResolver = createResolver(nuxt.options.srcDir);
|
|
753
|
+
mergedOptions.autoImportPatterns = (mergedOptions.autoImportPatterns || []).map((pattern) => {
|
|
754
|
+
if (pattern.startsWith("!")) {
|
|
755
|
+
return pattern;
|
|
586
756
|
}
|
|
587
|
-
|
|
757
|
+
const resolved = resolveAlias(pattern);
|
|
758
|
+
return srcResolver.resolve(resolved);
|
|
759
|
+
});
|
|
760
|
+
this.options = mergedOptions;
|
|
588
761
|
if (!nuxt.options._prepare) {
|
|
589
|
-
validateOptions(options);
|
|
762
|
+
validateOptions(this.options);
|
|
590
763
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
resolveAlias(options.schemaPath),
|
|
599
|
-
options,
|
|
600
|
-
rootResolver.resolve,
|
|
601
|
-
options.downloadSchema
|
|
602
|
-
);
|
|
603
|
-
const schema = await loadSchema(schemaContent, {
|
|
604
|
-
loaders: []
|
|
605
|
-
});
|
|
606
|
-
const runtimeDir = fileURLToPath(new URL("./runtime", import.meta.url));
|
|
607
|
-
nuxt.options.build.transpile.push(runtimeDir);
|
|
608
|
-
const context = {
|
|
609
|
-
patterns: options.autoImportPatterns || [],
|
|
610
|
-
srcDir: nuxt.options.srcDir,
|
|
611
|
-
schemaPath,
|
|
612
|
-
serverApiPrefix: options.serverApiPrefix
|
|
764
|
+
this.isDev = nuxt.options.dev;
|
|
765
|
+
this.resolvers = {
|
|
766
|
+
module: createResolver(moduleUrl),
|
|
767
|
+
server: createResolver(nuxt.options.serverDir),
|
|
768
|
+
src: srcResolver,
|
|
769
|
+
app: createResolver(nuxt.options.dir.app),
|
|
770
|
+
root: createResolver(nuxt.options.rootDir)
|
|
613
771
|
};
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
options.
|
|
772
|
+
this.paths = {
|
|
773
|
+
runtimeTypes: "",
|
|
774
|
+
root: nuxt.options.rootDir,
|
|
775
|
+
nuxtConfig: this.resolvers.root.resolve("nuxt.config.ts"),
|
|
776
|
+
serverDir: nuxt.options.serverDir,
|
|
777
|
+
schema: this.resolvers.root.resolve(
|
|
778
|
+
resolveAlias(this.options.schemaPath)
|
|
779
|
+
),
|
|
780
|
+
serverOptions: "",
|
|
781
|
+
clientOptions: this.findClientOptions(),
|
|
782
|
+
moduleBuildDir: nuxt.options.buildDir + "/nuxt-graphql-middleware",
|
|
783
|
+
moduleTypesDir: nuxt.options.buildDir + "/graphql-operations"
|
|
784
|
+
};
|
|
785
|
+
this.paths.runtimeTypes = this.toModuleBuildRelative(
|
|
786
|
+
this.resolvers.module.resolve("./runtime/types.ts")
|
|
619
787
|
);
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
788
|
+
this.paths.serverOptions = this.findServerOptions();
|
|
789
|
+
}
|
|
790
|
+
resolvers;
|
|
791
|
+
paths;
|
|
792
|
+
isDev;
|
|
793
|
+
options;
|
|
794
|
+
prompt = new ConsolePrompt();
|
|
795
|
+
nitroExternals = [];
|
|
796
|
+
/**
|
|
797
|
+
* Find the path to the graphqlMiddleware.serverOptions.ts file.
|
|
798
|
+
*/
|
|
799
|
+
findServerOptions() {
|
|
800
|
+
const newPath = this.resolvers.server.resolve(
|
|
801
|
+
"graphqlMiddleware.serverOptions"
|
|
802
|
+
);
|
|
803
|
+
const serverPath = fileExists(newPath);
|
|
804
|
+
if (serverPath) {
|
|
805
|
+
return serverPath;
|
|
806
|
+
}
|
|
807
|
+
const candidates = [
|
|
808
|
+
this.resolvers.root.resolve("graphqlMiddleware.serverOptions"),
|
|
809
|
+
this.resolvers.root.resolve("app/graphqlMiddleware.serverOptions"),
|
|
810
|
+
this.resolvers.src.resolve("graphqlMiddleware.serverOptions")
|
|
811
|
+
];
|
|
812
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
813
|
+
const path = candidates[i];
|
|
814
|
+
const filePath = fileExists(path);
|
|
815
|
+
if (filePath) {
|
|
816
|
+
throw new Error(
|
|
817
|
+
`The graphqlMiddleware.serverOptions file should be placed in Nuxt's <serverDir> ("${this.paths.serverDir}/graphqlMiddleware.serverOptions.ts").`
|
|
818
|
+
);
|
|
641
819
|
}
|
|
642
820
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
821
|
+
logger.info("No graphqlMiddleware.serverOptions file found.");
|
|
822
|
+
return null;
|
|
823
|
+
}
|
|
824
|
+
findClientOptions() {
|
|
825
|
+
const clientOptionsPath = this.resolvers.app.resolve(
|
|
826
|
+
"graphqlMiddleware.clientOptions"
|
|
827
|
+
);
|
|
828
|
+
if (fileExists(clientOptionsPath)) {
|
|
829
|
+
return clientOptionsPath;
|
|
830
|
+
}
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Transform the path relative to the module's build directory.
|
|
835
|
+
*
|
|
836
|
+
* @param path - The absolute path.
|
|
837
|
+
*
|
|
838
|
+
* @returns The path relative to the module's build directory.
|
|
839
|
+
*/
|
|
840
|
+
toModuleBuildRelative(path) {
|
|
841
|
+
return relative(this.paths.moduleBuildDir, path);
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* Transform the path relative to the Nuxt build directory.
|
|
845
|
+
*
|
|
846
|
+
* @param path - The absolute path.
|
|
847
|
+
*
|
|
848
|
+
* @returns The path relative to the module's build directory.
|
|
849
|
+
*/
|
|
850
|
+
toBuildRelative(path) {
|
|
851
|
+
return relative(this.nuxt.options.buildDir, path);
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Get all file paths that match the import patterns.
|
|
855
|
+
*/
|
|
856
|
+
async getImportPatternFiles() {
|
|
857
|
+
return resolveFiles(
|
|
858
|
+
this.nuxt.options.srcDir,
|
|
859
|
+
this.options.autoImportPatterns,
|
|
860
|
+
{
|
|
861
|
+
followSymbolicLinks: false
|
|
662
862
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
matchesImportPattern(filePath) {
|
|
866
|
+
return micromatch.isMatch(filePath, this.options.autoImportPatterns) || this.options.autoImportPatterns.includes(filePath);
|
|
867
|
+
}
|
|
868
|
+
addAlias(name, path) {
|
|
869
|
+
this.nuxt.options.alias[name] = path;
|
|
870
|
+
const pathFromName = `./${name.substring(1)}`;
|
|
871
|
+
this.nuxt.options.nitro.typescript ||= {};
|
|
872
|
+
this.nuxt.options.nitro.typescript.tsConfig ||= {};
|
|
873
|
+
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions ||= {};
|
|
874
|
+
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths ||= {};
|
|
875
|
+
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths[name] = [
|
|
876
|
+
pathFromName
|
|
877
|
+
];
|
|
878
|
+
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths[name + "/*"] = [pathFromName + "/*"];
|
|
879
|
+
this.nuxt.options.typescript.tsConfig ||= {};
|
|
880
|
+
this.nuxt.options.typescript.tsConfig.compilerOptions ||= {};
|
|
881
|
+
this.nuxt.options.typescript.tsConfig.compilerOptions.paths ||= {};
|
|
882
|
+
this.nuxt.options.typescript.tsConfig.compilerOptions.paths[name] = [
|
|
883
|
+
pathFromName
|
|
884
|
+
];
|
|
885
|
+
this.nuxt.options.typescript.tsConfig.compilerOptions.paths[name + "/*"] = [
|
|
886
|
+
pathFromName + "/*"
|
|
887
|
+
];
|
|
888
|
+
this.inlineNitroExternals(name);
|
|
889
|
+
}
|
|
890
|
+
inlineNitroExternals(arg) {
|
|
891
|
+
const path = typeof arg === "string" ? arg : arg.dst;
|
|
892
|
+
this.nitroExternals.push(path);
|
|
893
|
+
this.transpile(path);
|
|
894
|
+
}
|
|
895
|
+
transpile(path) {
|
|
896
|
+
this.nuxt.options.build.transpile.push(path);
|
|
897
|
+
}
|
|
898
|
+
applyBuildConfig() {
|
|
899
|
+
this.nuxt.options.nitro.externals ||= {};
|
|
900
|
+
this.nuxt.options.nitro.externals.inline ||= [];
|
|
901
|
+
this.nuxt.options.nitro.externals.inline.push(...this.nitroExternals);
|
|
902
|
+
}
|
|
903
|
+
addTemplate(template) {
|
|
904
|
+
if (template.build) {
|
|
905
|
+
const content = template.build(this).trim();
|
|
906
|
+
addTemplate({
|
|
907
|
+
filename: template.options.path + ".js",
|
|
908
|
+
write: true,
|
|
909
|
+
getContents: () => content
|
|
668
910
|
});
|
|
669
|
-
const serverUtils = ["useGraphqlQuery", "useGraphqlMutation"].map(
|
|
670
|
-
(name2) => {
|
|
671
|
-
return {
|
|
672
|
-
from: moduleResolver.resolve("./runtime/server/utils/" + name2),
|
|
673
|
-
name: name2
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
);
|
|
677
|
-
addServerImports(serverUtils);
|
|
678
911
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
912
|
+
if (template.buildTypes) {
|
|
913
|
+
const content = template.buildTypes(this).trim();
|
|
914
|
+
const filename = template.options.path + ".d.ts";
|
|
915
|
+
addTypeTemplate({
|
|
916
|
+
filename,
|
|
917
|
+
write: true,
|
|
918
|
+
getContents: () => content
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
addPlugin(path) {
|
|
923
|
+
addPlugin(this.resolvers.module.resolve(path), {
|
|
924
|
+
append: false
|
|
689
925
|
});
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
926
|
+
}
|
|
927
|
+
addServerHandler(name, path, method) {
|
|
928
|
+
addServerHandler({
|
|
929
|
+
handler: this.resolvers.module.resolve("./runtime/server/api/" + name),
|
|
930
|
+
route: this.options.serverApiPrefix + path,
|
|
931
|
+
method
|
|
695
932
|
});
|
|
696
|
-
addAlias("#nuxt-graphql-middleware/generated-types", templateContext.dst);
|
|
697
|
-
addTemplate({
|
|
698
|
-
write: true,
|
|
699
|
-
filename: "nuxt-graphql-middleware/graphql-documents.d.ts",
|
|
700
|
-
getContents: () => {
|
|
701
|
-
return `
|
|
702
|
-
import type {
|
|
703
|
-
GraphqlMiddlewareQuery,
|
|
704
|
-
GraphqlMiddlewareMutation,
|
|
705
|
-
} from '#nuxt-graphql-middleware/generated-types'
|
|
706
|
-
|
|
707
|
-
declare module '#graphql-documents' {
|
|
708
|
-
type Operations = {
|
|
709
|
-
query: GraphqlMiddlewareQuery
|
|
710
|
-
mutation: GraphqlMiddlewareMutation
|
|
711
933
|
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
}
|
|
934
|
+
addComposable(name) {
|
|
935
|
+
addImports({
|
|
936
|
+
from: this.resolvers.module.resolve("./runtime/composables/" + name),
|
|
937
|
+
name
|
|
717
938
|
});
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
const candidates = [
|
|
725
|
-
rootResolver.resolve("graphqlMiddleware.serverOptions"),
|
|
726
|
-
rootResolver.resolve("app/graphqlMiddleware.serverOptions"),
|
|
727
|
-
srcResolver.resolve("graphqlMiddleware.serverOptions")
|
|
728
|
-
];
|
|
729
|
-
for (let i = 0; i < candidates.length; i++) {
|
|
730
|
-
const path = candidates[i];
|
|
731
|
-
const filePath = fileExists(path);
|
|
732
|
-
if (filePath) {
|
|
733
|
-
logger.warn(
|
|
734
|
-
`The graphqlMiddleware.serverOptions file should be placed in Nuxt's <serverDir> ("${nuxt.options.serverDir}/graphqlMiddleware.serverOptions.ts"). The new path will be enforced in the next major release.`
|
|
735
|
-
);
|
|
736
|
-
return filePath;
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
logger.info("No graphqlMiddleware.serverOptions file found.");
|
|
740
|
-
};
|
|
741
|
-
const resolvedPath = findServerOptions();
|
|
742
|
-
const moduleTypesPath = relative(
|
|
743
|
-
nuxt.options.buildDir,
|
|
744
|
-
moduleResolver.resolve("./types")
|
|
745
|
-
);
|
|
746
|
-
const resolvedPathRelative = resolvedPath ? relative(nuxt.options.buildDir, resolvedPath) : null;
|
|
747
|
-
const template = addTemplate({
|
|
748
|
-
filename: "graphqlMiddleware.serverOptions.mjs",
|
|
749
|
-
write: true,
|
|
750
|
-
getContents: () => {
|
|
751
|
-
const serverOptionsLine = resolvedPathRelative ? `import serverOptions from '${resolvedPathRelative}'` : `const serverOptions = {}`;
|
|
752
|
-
return `
|
|
753
|
-
${serverOptionsLine}
|
|
754
|
-
export { serverOptions }
|
|
755
|
-
`;
|
|
939
|
+
}
|
|
940
|
+
addServerUtil(name) {
|
|
941
|
+
addServerImports([
|
|
942
|
+
{
|
|
943
|
+
from: this.resolvers.module.resolve("./runtime/server/utils/" + name),
|
|
944
|
+
name
|
|
756
945
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
write: true,
|
|
761
|
-
getContents: () => {
|
|
762
|
-
const serverOptionsLineTypes = resolvedPathRelative ? `import serverOptions from '${resolvedPathRelative}'` : `const serverOptions: GraphqlMiddlewareServerOptions = {}`;
|
|
763
|
-
return `
|
|
764
|
-
import type { GraphqlMiddlewareServerOptions } from '${moduleTypesPath}'
|
|
765
|
-
${serverOptionsLineTypes}
|
|
766
|
-
import type { GraphqlServerResponse } from '${runtimeTypesPath}'
|
|
767
|
-
import type { GraphqlMiddlewareResponseUnion } from '#nuxt-graphql-middleware/generated-types'
|
|
768
|
-
|
|
769
|
-
type GraphqlResponseAdditions =
|
|
770
|
-
typeof serverOptions extends GraphqlMiddlewareServerOptions<infer R, any, any> ? R : {}
|
|
771
|
-
|
|
772
|
-
export type GraphqlResponse<T> = GraphqlServerResponse<T> & GraphqlResponseAdditions
|
|
946
|
+
]);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
773
949
|
|
|
774
|
-
|
|
950
|
+
function defineGeneratorTemplate(options, build, buildTypes) {
|
|
951
|
+
return {
|
|
952
|
+
type: "generator",
|
|
953
|
+
options,
|
|
954
|
+
build,
|
|
955
|
+
buildTypes
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
function defineStaticTemplate(options, build, buildTypes) {
|
|
959
|
+
return {
|
|
960
|
+
type: "static",
|
|
961
|
+
options,
|
|
962
|
+
build,
|
|
963
|
+
buildTypes
|
|
964
|
+
};
|
|
965
|
+
}
|
|
775
966
|
|
|
776
|
-
|
|
967
|
+
const ClientOptions = defineStaticTemplate(
|
|
968
|
+
{ path: "nuxt-graphql-middleware/client-options" },
|
|
969
|
+
(helper) => {
|
|
970
|
+
if (helper.paths.clientOptions) {
|
|
971
|
+
const pathRelative = helper.toModuleBuildRelative(
|
|
972
|
+
helper.paths.clientOptions
|
|
973
|
+
);
|
|
974
|
+
return `import clientOptions from '${pathRelative}'
|
|
975
|
+
export { clientOptions }
|
|
777
976
|
`;
|
|
778
|
-
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
977
|
+
}
|
|
978
|
+
return `export const clientOptions = {}`;
|
|
979
|
+
},
|
|
980
|
+
(helper) => {
|
|
981
|
+
if (helper.paths.clientOptions) {
|
|
982
|
+
const pathRelative = helper.toModuleBuildRelative(
|
|
983
|
+
helper.paths.clientOptions
|
|
783
984
|
);
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
return `import clientOptions from '${pathRelative}'`;
|
|
787
|
-
}
|
|
788
|
-
};
|
|
789
|
-
const clientOptionsImport = getClientOptionsImport();
|
|
790
|
-
const clientOptionsTemplate = addTemplate({
|
|
791
|
-
filename: "graphqlMiddleware.clientOptions.mjs",
|
|
792
|
-
write: true,
|
|
793
|
-
getContents: () => {
|
|
794
|
-
if (clientOptionsImport) {
|
|
795
|
-
return `${clientOptionsImport}
|
|
796
|
-
export { clientOptions }`;
|
|
797
|
-
}
|
|
798
|
-
return `export const clientOptions = {}`;
|
|
799
|
-
}
|
|
800
|
-
});
|
|
801
|
-
const runtimeTypesPath = relative(
|
|
802
|
-
nuxt.options.buildDir,
|
|
803
|
-
moduleResolver.resolve("./runtime/types.ts")
|
|
804
|
-
);
|
|
805
|
-
addTemplate({
|
|
806
|
-
filename: "graphqlMiddleware.clientOptions.d.ts",
|
|
807
|
-
write: true,
|
|
808
|
-
getContents: () => {
|
|
809
|
-
if (clientOptionsImport) {
|
|
810
|
-
return `import type { GraphqlClientOptions } from '${runtimeTypesPath}'
|
|
811
|
-
${clientOptionsImport}
|
|
985
|
+
return `import type { GraphqlClientOptions } from '${helper.paths.runtimeTypes}'
|
|
986
|
+
import { clientOptions } from '${pathRelative}'
|
|
812
987
|
|
|
813
988
|
export type GraphqlClientContext = typeof clientOptions extends GraphqlClientOptions<infer R> ? R : {}
|
|
814
989
|
|
|
815
990
|
export { clientOptions }`;
|
|
816
|
-
|
|
817
|
-
|
|
991
|
+
}
|
|
992
|
+
return `
|
|
993
|
+
import type { GraphqlClientOptions } from '${helper.paths.runtimeTypes}'
|
|
818
994
|
export const clientOptions: GraphqlClientOptions
|
|
819
995
|
|
|
820
996
|
export type GraphqlClientContext = {}
|
|
821
997
|
`;
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
998
|
+
}
|
|
999
|
+
);
|
|
1000
|
+
|
|
1001
|
+
const Documents = defineGeneratorTemplate(
|
|
1002
|
+
{ path: "nuxt-graphql-middleware/documents", virtual: true },
|
|
1003
|
+
(output, helper) => {
|
|
1004
|
+
return output.getOperationsFile({
|
|
1005
|
+
exportName: "documents",
|
|
1006
|
+
minify: !helper.isDev
|
|
1007
|
+
}).getSource();
|
|
1008
|
+
},
|
|
1009
|
+
() => {
|
|
1010
|
+
return `
|
|
1011
|
+
import type { Query, Mutation } from './operation-types'
|
|
1012
|
+
|
|
1013
|
+
declare module '#nuxt-graphql-middleware/documents' {
|
|
1014
|
+
export type Documents = {
|
|
1015
|
+
query: Record<keyof Query, string>
|
|
1016
|
+
mutation: Record<keyof Mutation, string>
|
|
1017
|
+
}
|
|
1018
|
+
export const documents: Documents
|
|
1019
|
+
}`;
|
|
1020
|
+
}
|
|
1021
|
+
);
|
|
1022
|
+
|
|
1023
|
+
const GraphqlConfig = defineStaticTemplate(
|
|
1024
|
+
{ path: "nuxt-graphql-middleware/graphql.config" },
|
|
1025
|
+
(helper) => {
|
|
1026
|
+
const patterns = helper.options.autoImportPatterns || [];
|
|
1027
|
+
const configPath = helper.resolvers.root.resolve(
|
|
1028
|
+
(helper.options.graphqlConfigFilePath || "").replace(
|
|
1029
|
+
"/graphql.config.ts",
|
|
1030
|
+
""
|
|
1031
|
+
)
|
|
833
1032
|
);
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
1033
|
+
const schemaPath = "./" + relative(configPath, helper.paths.schema);
|
|
1034
|
+
const documents = patterns.filter((v) => !v.includes("!")).map((pattern) => {
|
|
1035
|
+
return "./" + relative(configPath, helper.resolvers.root.resolve(pattern));
|
|
837
1036
|
});
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
1037
|
+
return `const schema = ${JSON.stringify(schemaPath)}
|
|
1038
|
+
|
|
1039
|
+
const documents = ${JSON.stringify(documents, null, 2)};
|
|
1040
|
+
|
|
1041
|
+
const config = {
|
|
1042
|
+
schema,
|
|
1043
|
+
documents,
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
export default config
|
|
1047
|
+
`;
|
|
1048
|
+
},
|
|
1049
|
+
() => {
|
|
1050
|
+
return `
|
|
1051
|
+
import type { IGraphQLProject } from 'graphql-config'
|
|
1052
|
+
|
|
1053
|
+
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|
|
1054
|
+
|
|
1055
|
+
const config: WithRequired<IGraphQLProject, 'schema' | 'documents'>;
|
|
1056
|
+
|
|
1057
|
+
export default config;
|
|
1058
|
+
`;
|
|
1059
|
+
}
|
|
1060
|
+
);
|
|
1061
|
+
|
|
1062
|
+
const Helpers = defineStaticTemplate(
|
|
1063
|
+
{ path: "nuxt-graphql-middleware/helpers" },
|
|
1064
|
+
(helper) => {
|
|
1065
|
+
return `export const serverApiPrefix = '${helper.options.serverApiPrefix}'
|
|
1066
|
+
export function getEndpoint(operation, operationName) {
|
|
1067
|
+
return serverApiPrefix + '/' + operation + '/' + operationName
|
|
1068
|
+
}
|
|
1069
|
+
`;
|
|
1070
|
+
},
|
|
1071
|
+
() => {
|
|
1072
|
+
return `export const serverApiPrefix: string;
|
|
1073
|
+
export function getEndpoint(operation: string, operationName: string): string`;
|
|
1074
|
+
}
|
|
1075
|
+
);
|
|
1076
|
+
|
|
1077
|
+
const NitroTypes = defineGeneratorTemplate(
|
|
1078
|
+
{ path: "nuxt-graphql-middleware/nitro" },
|
|
1079
|
+
null,
|
|
1080
|
+
(output, helper) => {
|
|
1081
|
+
const operations = output.getCollectedOperations();
|
|
1082
|
+
const serverApiPrefix = helper.options.serverApiPrefix;
|
|
1083
|
+
const endpoints = [];
|
|
1084
|
+
const imports = [];
|
|
1085
|
+
for (const operation of operations) {
|
|
1086
|
+
imports.push(operation.typeName);
|
|
1087
|
+
const method = operation.operationType === OperationTypeNode.QUERY ? "get" : "post";
|
|
1088
|
+
endpoints.push(
|
|
1089
|
+
` '${serverApiPrefix}/${operation.operationType}/${operation.graphqlName}': {
|
|
1090
|
+
'${method}': GraphqlResponse<${operation.typeName}>
|
|
1091
|
+
}`
|
|
1092
|
+
);
|
|
843
1093
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1094
|
+
return `import type { GraphqlResponse } from './response'
|
|
1095
|
+
import type {
|
|
1096
|
+
${imports.sort().join(",\n ")}
|
|
1097
|
+
} from './../graphql-operations'
|
|
1098
|
+
|
|
1099
|
+
declare module 'nitropack/types' {
|
|
1100
|
+
interface InternalApi {
|
|
1101
|
+
${endpoints.sort().join("\n")}
|
|
1102
|
+
}
|
|
1103
|
+
}`;
|
|
1104
|
+
}
|
|
1105
|
+
);
|
|
1106
|
+
|
|
1107
|
+
const OperationTypesAll = defineGeneratorTemplate(
|
|
1108
|
+
{ path: "nuxt-graphql-middleware/operation-types" },
|
|
1109
|
+
() => `export {}`,
|
|
1110
|
+
(output) => {
|
|
1111
|
+
return output.getOperationTypesFile({
|
|
1112
|
+
importFrom: "./../graphql-operations"
|
|
1113
|
+
}).getSource();
|
|
1114
|
+
}
|
|
1115
|
+
);
|
|
1116
|
+
|
|
1117
|
+
const Operations = defineGeneratorTemplate(
|
|
1118
|
+
{ path: "graphql-operations/index" },
|
|
1119
|
+
(output) => {
|
|
1120
|
+
const typesFile = output.getOperations("js");
|
|
1121
|
+
return typesFile.getSource();
|
|
1122
|
+
},
|
|
1123
|
+
(output) => {
|
|
1124
|
+
const typesFile = output.getOperations("d.ts");
|
|
1125
|
+
return typesFile.getSource();
|
|
1126
|
+
}
|
|
1127
|
+
);
|
|
1128
|
+
|
|
1129
|
+
const Response = defineGeneratorTemplate(
|
|
1130
|
+
{ path: "nuxt-graphql-middleware/response" },
|
|
1131
|
+
null,
|
|
1132
|
+
(output, helper) => {
|
|
1133
|
+
const operations = output.getCollectedOperations();
|
|
1134
|
+
const allTypes = operations.map((v) => v.typeName).sort();
|
|
1135
|
+
return `import type {
|
|
1136
|
+
${allTypes.join(",\n ")}
|
|
1137
|
+
} from './../graphql-operations'
|
|
1138
|
+
import type { GraphqlResponseAdditions } from './server-options'
|
|
1139
|
+
import type { GraphqlServerResponse } from '${helper.paths.runtimeTypes}'
|
|
1140
|
+
|
|
1141
|
+
declare module '#nuxt-graphql-middleware/response' {
|
|
1142
|
+
export type GraphqlMiddlewareResponseUnion =
|
|
1143
|
+
| ${allTypes.join("\n | ") || "never"}
|
|
1144
|
+
|
|
1145
|
+
export type GraphqlResponse<T> = GraphqlServerResponse<T> & GraphqlResponseAdditions
|
|
1146
|
+
export type GraphqlResponseTyped = GraphqlResponse<GraphqlMiddlewareResponseUnion>
|
|
1147
|
+
}`;
|
|
1148
|
+
}
|
|
1149
|
+
);
|
|
1150
|
+
|
|
1151
|
+
const ServerOptions = defineStaticTemplate(
|
|
1152
|
+
{ path: "nuxt-graphql-middleware/server-options" },
|
|
1153
|
+
(helper) => {
|
|
1154
|
+
const resolvedPathRelative = helper.paths.serverOptions ? helper.toModuleBuildRelative(helper.paths.serverOptions) : null;
|
|
1155
|
+
const serverOptionsLine = resolvedPathRelative ? `import serverOptions from '${resolvedPathRelative}'` : `const serverOptions = {}`;
|
|
1156
|
+
return `
|
|
1157
|
+
${serverOptionsLine}
|
|
1158
|
+
export { serverOptions }
|
|
1159
|
+
`;
|
|
1160
|
+
},
|
|
1161
|
+
(helper) => {
|
|
1162
|
+
const resolvedPathRelative = helper.paths.serverOptions ? helper.toModuleBuildRelative(helper.paths.serverOptions) : null;
|
|
1163
|
+
const serverOptionsLineTypes = resolvedPathRelative ? `import serverOptions from '${resolvedPathRelative}'` : `const serverOptions: GraphqlMiddlewareServerOptions = {}`;
|
|
1164
|
+
return `
|
|
1165
|
+
import type { GraphqlMiddlewareServerOptions } from '${helper.paths.runtimeTypes}'
|
|
1166
|
+
${serverOptionsLineTypes}
|
|
1167
|
+
|
|
1168
|
+
export type GraphqlResponseAdditions =
|
|
1169
|
+
typeof serverOptions extends GraphqlMiddlewareServerOptions<infer R, any, any> ? R : {}
|
|
1170
|
+
|
|
1171
|
+
export { serverOptions }`;
|
|
1172
|
+
}
|
|
1173
|
+
);
|
|
1174
|
+
|
|
1175
|
+
const Sources = defineGeneratorTemplate(
|
|
1176
|
+
{ path: "nuxt-graphql-middleware/sources" },
|
|
1177
|
+
(output, helper) => {
|
|
1178
|
+
const operations = output.getCollectedOperations();
|
|
1179
|
+
const srcDir = helper.paths.root;
|
|
1180
|
+
const lines = [];
|
|
1181
|
+
for (const operation of operations) {
|
|
1182
|
+
const filePath = relative(srcDir, operation.filePath);
|
|
1183
|
+
lines.push(
|
|
1184
|
+
`${operation.operationType}_${operation.graphqlName}: '${filePath}',`
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
return `
|
|
1188
|
+
export const operationSources = {
|
|
1189
|
+
${lines.join("\n ")}
|
|
1190
|
+
}
|
|
1191
|
+
`;
|
|
1192
|
+
},
|
|
1193
|
+
() => {
|
|
1194
|
+
return `export const operationSources: Record<string, string>`;
|
|
1195
|
+
}
|
|
1196
|
+
);
|
|
1197
|
+
|
|
1198
|
+
const TEMPLATES = [
|
|
1199
|
+
ClientOptions,
|
|
1200
|
+
Documents,
|
|
1201
|
+
GraphqlConfig,
|
|
1202
|
+
Helpers,
|
|
1203
|
+
NitroTypes,
|
|
1204
|
+
OperationTypesAll,
|
|
1205
|
+
Operations,
|
|
1206
|
+
Response,
|
|
1207
|
+
ServerOptions,
|
|
1208
|
+
Sources
|
|
1209
|
+
];
|
|
1210
|
+
|
|
1211
|
+
const DEVTOOLS_UI_ROUTE = "/__nuxt-graphql-middleware";
|
|
1212
|
+
const DEVTOOLS_UI_LOCAL_PORT = 3300;
|
|
1213
|
+
function setupDevToolsUI(nuxt, clientPath) {
|
|
1214
|
+
const isProductionBuild = existsSync$1(clientPath);
|
|
1215
|
+
if (isProductionBuild) {
|
|
1216
|
+
nuxt.hook("vite:serverCreated", async (server) => {
|
|
1217
|
+
const sirv = await import('sirv').then((r) => r.default || r);
|
|
1218
|
+
server.middlewares.use(
|
|
1219
|
+
DEVTOOLS_UI_ROUTE,
|
|
1220
|
+
sirv(clientPath, { dev: true, single: true })
|
|
853
1221
|
);
|
|
854
1222
|
});
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
1223
|
+
} else {
|
|
1224
|
+
nuxt.hook("vite:extendConfig", (config) => {
|
|
1225
|
+
config.server = config.server || {};
|
|
1226
|
+
config.server.proxy = config.server.proxy || {};
|
|
1227
|
+
config.server.proxy[DEVTOOLS_UI_ROUTE] = {
|
|
1228
|
+
target: "http://localhost:" + DEVTOOLS_UI_LOCAL_PORT + DEVTOOLS_UI_ROUTE,
|
|
1229
|
+
changeOrigin: true,
|
|
1230
|
+
followRedirects: true,
|
|
1231
|
+
rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
|
|
1232
|
+
};
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
nuxt.hook("devtools:customTabs", (tabs) => {
|
|
1236
|
+
tabs.push({
|
|
1237
|
+
// unique identifier
|
|
1238
|
+
name: "nuxt-graphql-middleware",
|
|
1239
|
+
// title to display in the tab
|
|
1240
|
+
title: "GraphQL Middleware",
|
|
1241
|
+
// any icon from Iconify, or a URL to an image
|
|
1242
|
+
icon: "akar-icons:graphql-fill",
|
|
1243
|
+
// iframe view
|
|
1244
|
+
view: {
|
|
1245
|
+
type: "iframe",
|
|
1246
|
+
src: DEVTOOLS_UI_ROUTE
|
|
1247
|
+
}
|
|
1248
|
+
});
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
const RPC_NAMESPACE = "nuxt-graphql-middleware";
|
|
1253
|
+
class DevModeHandler {
|
|
1254
|
+
constructor(nuxt, schemaProvider, collector, helper) {
|
|
1255
|
+
this.nuxt = nuxt;
|
|
1256
|
+
this.schemaProvider = schemaProvider;
|
|
1257
|
+
this.collector = collector;
|
|
1258
|
+
this.helper = helper;
|
|
1259
|
+
}
|
|
1260
|
+
devToolsRpc = null;
|
|
1261
|
+
nitro = null;
|
|
1262
|
+
viteWebSocket = null;
|
|
1263
|
+
operationsToReload = /* @__PURE__ */ new Set();
|
|
1264
|
+
init() {
|
|
1265
|
+
this.nuxt.hooks.hookOnce("ready", this.onReady.bind(this));
|
|
1266
|
+
this.nuxt.hooks.hookOnce(
|
|
1267
|
+
"vite:serverCreated",
|
|
1268
|
+
this.onViteServerCreated.bind(this)
|
|
1269
|
+
);
|
|
1270
|
+
this.nuxt.hook("builder:watch", this.onBuilderWatch.bind(this));
|
|
1271
|
+
if (this.helper.options.devtools) {
|
|
1272
|
+
const clientPath = this.helper.resolvers.module.resolve("./client");
|
|
1273
|
+
setupDevToolsUI(this.nuxt, clientPath);
|
|
1274
|
+
onDevToolsInitialized(() => {
|
|
1275
|
+
this.devToolsRpc = extendServerRpc(
|
|
1276
|
+
RPC_NAMESPACE,
|
|
1277
|
+
{
|
|
1278
|
+
// register server RPC functions
|
|
1279
|
+
getModuleOptions: () => {
|
|
1280
|
+
return this.helper.options;
|
|
1281
|
+
},
|
|
1282
|
+
getDocuments: () => {
|
|
1283
|
+
return [...this.collector.rpcItems.values()];
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
);
|
|
859
1287
|
});
|
|
860
|
-
|
|
861
|
-
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
onReady() {
|
|
1291
|
+
this.nitro = useNitro();
|
|
1292
|
+
this.nitro.hooks.hook("compiled", this.onNitroCompiled.bind(this));
|
|
1293
|
+
}
|
|
1294
|
+
async onBuilderWatch(event, providedFilePath) {
|
|
1295
|
+
if (!providedFilePath.endsWith(".graphql") && !providedFilePath.endsWith(".gql")) {
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
const pathAbsolute = providedFilePath.startsWith("/") ? providedFilePath : this.helper.resolvers.src.resolve(providedFilePath);
|
|
1299
|
+
if (pathAbsolute === this.helper.paths.schema) {
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
this.helper.prompt.abort();
|
|
1303
|
+
const { hasChanged, affectedOperations, error } = await this.collector.handleWatchEvent(event, pathAbsolute);
|
|
1304
|
+
if (error) {
|
|
1305
|
+
this.sendError(error);
|
|
1306
|
+
await this.helper.prompt.confirm("Do you want to download and update the GraphQL schema?").then(async (shouldReload) => {
|
|
1307
|
+
if (shouldReload !== "yes") {
|
|
862
1308
|
return;
|
|
863
1309
|
}
|
|
864
|
-
|
|
865
|
-
|
|
1310
|
+
try {
|
|
1311
|
+
await this.schemaProvider.loadSchema({ forceDownload: true });
|
|
1312
|
+
await this.collector.updateSchema(this.schemaProvider.getSchema());
|
|
1313
|
+
} catch (e) {
|
|
1314
|
+
logger.error(e);
|
|
866
1315
|
}
|
|
867
|
-
await collector.handleWatchEvent(event, pathAbsolute);
|
|
868
1316
|
});
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
if (!hasChanged) {
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
if (this.nitro) {
|
|
1323
|
+
await this.nitro.hooks.callHook("rollup:reload");
|
|
1324
|
+
}
|
|
1325
|
+
if (affectedOperations.length) {
|
|
1326
|
+
affectedOperations.forEach(
|
|
1327
|
+
(operation) => this.operationsToReload.add(operation)
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
if (this.devToolsRpc) {
|
|
1331
|
+
try {
|
|
1332
|
+
this.devToolsRpc.broadcast.documentsUpdated([
|
|
1333
|
+
...this.collector.rpcItems.values()
|
|
1334
|
+
]);
|
|
1335
|
+
} catch {
|
|
1336
|
+
logger.info(
|
|
1337
|
+
"Failed to update GraphQL documents in dev tools. The documents might be stale."
|
|
1338
|
+
);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
onViteServerCreated(server) {
|
|
1343
|
+
this.viteWebSocket = server.ws;
|
|
1344
|
+
}
|
|
1345
|
+
sendError(error) {
|
|
1346
|
+
if (!this.viteWebSocket) {
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
this.viteWebSocket.send({
|
|
1350
|
+
type: "error",
|
|
1351
|
+
err: {
|
|
1352
|
+
message: error.message,
|
|
1353
|
+
stack: ""
|
|
1354
|
+
}
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
onNitroCompiled() {
|
|
1358
|
+
if (!this.operationsToReload.size) {
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
const operations = [...this.operationsToReload.values()];
|
|
1362
|
+
this.operationsToReload.clear();
|
|
1363
|
+
if (!this.viteWebSocket) {
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
this.viteWebSocket.send({
|
|
1367
|
+
type: "custom",
|
|
1368
|
+
event: "nuxt-graphql-middleware:reload",
|
|
1369
|
+
data: { operations }
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
const module = defineNuxtModule({
|
|
1375
|
+
meta: {
|
|
1376
|
+
name,
|
|
1377
|
+
configKey: "graphqlMiddleware",
|
|
1378
|
+
version,
|
|
1379
|
+
compatibility: {
|
|
1380
|
+
nuxt: ">=3.15.0"
|
|
869
1381
|
}
|
|
1382
|
+
},
|
|
1383
|
+
defaults: defaultOptions,
|
|
1384
|
+
async setup(passedOptions, nuxt) {
|
|
1385
|
+
const helper = new ModuleHelper(nuxt, import.meta.url, passedOptions);
|
|
1386
|
+
const schemaProvider = new SchemaProvider(helper);
|
|
1387
|
+
await schemaProvider.init();
|
|
1388
|
+
const collector = new Collector(schemaProvider.getSchema(), helper);
|
|
1389
|
+
nuxt.options.appConfig.graphqlMiddleware = {
|
|
1390
|
+
clientCacheEnabled: !!helper.options.clientCache?.enabled,
|
|
1391
|
+
clientCacheMaxSize: helper.options.clientCache?.maxSize ?? 100
|
|
1392
|
+
};
|
|
1393
|
+
nuxt.options.runtimeConfig.graphqlMiddleware = {
|
|
1394
|
+
graphqlEndpoint: helper.options.graphqlEndpoint || ""
|
|
1395
|
+
};
|
|
1396
|
+
helper.transpile(fileURLToPath(new URL("./runtime", import.meta.url)));
|
|
1397
|
+
helper.inlineNitroExternals(helper.resolvers.module.resolve("./runtime"));
|
|
1398
|
+
helper.inlineNitroExternals(helper.paths.moduleBuildDir);
|
|
1399
|
+
helper.inlineNitroExternals(helper.paths.moduleTypesDir);
|
|
1400
|
+
helper.addAlias("#nuxt-graphql-middleware", helper.paths.moduleBuildDir);
|
|
1401
|
+
helper.addAlias("#graphql-operations", helper.paths.moduleTypesDir);
|
|
1402
|
+
helper.addPlugin("./runtime/plugins/provideState");
|
|
1403
|
+
if (helper.isDev && helper.options.errorOverlay) {
|
|
1404
|
+
helper.addPlugin("./runtime/plugins/devMode");
|
|
1405
|
+
}
|
|
1406
|
+
helper.addServerHandler("query", "/query/:name", "get");
|
|
1407
|
+
helper.addServerHandler("mutation", "/mutation/:name", "post");
|
|
1408
|
+
if (helper.options.enableFileUploads) {
|
|
1409
|
+
helper.addServerHandler("upload", "/upload/:name", "post");
|
|
1410
|
+
}
|
|
1411
|
+
if (helper.isDev) {
|
|
1412
|
+
helper.addServerHandler("debug", "/debug", "get");
|
|
1413
|
+
}
|
|
1414
|
+
if (helper.options.includeComposables) {
|
|
1415
|
+
helper.addComposable("useGraphqlQuery");
|
|
1416
|
+
helper.addComposable("useGraphqlMutation");
|
|
1417
|
+
helper.addComposable("useGraphqlState");
|
|
1418
|
+
helper.addComposable("useAsyncGraphqlQuery");
|
|
1419
|
+
if (helper.options.enableFileUploads) {
|
|
1420
|
+
helper.addComposable("useGraphqlUploadMutation");
|
|
1421
|
+
}
|
|
1422
|
+
helper.addServerUtil("useGraphqlQuery");
|
|
1423
|
+
helper.addServerUtil("useGraphqlMutation");
|
|
1424
|
+
helper.addServerUtil("doGraphqlRequest");
|
|
1425
|
+
}
|
|
1426
|
+
TEMPLATES.forEach((template) => {
|
|
1427
|
+
if (template.type === "static") {
|
|
1428
|
+
helper.addTemplate(template);
|
|
1429
|
+
} else {
|
|
1430
|
+
collector.addTemplate(template);
|
|
1431
|
+
}
|
|
1432
|
+
});
|
|
1433
|
+
helper.applyBuildConfig();
|
|
1434
|
+
await collector.init();
|
|
1435
|
+
if (!helper.isDev) {
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
const devModeHandler = new DevModeHandler(
|
|
1439
|
+
nuxt,
|
|
1440
|
+
schemaProvider,
|
|
1441
|
+
collector,
|
|
1442
|
+
helper
|
|
1443
|
+
);
|
|
1444
|
+
devModeHandler.init();
|
|
870
1445
|
}
|
|
871
1446
|
});
|
|
872
1447
|
|