nuxt-graphql-middleware 5.0.0-alpha.9 → 5.0.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.
- package/README.md +101 -19
- package/dist/client/200.html +8 -8
- package/dist/client/404.html +8 -8
- package/dist/client/_nuxt/{CPyoLiCY.js → BM34SYth.js} +1 -1
- package/dist/client/_nuxt/CROlboVl.js +1 -0
- package/dist/client/_nuxt/D5hBL5aZ.js +25 -0
- package/dist/client/_nuxt/{BLvMh1Ga.js → FTbv7CO6.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/83f9fcd5-bd28-4608-b499-05e08fe0f7d0.json +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/{C9pb_2rp.js → lIgCBhS_.js} +2 -2
- package/dist/client/index.html +8 -8
- package/dist/client-options.d.mts +6 -0
- package/dist/client-options.mjs +5 -0
- package/dist/module.d.mts +63 -181
- package/dist/module.json +3 -3
- package/dist/module.mjs +338 -90
- package/dist/runtime/components/CodeFrame.vue +19 -28
- package/dist/runtime/components/CodeFrame.vue.d.ts +7 -0
- package/dist/runtime/components/DevModeOverlay.vue +25 -33
- package/dist/runtime/components/DevModeOverlay.vue.d.ts +3 -0
- package/dist/runtime/components/ErrorExtensions.vue +9 -11
- package/dist/runtime/components/ErrorExtensions.vue.d.ts +5 -0
- package/dist/runtime/components/ErrorGroup.vue +28 -39
- package/dist/runtime/components/ErrorGroup.vue.d.ts +9 -0
- package/dist/runtime/server/api/mutation.js +2 -1
- package/dist/runtime/server/api/query.js +2 -1
- package/dist/runtime/server/utils/doGraphqlRequest.js +5 -4
- package/dist/runtime/types.d.ts +2 -2
- package/dist/server-options.d.mts +8 -0
- package/dist/server-options.mjs +5 -0
- package/dist/shared/nuxt-graphql-middleware.cXfDI4U3.d.mts +517 -0
- package/dist/types.d.mts +1 -7
- package/dist/utils.d.mts +15 -0
- package/dist/utils.mjs +18 -0
- package/package.json +34 -30
- package/dist/client/_nuxt/CBwfSTyQ.js +0 -1
- package/dist/client/_nuxt/VpkRx2_e.js +0 -25
- package/dist/client/_nuxt/builds/meta/826a43da-d42c-4fbf-8dfd-2572141eaf8f.json +0 -1
- package/dist/client/_nuxt/error-404.BJkSn6RI.css +0 -1
- package/dist/client/_nuxt/error-500.TOCKLquH.css +0 -1
- package/dist/module.cjs +0 -5
- package/dist/module.d.ts +0 -210
- package/dist/runtime/clientOptions/index.d.ts +0 -2
- package/dist/runtime/clientOptions/index.js +0 -3
- package/dist/runtime/serverOptions/defineGraphqlServerOptions.d.ts +0 -4
- package/dist/runtime/serverOptions/defineGraphqlServerOptions.js +0 -3
- package/dist/runtime/serverOptions/index.d.ts +0 -2
- package/dist/runtime/serverOptions/index.js +0 -2
- package/dist/types.d.ts +0 -7
package/dist/module.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { fileURLToPath } from 'url';
|
|
2
|
-
import { useLogger, addTemplate, addServerTemplate, addTypeTemplate,
|
|
2
|
+
import { useLogger, addTemplate, addServerTemplate, addTypeTemplate, createResolver, resolveAlias, resolveFiles, addPlugin, addServerHandler, addImports, addServerImports, useNitro, defineNuxtModule } from '@nuxt/kit';
|
|
3
3
|
import { existsSync, promises } from 'node:fs';
|
|
4
|
-
import { relative } from 'pathe';
|
|
5
4
|
import { basename } from 'node:path';
|
|
5
|
+
import { relative, join } from 'pathe';
|
|
6
6
|
import { printSourceLocation, parse, Source, OperationTypeNode } from 'graphql';
|
|
7
7
|
import { Generator, FieldNotFoundError, TypeNotFoundError, FragmentNotFoundError } from 'graphql-typescript-deluxe';
|
|
8
8
|
import color from 'picocolors';
|
|
@@ -12,16 +12,16 @@ import { generate } from '@graphql-codegen/cli';
|
|
|
12
12
|
import * as PluginSchemaAst from '@graphql-codegen/schema-ast';
|
|
13
13
|
import { loadSchema } from '@graphql-tools/load';
|
|
14
14
|
import { defu } from 'defu';
|
|
15
|
-
import
|
|
15
|
+
import micromatch from 'micromatch';
|
|
16
16
|
import { ConfirmPrompt } from '@clack/core';
|
|
17
17
|
import isUnicodeSupported from 'is-unicode-supported';
|
|
18
18
|
import { existsSync as existsSync$1 } from 'fs';
|
|
19
19
|
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
20
20
|
|
|
21
21
|
const name = "nuxt-graphql-middleware";
|
|
22
|
-
const version = "5.0.0
|
|
22
|
+
const version = "5.0.0";
|
|
23
23
|
|
|
24
|
-
const logger = useLogger(
|
|
24
|
+
const logger = useLogger("nuxt-graphql-middleware");
|
|
25
25
|
const defaultOptions = {
|
|
26
26
|
downloadSchema: true,
|
|
27
27
|
schemaPath: "~~/schema.graphql",
|
|
@@ -119,6 +119,9 @@ class CollectedFile {
|
|
|
119
119
|
}
|
|
120
120
|
static async fromFilePath(filePath) {
|
|
121
121
|
const content = (await promises.readFile(filePath)).toString();
|
|
122
|
+
if (!content) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
122
125
|
return new CollectedFile(filePath, content, true);
|
|
123
126
|
}
|
|
124
127
|
/**
|
|
@@ -148,7 +151,10 @@ class Collector {
|
|
|
148
151
|
}
|
|
149
152
|
if (!mappedOptions.output.buildTypeDocFilePath) {
|
|
150
153
|
mappedOptions.output.buildTypeDocFilePath = (filePath) => {
|
|
151
|
-
|
|
154
|
+
if (filePath.startsWith("/")) {
|
|
155
|
+
return this.filePathToBuildRelative(filePath);
|
|
156
|
+
}
|
|
157
|
+
return filePath;
|
|
152
158
|
};
|
|
153
159
|
}
|
|
154
160
|
this.generator = new Generator(schema, mappedOptions);
|
|
@@ -157,6 +163,14 @@ class Collector {
|
|
|
157
163
|
* All collected files.
|
|
158
164
|
*/
|
|
159
165
|
files = /* @__PURE__ */ new Map();
|
|
166
|
+
/**
|
|
167
|
+
* All documents provided by hooks.
|
|
168
|
+
*/
|
|
169
|
+
hookDocuments = /* @__PURE__ */ new Map();
|
|
170
|
+
/**
|
|
171
|
+
* All file paths provided by hooks.
|
|
172
|
+
*/
|
|
173
|
+
hookFiles = /* @__PURE__ */ new Set();
|
|
160
174
|
/**
|
|
161
175
|
* The code generator.
|
|
162
176
|
*/
|
|
@@ -177,6 +191,7 @@ class Collector {
|
|
|
177
191
|
* The generated template contents.
|
|
178
192
|
*/
|
|
179
193
|
templateResult = /* @__PURE__ */ new Map();
|
|
194
|
+
isInitialised = false;
|
|
180
195
|
async reset() {
|
|
181
196
|
this.files.clear();
|
|
182
197
|
this.generator.reset();
|
|
@@ -190,10 +205,13 @@ class Collector {
|
|
|
190
205
|
await this.initDocuments();
|
|
191
206
|
}
|
|
192
207
|
filePathToBuildRelative(filePath) {
|
|
193
|
-
return "./" + this.helper.
|
|
208
|
+
return "./" + this.helper.toModuleBuildRelative(filePath);
|
|
194
209
|
}
|
|
195
210
|
filePathToSourceRelative(filePath) {
|
|
196
|
-
|
|
211
|
+
if (filePath.startsWith("/")) {
|
|
212
|
+
return "./" + relative(process.cwd(), filePath);
|
|
213
|
+
}
|
|
214
|
+
return filePath;
|
|
197
215
|
}
|
|
198
216
|
operationToLogEntry(operation, errors) {
|
|
199
217
|
return {
|
|
@@ -203,8 +221,8 @@ class Collector {
|
|
|
203
221
|
errors
|
|
204
222
|
};
|
|
205
223
|
}
|
|
206
|
-
getTemplate(template) {
|
|
207
|
-
const content = this.templateResult.get(template);
|
|
224
|
+
getTemplate(template, type) {
|
|
225
|
+
const content = this.templateResult.get(template + "-" + type);
|
|
208
226
|
if (content === void 0) {
|
|
209
227
|
throw new Error(`Missing template content: ${template}`);
|
|
210
228
|
}
|
|
@@ -213,23 +231,28 @@ class Collector {
|
|
|
213
231
|
/**
|
|
214
232
|
* Executes code gen and performs validation for operations.
|
|
215
233
|
*/
|
|
216
|
-
buildState() {
|
|
234
|
+
async buildState() {
|
|
217
235
|
const output = this.generator.build();
|
|
218
236
|
const operations = output.getCollectedOperations();
|
|
219
237
|
const generatedCode = output.getGeneratedCode();
|
|
220
238
|
this.templates.forEach((template) => {
|
|
239
|
+
const path = template.options.path;
|
|
221
240
|
if (template.build) {
|
|
222
|
-
const filename = template.options.path + ".js";
|
|
223
241
|
this.templateResult.set(
|
|
224
|
-
|
|
225
|
-
|
|
242
|
+
path + "-default",
|
|
243
|
+
this.helper.processTemplate(
|
|
244
|
+
template.options.path,
|
|
245
|
+
template.build(output, this.helper, this)
|
|
246
|
+
)
|
|
226
247
|
);
|
|
227
248
|
}
|
|
228
249
|
if (template.buildTypes) {
|
|
229
|
-
const filename = template.options.path + ".d.ts";
|
|
230
250
|
this.templateResult.set(
|
|
231
|
-
|
|
232
|
-
|
|
251
|
+
template.options.path + "-types",
|
|
252
|
+
this.helper.processTemplate(
|
|
253
|
+
template.options.path,
|
|
254
|
+
template.buildTypes(output, this.helper, this)
|
|
255
|
+
)
|
|
233
256
|
);
|
|
234
257
|
}
|
|
235
258
|
});
|
|
@@ -266,10 +289,15 @@ class Collector {
|
|
|
266
289
|
logEntries.push(this.operationToLogEntry(operation, errors));
|
|
267
290
|
}
|
|
268
291
|
}
|
|
269
|
-
logAllEntries(
|
|
292
|
+
logAllEntries(
|
|
293
|
+
logEntries.sort((a, b) => {
|
|
294
|
+
return a.type.localeCompare(b.type) || a.name.localeCompare(b.name);
|
|
295
|
+
})
|
|
296
|
+
);
|
|
270
297
|
if (hasErrors) {
|
|
271
298
|
throw new Error("GraphQL errors");
|
|
272
299
|
}
|
|
300
|
+
await this.helper.nuxt.callHook("nuxt-graphql-middleware:build", { output });
|
|
273
301
|
if (this.helper.isDev) {
|
|
274
302
|
for (const code of generatedCode) {
|
|
275
303
|
const id = `${code.identifier}_${code.graphqlName}`;
|
|
@@ -332,12 +360,32 @@ class Collector {
|
|
|
332
360
|
);
|
|
333
361
|
if (shouldRevalidate === "yes") {
|
|
334
362
|
await this.reset();
|
|
335
|
-
|
|
363
|
+
await this.init();
|
|
364
|
+
this.isInitialised = true;
|
|
365
|
+
return;
|
|
336
366
|
}
|
|
337
367
|
}
|
|
338
368
|
throw new Error("Graphql document validation failed.");
|
|
339
369
|
}
|
|
340
370
|
}
|
|
371
|
+
addHookDocument(identifier, source) {
|
|
372
|
+
this.hookDocuments.set("hook:" + identifier, source);
|
|
373
|
+
}
|
|
374
|
+
async addOrUpdateHookDocument(identifier, source) {
|
|
375
|
+
const fullIdentifier = "hook:" + identifier;
|
|
376
|
+
const exists = this.hookDocuments.has(fullIdentifier);
|
|
377
|
+
this.hookDocuments.set(fullIdentifier, source);
|
|
378
|
+
if (exists && this.isInitialised) {
|
|
379
|
+
this.generator.update({
|
|
380
|
+
filePath: fullIdentifier,
|
|
381
|
+
document: source
|
|
382
|
+
});
|
|
383
|
+
await this.buildState();
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
addHookFile(filePath) {
|
|
387
|
+
this.hookFiles.add(filePath);
|
|
388
|
+
}
|
|
341
389
|
/**
|
|
342
390
|
* Initialise the collector.
|
|
343
391
|
*/
|
|
@@ -357,7 +405,19 @@ class Collector {
|
|
|
357
405
|
documentNode: file.parsed
|
|
358
406
|
});
|
|
359
407
|
}
|
|
360
|
-
this.
|
|
408
|
+
const hookDocuments = [...this.hookDocuments.entries()];
|
|
409
|
+
hookDocuments.forEach(([identifier, source]) => {
|
|
410
|
+
const file = new CollectedFile(identifier, source, false);
|
|
411
|
+
this.files.set(identifier, file);
|
|
412
|
+
this.generator.add({
|
|
413
|
+
filePath: identifier,
|
|
414
|
+
documentNode: file.parsed
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
for (const filePath of this.hookFiles) {
|
|
418
|
+
await this.addFile(filePath);
|
|
419
|
+
}
|
|
420
|
+
await this.buildState();
|
|
361
421
|
logger.success("All GraphQL documents are valid.");
|
|
362
422
|
} catch (e) {
|
|
363
423
|
this.logError(e);
|
|
@@ -369,7 +429,7 @@ class Collector {
|
|
|
369
429
|
*/
|
|
370
430
|
async addFile(filePath) {
|
|
371
431
|
const file = await CollectedFile.fromFilePath(filePath);
|
|
372
|
-
if (!file
|
|
432
|
+
if (!file?.fileContents) {
|
|
373
433
|
return null;
|
|
374
434
|
}
|
|
375
435
|
this.files.set(filePath, file);
|
|
@@ -379,15 +439,18 @@ class Collector {
|
|
|
379
439
|
});
|
|
380
440
|
return file;
|
|
381
441
|
}
|
|
442
|
+
matchesPatternOrExists(filePath) {
|
|
443
|
+
return this.files.has(filePath) || this.hookFiles.has(filePath) || this.hookDocuments.has(filePath) || this.helper.matchesImportPattern(filePath);
|
|
444
|
+
}
|
|
382
445
|
async handleAdd(filePath) {
|
|
383
|
-
if (!this.
|
|
446
|
+
if (!this.matchesPatternOrExists(filePath)) {
|
|
384
447
|
return false;
|
|
385
448
|
}
|
|
386
449
|
const result = await this.addFile(filePath);
|
|
387
450
|
return !!result;
|
|
388
451
|
}
|
|
389
452
|
async handleChange(filePath) {
|
|
390
|
-
if (!this.
|
|
453
|
+
if (!this.matchesPatternOrExists(filePath)) {
|
|
391
454
|
return false;
|
|
392
455
|
}
|
|
393
456
|
const file = this.files.get(filePath);
|
|
@@ -446,7 +509,7 @@ class Collector {
|
|
|
446
509
|
hasChanged = this.handleUnlinkDir(filePath);
|
|
447
510
|
}
|
|
448
511
|
if (hasChanged) {
|
|
449
|
-
this.buildState();
|
|
512
|
+
await this.buildState();
|
|
450
513
|
}
|
|
451
514
|
} catch (e) {
|
|
452
515
|
this.generator.resetCaches();
|
|
@@ -478,7 +541,7 @@ class Collector {
|
|
|
478
541
|
*/
|
|
479
542
|
addVirtualTemplate(template) {
|
|
480
543
|
const filename = template.options.path + ".js";
|
|
481
|
-
const getContents = () => this.getTemplate(
|
|
544
|
+
const getContents = () => this.getTemplate(template.options.path, "default");
|
|
482
545
|
addTemplate({
|
|
483
546
|
filename,
|
|
484
547
|
getContents
|
|
@@ -503,21 +566,23 @@ class Collector {
|
|
|
503
566
|
if (template.options.virtual) {
|
|
504
567
|
this.addVirtualTemplate(template);
|
|
505
568
|
} else {
|
|
506
|
-
const
|
|
569
|
+
const path = template.options.path;
|
|
570
|
+
const filename = template.options.isFullPath ? path : path + ".js";
|
|
507
571
|
addTemplate({
|
|
508
572
|
filename,
|
|
509
573
|
write: true,
|
|
510
|
-
getContents: () => this.getTemplate(
|
|
574
|
+
getContents: () => this.getTemplate(path, "default")
|
|
511
575
|
});
|
|
512
576
|
}
|
|
513
577
|
}
|
|
514
578
|
if (template.buildTypes) {
|
|
579
|
+
const path = template.options.path;
|
|
515
580
|
const filename = template.options.path + ".d.ts";
|
|
516
581
|
addTypeTemplate(
|
|
517
582
|
{
|
|
518
583
|
filename,
|
|
519
584
|
write: true,
|
|
520
|
-
getContents: () => this.getTemplate(
|
|
585
|
+
getContents: () => this.getTemplate(path, "types")
|
|
521
586
|
},
|
|
522
587
|
{
|
|
523
588
|
nuxt: true,
|
|
@@ -526,6 +591,23 @@ class Collector {
|
|
|
526
591
|
);
|
|
527
592
|
}
|
|
528
593
|
}
|
|
594
|
+
/**
|
|
595
|
+
* Get the hook documents.
|
|
596
|
+
*/
|
|
597
|
+
getHookDocuments() {
|
|
598
|
+
return [...this.hookDocuments.entries()].map(([identifier, source]) => {
|
|
599
|
+
return {
|
|
600
|
+
identifier,
|
|
601
|
+
source
|
|
602
|
+
};
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Get the hook documents.
|
|
607
|
+
*/
|
|
608
|
+
getHookFiles() {
|
|
609
|
+
return [...this.hookFiles.values()];
|
|
610
|
+
}
|
|
529
611
|
}
|
|
530
612
|
|
|
531
613
|
class SchemaProvider {
|
|
@@ -730,7 +812,6 @@ ${color.cyan(S_BAR_END)}
|
|
|
730
812
|
class ModuleHelper {
|
|
731
813
|
constructor(nuxt, moduleUrl, options) {
|
|
732
814
|
this.nuxt = nuxt;
|
|
733
|
-
const isModuleBuild = process.env.MODULE_BUILD === "true" && nuxt.options._prepare;
|
|
734
815
|
const mergedOptions = defu({}, options, defaultOptions);
|
|
735
816
|
if (!mergedOptions.autoImportPatterns) {
|
|
736
817
|
mergedOptions.autoImportPatterns = [
|
|
@@ -738,17 +819,28 @@ class ModuleHelper {
|
|
|
738
819
|
"!node_modules"
|
|
739
820
|
];
|
|
740
821
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
"
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
822
|
+
const layerAliases = nuxt.options._layers.map((layer) => {
|
|
823
|
+
return {
|
|
824
|
+
"~~": layer.config.rootDir,
|
|
825
|
+
"@@": layer.config.rootDir,
|
|
826
|
+
"~": layer.config.srcDir,
|
|
827
|
+
"@": layer.config.srcDir,
|
|
828
|
+
// Merge any additional aliases defined by the layer.
|
|
829
|
+
// Must be last so that the layer may override the "default" aliases.
|
|
830
|
+
...layer.config.alias || {}
|
|
831
|
+
};
|
|
832
|
+
});
|
|
833
|
+
const srcResolver = createResolver(nuxt.options.srcDir);
|
|
834
|
+
const rootResolver = createResolver(nuxt.options.rootDir);
|
|
835
|
+
mergedOptions.autoImportPatterns = (mergedOptions.autoImportPatterns || []).flatMap((pattern) => {
|
|
836
|
+
if (pattern.startsWith("!") || pattern.startsWith("/")) {
|
|
837
|
+
return pattern;
|
|
838
|
+
} else if (pattern.startsWith("~") || pattern.startsWith("@")) {
|
|
839
|
+
return layerAliases.map((aliases) => resolveAlias(pattern, aliases));
|
|
840
|
+
}
|
|
841
|
+
return rootResolver.resolve(pattern);
|
|
842
|
+
}).map((pattern) => {
|
|
843
|
+
return pattern.replace(".{graphql}", ".graphql").replace(".{gql}", ".gql");
|
|
752
844
|
});
|
|
753
845
|
this.options = mergedOptions;
|
|
754
846
|
if (!nuxt.options._prepare) {
|
|
@@ -758,9 +850,9 @@ class ModuleHelper {
|
|
|
758
850
|
this.resolvers = {
|
|
759
851
|
module: createResolver(moduleUrl),
|
|
760
852
|
server: createResolver(nuxt.options.serverDir),
|
|
761
|
-
src:
|
|
853
|
+
src: srcResolver,
|
|
762
854
|
app: createResolver(nuxt.options.dir.app),
|
|
763
|
-
root:
|
|
855
|
+
root: rootResolver
|
|
764
856
|
};
|
|
765
857
|
this.paths = {
|
|
766
858
|
runtimeTypes: "",
|
|
@@ -786,6 +878,7 @@ class ModuleHelper {
|
|
|
786
878
|
options;
|
|
787
879
|
prompt = new ConsolePrompt();
|
|
788
880
|
nitroExternals = [];
|
|
881
|
+
tsPaths = {};
|
|
789
882
|
/**
|
|
790
883
|
* Find the path to the graphqlMiddleware.serverOptions.ts file.
|
|
791
884
|
*/
|
|
@@ -849,35 +942,17 @@ class ModuleHelper {
|
|
|
849
942
|
async getImportPatternFiles() {
|
|
850
943
|
return resolveFiles(
|
|
851
944
|
this.nuxt.options.srcDir,
|
|
852
|
-
this.options.autoImportPatterns
|
|
853
|
-
{
|
|
854
|
-
followSymbolicLinks: false
|
|
855
|
-
}
|
|
945
|
+
this.options.autoImportPatterns
|
|
856
946
|
);
|
|
857
947
|
}
|
|
858
948
|
matchesImportPattern(filePath) {
|
|
859
|
-
return micromatch.isMatch(filePath, this.options.autoImportPatterns);
|
|
949
|
+
return micromatch.isMatch(filePath, this.options.autoImportPatterns) || this.options.autoImportPatterns.includes(filePath);
|
|
860
950
|
}
|
|
861
951
|
addAlias(name, path) {
|
|
862
952
|
this.nuxt.options.alias[name] = path;
|
|
863
953
|
const pathFromName = `./${name.substring(1)}`;
|
|
864
|
-
this.
|
|
865
|
-
this.
|
|
866
|
-
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions ||= {};
|
|
867
|
-
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths ||= {};
|
|
868
|
-
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths[name] = [
|
|
869
|
-
pathFromName
|
|
870
|
-
];
|
|
871
|
-
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths[name + "/*"] = [pathFromName + "/*"];
|
|
872
|
-
this.nuxt.options.typescript.tsConfig ||= {};
|
|
873
|
-
this.nuxt.options.typescript.tsConfig.compilerOptions ||= {};
|
|
874
|
-
this.nuxt.options.typescript.tsConfig.compilerOptions.paths ||= {};
|
|
875
|
-
this.nuxt.options.typescript.tsConfig.compilerOptions.paths[name] = [
|
|
876
|
-
pathFromName
|
|
877
|
-
];
|
|
878
|
-
this.nuxt.options.typescript.tsConfig.compilerOptions.paths[name + "/*"] = [
|
|
879
|
-
pathFromName + "/*"
|
|
880
|
-
];
|
|
954
|
+
this.tsPaths[name] = pathFromName;
|
|
955
|
+
this.tsPaths[name + "/*"] = pathFromName + "/*";
|
|
881
956
|
this.inlineNitroExternals(name);
|
|
882
957
|
}
|
|
883
958
|
inlineNitroExternals(arg) {
|
|
@@ -892,10 +967,34 @@ class ModuleHelper {
|
|
|
892
967
|
this.nuxt.options.nitro.externals ||= {};
|
|
893
968
|
this.nuxt.options.nitro.externals.inline ||= [];
|
|
894
969
|
this.nuxt.options.nitro.externals.inline.push(...this.nitroExternals);
|
|
970
|
+
this.nuxt.options.nitro.typescript ||= {};
|
|
971
|
+
this.nuxt.options.nitro.typescript.tsConfig ||= {};
|
|
972
|
+
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions ||= {};
|
|
973
|
+
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths ||= {};
|
|
974
|
+
this.nuxt.options.typescript.tsConfig ||= {};
|
|
975
|
+
this.nuxt.options.typescript.tsConfig.compilerOptions ||= {};
|
|
976
|
+
this.nuxt.options.typescript.tsConfig.compilerOptions.paths ||= {};
|
|
977
|
+
for (const [name, path] of Object.entries(this.tsPaths)) {
|
|
978
|
+
this.nuxt.options.nitro.typescript.tsConfig.compilerOptions.paths[name] = [path];
|
|
979
|
+
this.nuxt.options.typescript.tsConfig.compilerOptions.paths[name] = [path];
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
processTemplate(path, content) {
|
|
983
|
+
if (path.includes("graphql-operations/") || path.endsWith(".graphql")) {
|
|
984
|
+
return content.trim();
|
|
985
|
+
}
|
|
986
|
+
const name = path.split("/")[1];
|
|
987
|
+
return `/*
|
|
988
|
+
* @see [Documentation](https://nuxt-graphql-middleware.dulnan.net/advanced/templates#${name})
|
|
989
|
+
*/
|
|
990
|
+
${content.trim()}`;
|
|
895
991
|
}
|
|
896
992
|
addTemplate(template) {
|
|
897
993
|
if (template.build) {
|
|
898
|
-
const content =
|
|
994
|
+
const content = this.processTemplate(
|
|
995
|
+
template.options.path,
|
|
996
|
+
template.build(this)
|
|
997
|
+
);
|
|
899
998
|
addTemplate({
|
|
900
999
|
filename: template.options.path + ".js",
|
|
901
1000
|
write: true,
|
|
@@ -903,7 +1002,10 @@ class ModuleHelper {
|
|
|
903
1002
|
});
|
|
904
1003
|
}
|
|
905
1004
|
if (template.buildTypes) {
|
|
906
|
-
const content =
|
|
1005
|
+
const content = this.processTemplate(
|
|
1006
|
+
template.options.path,
|
|
1007
|
+
template.buildTypes(this)
|
|
1008
|
+
);
|
|
907
1009
|
const filename = template.options.path + ".d.ts";
|
|
908
1010
|
addTypeTemplate({
|
|
909
1011
|
filename,
|
|
@@ -912,8 +1014,8 @@ class ModuleHelper {
|
|
|
912
1014
|
});
|
|
913
1015
|
}
|
|
914
1016
|
}
|
|
915
|
-
addPlugin(
|
|
916
|
-
addPlugin(this.resolvers.module.resolve(
|
|
1017
|
+
addPlugin(name) {
|
|
1018
|
+
addPlugin(this.resolvers.module.resolve("./runtime/plugins/" + name), {
|
|
917
1019
|
append: false
|
|
918
1020
|
});
|
|
919
1021
|
}
|
|
@@ -976,16 +1078,16 @@ export { clientOptions }
|
|
|
976
1078
|
helper.paths.clientOptions
|
|
977
1079
|
);
|
|
978
1080
|
return `import type { GraphqlClientOptions } from '${helper.paths.runtimeTypes}'
|
|
979
|
-
import
|
|
980
|
-
|
|
981
|
-
export type GraphqlClientContext = typeof clientOptions extends GraphqlClientOptions<infer R> ? R : {}
|
|
1081
|
+
import clientOptionsImport from '${pathRelative}'
|
|
982
1082
|
|
|
983
|
-
export
|
|
1083
|
+
declare export const clientOptions: GraphqlClientOptions
|
|
1084
|
+
export type GraphqlClientContext = typeof clientOptionsImport extends GraphqlClientOptions<infer R> ? R : {}
|
|
1085
|
+
`;
|
|
984
1086
|
}
|
|
985
1087
|
return `
|
|
986
1088
|
import type { GraphqlClientOptions } from '${helper.paths.runtimeTypes}'
|
|
987
|
-
export const clientOptions: GraphqlClientOptions
|
|
988
1089
|
|
|
1090
|
+
declare export const clientOptions: GraphqlClientOptions
|
|
989
1091
|
export type GraphqlClientContext = {}
|
|
990
1092
|
`;
|
|
991
1093
|
}
|
|
@@ -1027,13 +1129,25 @@ const GraphqlConfig = defineStaticTemplate(
|
|
|
1027
1129
|
const documents = patterns.filter((v) => !v.includes("!")).map((pattern) => {
|
|
1028
1130
|
return "./" + relative(configPath, helper.resolvers.root.resolve(pattern));
|
|
1029
1131
|
});
|
|
1030
|
-
|
|
1132
|
+
documents.push(
|
|
1133
|
+
"./" + relative(
|
|
1134
|
+
configPath,
|
|
1135
|
+
join(helper.paths.moduleBuildDir, "hook-documents.graphql")
|
|
1136
|
+
)
|
|
1137
|
+
);
|
|
1138
|
+
return `
|
|
1139
|
+
import { hookFiles } from './hook-files'
|
|
1140
|
+
|
|
1141
|
+
const schema = ${JSON.stringify(schemaPath)}
|
|
1031
1142
|
|
|
1032
1143
|
const documents = ${JSON.stringify(documents, null, 2)};
|
|
1033
1144
|
|
|
1034
1145
|
const config = {
|
|
1035
1146
|
schema,
|
|
1036
|
-
documents
|
|
1147
|
+
documents: [
|
|
1148
|
+
...documents,
|
|
1149
|
+
...hookFiles
|
|
1150
|
+
]
|
|
1037
1151
|
}
|
|
1038
1152
|
|
|
1039
1153
|
export default config
|
|
@@ -1133,7 +1247,7 @@ import type { GraphqlServerResponse } from '${helper.paths.runtimeTypes}'
|
|
|
1133
1247
|
|
|
1134
1248
|
declare module '#nuxt-graphql-middleware/response' {
|
|
1135
1249
|
export type GraphqlMiddlewareResponseUnion =
|
|
1136
|
-
| ${allTypes.join("\n
|
|
1250
|
+
| ${allTypes.join("\n | ") || "never"}
|
|
1137
1251
|
|
|
1138
1252
|
export type GraphqlResponse<T> = GraphqlServerResponse<T> & GraphqlResponseAdditions
|
|
1139
1253
|
export type GraphqlResponseTyped = GraphqlResponse<GraphqlMiddlewareResponseUnion>
|
|
@@ -1152,16 +1266,27 @@ export { serverOptions }
|
|
|
1152
1266
|
`;
|
|
1153
1267
|
},
|
|
1154
1268
|
(helper) => {
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1269
|
+
if (helper.paths.serverOptions) {
|
|
1270
|
+
const resolvedPathRelative = helper.toModuleBuildRelative(
|
|
1271
|
+
helper.paths.serverOptions
|
|
1272
|
+
);
|
|
1273
|
+
return `
|
|
1158
1274
|
import type { GraphqlMiddlewareServerOptions } from '${helper.paths.runtimeTypes}'
|
|
1159
|
-
${
|
|
1275
|
+
import serverOptionsImport from '${resolvedPathRelative}'
|
|
1160
1276
|
|
|
1161
1277
|
export type GraphqlResponseAdditions =
|
|
1162
|
-
typeof
|
|
1278
|
+
typeof serverOptionsImport extends GraphqlMiddlewareServerOptions<infer R, any, any> ? R : {}
|
|
1279
|
+
|
|
1280
|
+
declare export const serverOptions: GraphqlMiddlewareServerOptions
|
|
1281
|
+
`;
|
|
1282
|
+
}
|
|
1283
|
+
return `
|
|
1284
|
+
import type { GraphqlMiddlewareServerOptions } from '${helper.paths.runtimeTypes}'
|
|
1285
|
+
|
|
1286
|
+
declare export const serverOptions: GraphqlMiddlewareServerOptions
|
|
1163
1287
|
|
|
1164
|
-
export
|
|
1288
|
+
export type GraphqlResponseAdditions = object
|
|
1289
|
+
`;
|
|
1165
1290
|
}
|
|
1166
1291
|
);
|
|
1167
1292
|
|
|
@@ -1172,7 +1297,7 @@ const Sources = defineGeneratorTemplate(
|
|
|
1172
1297
|
const srcDir = helper.paths.root;
|
|
1173
1298
|
const lines = [];
|
|
1174
1299
|
for (const operation of operations) {
|
|
1175
|
-
const filePath = relative(srcDir, operation.filePath);
|
|
1300
|
+
const filePath = operation.filePath.startsWith("/") ? relative(srcDir, operation.filePath) : operation.filePath;
|
|
1176
1301
|
lines.push(
|
|
1177
1302
|
`${operation.operationType}_${operation.graphqlName}: '${filePath}',`
|
|
1178
1303
|
);
|
|
@@ -1188,6 +1313,43 @@ export const operationSources = {
|
|
|
1188
1313
|
}
|
|
1189
1314
|
);
|
|
1190
1315
|
|
|
1316
|
+
const HookDocuments = defineGeneratorTemplate(
|
|
1317
|
+
{
|
|
1318
|
+
path: "nuxt-graphql-middleware/hook-documents.graphql",
|
|
1319
|
+
virtual: false,
|
|
1320
|
+
isFullPath: true
|
|
1321
|
+
},
|
|
1322
|
+
(_output, _helper, collector) => {
|
|
1323
|
+
return collector.getHookDocuments().map((v) => {
|
|
1324
|
+
return `
|
|
1325
|
+
# ${v.identifier}
|
|
1326
|
+
${v.source}
|
|
1327
|
+
`;
|
|
1328
|
+
}).join("\n\n");
|
|
1329
|
+
},
|
|
1330
|
+
null
|
|
1331
|
+
);
|
|
1332
|
+
|
|
1333
|
+
const HookFiles = defineGeneratorTemplate(
|
|
1334
|
+
{
|
|
1335
|
+
path: "nuxt-graphql-middleware/hook-files",
|
|
1336
|
+
virtual: false
|
|
1337
|
+
},
|
|
1338
|
+
(_output, helper, collector) => {
|
|
1339
|
+
const configPath = helper.resolvers.root.resolve(
|
|
1340
|
+
(helper.options.graphqlConfigFilePath || "").replace(
|
|
1341
|
+
"/graphql.config.ts",
|
|
1342
|
+
""
|
|
1343
|
+
)
|
|
1344
|
+
);
|
|
1345
|
+
const files = collector.getHookFiles().map((filePath) => {
|
|
1346
|
+
return "./" + relative(configPath, filePath);
|
|
1347
|
+
});
|
|
1348
|
+
return `export const hookFiles = ${JSON.stringify(files, null, 2)}`;
|
|
1349
|
+
},
|
|
1350
|
+
null
|
|
1351
|
+
);
|
|
1352
|
+
|
|
1191
1353
|
const TEMPLATES = [
|
|
1192
1354
|
ClientOptions,
|
|
1193
1355
|
Documents,
|
|
@@ -1198,7 +1360,9 @@ const TEMPLATES = [
|
|
|
1198
1360
|
Operations,
|
|
1199
1361
|
Response,
|
|
1200
1362
|
ServerOptions,
|
|
1201
|
-
Sources
|
|
1363
|
+
Sources,
|
|
1364
|
+
HookDocuments,
|
|
1365
|
+
HookFiles
|
|
1202
1366
|
];
|
|
1203
1367
|
|
|
1204
1368
|
const DEVTOOLS_UI_ROUTE = "/__nuxt-graphql-middleware";
|
|
@@ -1284,11 +1448,12 @@ class DevModeHandler {
|
|
|
1284
1448
|
this.nitro = useNitro();
|
|
1285
1449
|
this.nitro.hooks.hook("compiled", this.onNitroCompiled.bind(this));
|
|
1286
1450
|
}
|
|
1287
|
-
async onBuilderWatch(event,
|
|
1288
|
-
if (
|
|
1451
|
+
async onBuilderWatch(event, providedFilePath) {
|
|
1452
|
+
if (!providedFilePath.endsWith(".graphql") && !providedFilePath.endsWith(".gql")) {
|
|
1289
1453
|
return;
|
|
1290
1454
|
}
|
|
1291
|
-
|
|
1455
|
+
const pathAbsolute = providedFilePath.startsWith("/") ? providedFilePath : this.helper.resolvers.src.resolve(providedFilePath);
|
|
1456
|
+
if (pathAbsolute === this.helper.paths.schema) {
|
|
1292
1457
|
return;
|
|
1293
1458
|
}
|
|
1294
1459
|
this.helper.prompt.abort();
|
|
@@ -1363,6 +1528,84 @@ class DevModeHandler {
|
|
|
1363
1528
|
}
|
|
1364
1529
|
}
|
|
1365
1530
|
|
|
1531
|
+
class ModuleContext {
|
|
1532
|
+
constructor(schemaProvider, collector) {
|
|
1533
|
+
this.schemaProvider = schemaProvider;
|
|
1534
|
+
this.collector = collector;
|
|
1535
|
+
}
|
|
1536
|
+
/**
|
|
1537
|
+
* Return the GraphQL schema.
|
|
1538
|
+
*
|
|
1539
|
+
* Note that the schema may be updated during development, so it can become
|
|
1540
|
+
* stale. Prefer using methods like `schemaHasType()` to query the schema.
|
|
1541
|
+
*
|
|
1542
|
+
* @returns The GraphQL schema.
|
|
1543
|
+
*/
|
|
1544
|
+
getSchema() {
|
|
1545
|
+
return this.schemaProvider.getSchema();
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Check if the given GraphQL type (interface, concrete type, enum, input type)
|
|
1549
|
+
* exists in the schema.
|
|
1550
|
+
*
|
|
1551
|
+
* @param name - The name of the type.
|
|
1552
|
+
*
|
|
1553
|
+
* @returns True if the type exists in the schema.
|
|
1554
|
+
*/
|
|
1555
|
+
schemaHasType(name) {
|
|
1556
|
+
return !!this.schemaProvider.getSchema().getType(name);
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Get a type from the schema.
|
|
1560
|
+
*
|
|
1561
|
+
* @param name - The name of the type.
|
|
1562
|
+
*
|
|
1563
|
+
* @returns The type.
|
|
1564
|
+
*/
|
|
1565
|
+
schemaGetType(name) {
|
|
1566
|
+
return this.schemaProvider.getSchema().getType(name);
|
|
1567
|
+
}
|
|
1568
|
+
/**
|
|
1569
|
+
* Add an additional static document.
|
|
1570
|
+
*
|
|
1571
|
+
* @param identifier - The unique identifier for your document.
|
|
1572
|
+
* @param source - The document source.
|
|
1573
|
+
*/
|
|
1574
|
+
addDocument(identifier, source) {
|
|
1575
|
+
this.collector.addHookDocument(identifier, source);
|
|
1576
|
+
return this;
|
|
1577
|
+
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Add or update an additional static document.
|
|
1580
|
+
*
|
|
1581
|
+
* @param identifier - The unique identifier for your document.
|
|
1582
|
+
* @param source - The document source.
|
|
1583
|
+
*/
|
|
1584
|
+
async addOrUpdateDocument(identifier, source) {
|
|
1585
|
+
await this.collector.addOrUpdateHookDocument(identifier, source);
|
|
1586
|
+
return this;
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* Add an additional GraphQL file to import.
|
|
1590
|
+
*
|
|
1591
|
+
* @param filePath - The absolute path to the file.
|
|
1592
|
+
*/
|
|
1593
|
+
addImportFile(filePath) {
|
|
1594
|
+
if (!filePath.startsWith("/")) {
|
|
1595
|
+
throw new Error(
|
|
1596
|
+
`The provided file path "${filePath}" must be an absolute path.`
|
|
1597
|
+
);
|
|
1598
|
+
}
|
|
1599
|
+
if (!filePath.endsWith(".graphql") && !filePath.endsWith(".gql")) {
|
|
1600
|
+
throw new Error(
|
|
1601
|
+
`The provided file path "${filePath}" should have a .graphql or .gql extension.`
|
|
1602
|
+
);
|
|
1603
|
+
}
|
|
1604
|
+
this.collector.addHookFile(filePath);
|
|
1605
|
+
return this;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1366
1609
|
const module = defineNuxtModule({
|
|
1367
1610
|
meta: {
|
|
1368
1611
|
name,
|
|
@@ -1378,6 +1621,8 @@ const module = defineNuxtModule({
|
|
|
1378
1621
|
const schemaProvider = new SchemaProvider(helper);
|
|
1379
1622
|
await schemaProvider.init();
|
|
1380
1623
|
const collector = new Collector(schemaProvider.getSchema(), helper);
|
|
1624
|
+
const moduleContext = new ModuleContext(schemaProvider, collector);
|
|
1625
|
+
nuxt._nuxt_graphql_middleware = moduleContext;
|
|
1381
1626
|
nuxt.options.appConfig.graphqlMiddleware = {
|
|
1382
1627
|
clientCacheEnabled: !!helper.options.clientCache?.enabled,
|
|
1383
1628
|
clientCacheMaxSize: helper.options.clientCache?.maxSize ?? 100
|
|
@@ -1391,9 +1636,9 @@ const module = defineNuxtModule({
|
|
|
1391
1636
|
helper.inlineNitroExternals(helper.paths.moduleTypesDir);
|
|
1392
1637
|
helper.addAlias("#nuxt-graphql-middleware", helper.paths.moduleBuildDir);
|
|
1393
1638
|
helper.addAlias("#graphql-operations", helper.paths.moduleTypesDir);
|
|
1394
|
-
helper.addPlugin("
|
|
1639
|
+
helper.addPlugin("provideState");
|
|
1395
1640
|
if (helper.isDev && helper.options.errorOverlay) {
|
|
1396
|
-
helper.addPlugin("
|
|
1641
|
+
helper.addPlugin("devMode");
|
|
1397
1642
|
}
|
|
1398
1643
|
helper.addServerHandler("query", "/query/:name", "get");
|
|
1399
1644
|
helper.addServerHandler("mutation", "/mutation/:name", "post");
|
|
@@ -1423,7 +1668,10 @@ const module = defineNuxtModule({
|
|
|
1423
1668
|
}
|
|
1424
1669
|
});
|
|
1425
1670
|
helper.applyBuildConfig();
|
|
1426
|
-
|
|
1671
|
+
nuxt.hooks.hookOnce("modules:done", async () => {
|
|
1672
|
+
await nuxt.hooks.callHook("nuxt-graphql-middleware:init", moduleContext);
|
|
1673
|
+
await collector.init();
|
|
1674
|
+
});
|
|
1427
1675
|
if (!helper.isDev) {
|
|
1428
1676
|
return;
|
|
1429
1677
|
}
|