nuxt-graphql-middleware 4.0.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +10 -2
  2. package/dist/client/200.html +10 -12
  3. package/dist/client/404.html +10 -12
  4. package/dist/client/_nuxt/Bk31qVW4.js +1 -0
  5. package/dist/client/_nuxt/CHM3Rz8p.js +1 -0
  6. package/dist/client/_nuxt/CUKk0hSk.js +24 -0
  7. package/dist/client/_nuxt/Ca6k-hEN.js +2 -0
  8. package/dist/client/_nuxt/KmIjpfWJ.js +1 -0
  9. package/dist/client/_nuxt/builds/latest.json +1 -1
  10. package/dist/client/_nuxt/builds/meta/42e92f16-7f29-4b6f-8e46-68076031ade3.json +1 -0
  11. package/dist/client/_nuxt/entry.BMcZ91J5.css +1 -0
  12. package/dist/client/_nuxt/error-404.CjTTbIxB.css +1 -0
  13. package/dist/client/_nuxt/error-500.B4KzowuE.css +1 -0
  14. package/dist/client/_nuxt/index.DCCKx2Zk.css +1 -0
  15. package/dist/client/index.html +10 -12
  16. package/dist/module.d.mts +71 -10
  17. package/dist/module.d.ts +71 -10
  18. package/dist/module.json +6 -2
  19. package/dist/module.mjs +283 -179
  20. package/dist/runtime/composables/nuxtApp.d.ts +9 -4
  21. package/dist/runtime/composables/nuxtApp.js +47 -0
  22. package/dist/runtime/composables/server.d.ts +4 -3
  23. package/dist/runtime/composables/{server.mjs → server.js} +2 -2
  24. package/dist/runtime/composables/shared.d.ts +12 -7
  25. package/dist/runtime/composables/useAsyncGraphqlQuery.d.ts +22 -0
  26. package/dist/runtime/composables/useAsyncGraphqlQuery.js +43 -0
  27. package/dist/runtime/composables/useGraphqlMutation.d.ts +3 -2
  28. package/dist/runtime/composables/{useGraphqlMutation.mjs → useGraphqlMutation.js} +2 -2
  29. package/dist/runtime/composables/useGraphqlQuery.d.ts +3 -2
  30. package/dist/runtime/composables/useGraphqlQuery.js +20 -0
  31. package/dist/runtime/composables/useGraphqlState.d.ts +1 -1
  32. package/dist/runtime/composables/{useGraphqlState.mjs → useGraphqlState.js} +1 -1
  33. package/dist/runtime/composables/useGraphqlUploadMutation.d.ts +7 -0
  34. package/dist/runtime/composables/useGraphqlUploadMutation.js +57 -0
  35. package/dist/runtime/helpers/ClientCache.d.ts +15 -0
  36. package/dist/runtime/helpers/ClientCache.js +40 -0
  37. package/dist/runtime/helpers/{index.mjs → index.js} +1 -1
  38. package/dist/runtime/plugins/provideState.d.ts +1 -1
  39. package/dist/runtime/plugins/provideState.js +17 -0
  40. package/dist/runtime/serverHandler/helpers/index.d.ts +5 -3
  41. package/dist/runtime/serverHandler/helpers/{index.mjs → index.js} +2 -2
  42. package/dist/runtime/serverHandler/{index.mjs → index.js} +3 -3
  43. package/dist/runtime/serverHandler/upload.d.ts +2 -0
  44. package/dist/runtime/serverHandler/upload.js +101 -0
  45. package/dist/runtime/serverOptions/defineGraphqlServerOptions.d.ts +2 -2
  46. package/dist/runtime/serverOptions/index.d.ts +1 -1
  47. package/dist/runtime/serverOptions/{index.mjs → index.js} +1 -1
  48. package/dist/runtime/types.d.ts +24 -0
  49. package/dist/runtime/types.js +0 -0
  50. package/dist/types.d.mts +2 -9
  51. package/dist/types.d.ts +2 -9
  52. package/package.json +43 -32
  53. package/dist/client/_nuxt/_plugin-vue_export-helper.x3n3nnut.js +0 -1
  54. package/dist/client/_nuxt/builds/meta/71f1ba68-6be9-464d-87d1-1b4b3ac786b2.json +0 -1
  55. package/dist/client/_nuxt/entry.N5CnhLMX.css +0 -1
  56. package/dist/client/_nuxt/entry.sn4ItzJP.js +0 -29
  57. package/dist/client/_nuxt/error-404._g063Njv.js +0 -1
  58. package/dist/client/_nuxt/error-404.gOl2ep2B.css +0 -1
  59. package/dist/client/_nuxt/error-500.iP22ayZD.js +0 -1
  60. package/dist/client/_nuxt/error-500.z8GAN5B3.css +0 -1
  61. package/dist/client/_nuxt/index.KH5Eug0w.css +0 -1
  62. package/dist/client/_nuxt/index.wowlKkKL.js +0 -2
  63. package/dist/client/_nuxt/vue.f36acd1f.H09MX4qF.js +0 -1
  64. package/dist/runtime/composables/nuxtApp.mjs +0 -15
  65. package/dist/runtime/composables/useGraphqlQuery.mjs +0 -9
  66. package/dist/runtime/plugins/provideState.mjs +0 -7
  67. /package/dist/runtime/composables/{shared.mjs → shared.js} +0 -0
  68. /package/dist/runtime/serverHandler/{debug.mjs → debug.js} +0 -0
  69. /package/dist/runtime/serverOptions/{defineGraphqlServerOptions.mjs → defineGraphqlServerOptions.js} +0 -0
  70. /package/dist/runtime/settings/{index.mjs → index.js} +0 -0
package/dist/module.mjs CHANGED
@@ -1,26 +1,27 @@
1
1
  import { fileURLToPath } from 'url';
2
- import { resolve } from 'pathe';
2
+ import { dirname, resolve, relative } from 'pathe';
3
3
  import { defu } from 'defu';
4
4
  import { useLogger, resolveAlias, resolveFiles, defineNuxtModule, createResolver, addImports, addTemplate, addServerHandler, addPlugin, updateTemplates } from '@nuxt/kit';
5
5
  import inquirer from 'inquirer';
6
6
  import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
7
7
  import { existsSync } from 'fs';
8
+ import { GraphqlMiddlewareTemplate } from '../dist/runtime/settings/index.js';
9
+ import * as fs from 'node:fs';
8
10
  import { promises, existsSync as existsSync$1 } from 'node:fs';
9
11
  import { oldVisit } from '@graphql-codegen/plugin-helpers';
10
- import fragmentImport from '@graphql-fragment-import/lib/inline-imports.js';
11
12
  import { validateGraphQlDocuments } from '@graphql-tools/utils';
12
13
  import { loadSchema } from '@graphql-tools/load';
13
- import Table from 'cli-table';
14
- import chalk from 'chalk';
15
14
  import { concatAST, parse, print, visit, Kind, Source } from 'graphql';
15
+ import { falsy } from '../dist/runtime/helpers/index.js';
16
16
  import { generate as generate$1, executeCodegen } from '@graphql-codegen/cli';
17
17
  import * as PluginTypescript from '@graphql-codegen/typescript';
18
18
  import * as PluginTypescriptOperations from '@graphql-codegen/typescript-operations';
19
19
  import * as PluginSchemaAst from '@graphql-codegen/schema-ast';
20
20
  import { pascalCase } from 'change-case-all';
21
+ import colors from 'picocolors';
21
22
 
22
23
  const name = "nuxt-graphql-middleware";
23
- const version = "4.0.0";
24
+ const version = "4.1.1";
24
25
 
25
26
  const DEVTOOLS_UI_ROUTE = "/__nuxt-graphql-middleware";
26
27
  const DEVTOOLS_UI_LOCAL_PORT = 3300;
@@ -63,19 +64,102 @@ function setupDevToolsUI(nuxt, clientPath) {
63
64
  });
64
65
  }
65
66
 
66
- var GraphqlMiddlewareTemplate = /* @__PURE__ */ ((GraphqlMiddlewareTemplate2) => {
67
- GraphqlMiddlewareTemplate2["OperationTypes"] = "graphql-operations.d.ts";
68
- GraphqlMiddlewareTemplate2["ComposableContext"] = "nuxt-graphql-middleware.d.ts";
69
- GraphqlMiddlewareTemplate2["Documents"] = "graphql-documents.mjs";
70
- return GraphqlMiddlewareTemplate2;
71
- })(GraphqlMiddlewareTemplate || {});
67
+ const importSyntaxRE = /^#import (?:'([^']*)'|"([^"]*)")/;
68
+ const matchImport = (value = "") => {
69
+ if (!value) {
70
+ return void 0;
71
+ }
72
+ if (value.indexOf("#import") !== 0) {
73
+ return void 0;
74
+ }
75
+ const matched = value.match(importSyntaxRE);
76
+ if (matched === null) {
77
+ return void 0;
78
+ }
79
+ const importIdentifierMatch = value.match(importSyntaxRE) || [];
80
+ const importIdentifier = importIdentifierMatch[1] ?? importIdentifierMatch[2];
81
+ if (importIdentifier === void 0) {
82
+ return void 0;
83
+ }
84
+ return { importIdentifier };
85
+ };
72
86
 
73
- function falsy(value) {
74
- return value !== null && value !== void 0;
87
+ const lineEndingRE = /\r\n|\n/;
88
+ function* linesWithInlinedImportsOf(fileContents, inlineImportsOptions, visited) {
89
+ const {
90
+ resolveOptions = {},
91
+ resolveImport,
92
+ fs: nodeFs = fs,
93
+ throwIfImportNotFound
94
+ } = inlineImportsOptions;
95
+ const { basedir } = resolveOptions;
96
+ if (typeof basedir !== "string") {
97
+ throw new TypeError(
98
+ "inlineImports requires options.resolverOptions.basedir be set"
99
+ );
100
+ }
101
+ if (!resolveImport) {
102
+ throw new TypeError("inlineImports requires options.resolveImport be set");
103
+ }
104
+ let lineNumber = 0;
105
+ for (const line of fileContents.split(lineEndingRE)) {
106
+ ++lineNumber;
107
+ const matched = matchImport(line);
108
+ if (matched) {
109
+ const importIdentifier = matched.importIdentifier;
110
+ let filename;
111
+ try {
112
+ filename = resolveImport(importIdentifier, resolveOptions);
113
+ } catch (err) {
114
+ if (throwIfImportNotFound === false) {
115
+ continue;
116
+ }
117
+ throw err;
118
+ }
119
+ if (visited.has(filename)) {
120
+ continue;
121
+ } else {
122
+ visited.add(filename);
123
+ }
124
+ const fragmentSource = nodeFs.readFileSync(filename, "utf8");
125
+ const line2 = inlineImportsWithLineToImports(
126
+ fragmentSource,
127
+ {
128
+ resolveImport,
129
+ resolveOptions: {
130
+ basedir: dirname(filename)
131
+ }
132
+ },
133
+ visited
134
+ );
135
+ yield { line: line2.inlineImports, match: true, lineNumber, filename };
136
+ } else {
137
+ yield { line, match: false, lineNumber };
138
+ }
139
+ }
140
+ }
141
+ function inlineImportsWithLineToImports(fileContents, options, visited = /* @__PURE__ */ new Set()) {
142
+ const inlineImportsResult = [];
143
+ const lineToImports = /* @__PURE__ */ new Map();
144
+ for (const { line, match, lineNumber, filename } of linesWithInlinedImportsOf(
145
+ fileContents,
146
+ options,
147
+ visited
148
+ )) {
149
+ inlineImportsResult.push(line);
150
+ if (match) {
151
+ lineToImports.set(lineNumber, { filename, line });
152
+ }
153
+ }
154
+ return {
155
+ inlineImports: inlineImportsResult.join("\n"),
156
+ lineToImports
157
+ };
75
158
  }
76
159
 
77
160
  function getCodeResult(operations, typeName, serverApiPrefix) {
78
161
  const imports = [];
162
+ const resultTypes = [];
79
163
  let code = "";
80
164
  let nitroCode = "";
81
165
  const names = Object.keys(operations);
@@ -84,6 +168,7 @@ function getCodeResult(operations, typeName, serverApiPrefix) {
84
168
  const nitroLines = [];
85
169
  names.forEach((name) => {
86
170
  const nameResult = pascalCase(name + typeName);
171
+ resultTypes.push(nameResult);
87
172
  imports.push(nameResult);
88
173
  const nameVariables = pascalCase(name + typeName + "Variables");
89
174
  const { hasVariables, variablesOptional } = operations[name];
@@ -95,7 +180,9 @@ function getCodeResult(operations, typeName, serverApiPrefix) {
95
180
  ` ${name}: [${variablesType}, ${variablesOptional ? "true" : "false"}, ${nameResult}]`
96
181
  );
97
182
  nitroLines.push(
98
- ` '${serverApiPrefix}/${typeName.toLowerCase()}/${name}': GraphqlMiddlewareResponse<Awaited<${nameResult}>>`
183
+ ` '${serverApiPrefix}/${typeName.toLowerCase()}/${name}': {
184
+ 'default': GraphqlResponse<${nameResult}>
185
+ }`
99
186
  );
100
187
  });
101
188
  code += ` export type GraphqlMiddleware${typeName} = {
@@ -104,7 +191,7 @@ ${lines.join(",\n")}
104
191
  `;
105
192
  nitroCode += `${nitroLines.join("\n")}`;
106
193
  }
107
- return { code, imports, nitroCode };
194
+ return { code, imports, nitroCode, resultTypes };
108
195
  }
109
196
  const plugin$1 = (_schema, documents, config) => {
110
197
  const allAst = concatAST(documents.map((v) => v.document).filter(falsy));
@@ -129,6 +216,7 @@ const plugin$1 = (_schema, documents, config) => {
129
216
  let code = "";
130
217
  let nitroCode = "";
131
218
  const imports = [];
219
+ const resultTypes = [];
132
220
  const resultQuery = getCodeResult(
133
221
  operations.query,
134
222
  "Query",
@@ -137,6 +225,7 @@ const plugin$1 = (_schema, documents, config) => {
137
225
  code += resultQuery.code;
138
226
  nitroCode += resultQuery.nitroCode;
139
227
  imports.push(...resultQuery.imports);
228
+ resultTypes.push(...resultQuery.resultTypes);
140
229
  const resultMutation = getCodeResult(
141
230
  operations.mutation,
142
231
  "Mutation",
@@ -145,21 +234,20 @@ const plugin$1 = (_schema, documents, config) => {
145
234
  code += "\n" + resultMutation.code;
146
235
  nitroCode += "\n" + resultMutation.nitroCode;
147
236
  imports.push(...resultMutation.imports);
148
- return `import {
237
+ resultTypes.push(...resultMutation.resultTypes);
238
+ return `
239
+ import type { GraphqlResponse } from '#graphql-middleware-server-options-build'
240
+ import type {
149
241
  ${imports.join(",\n ")}
150
242
  } from './graphql-operations'
151
243
 
152
244
 
153
- type GraphqlMiddlewareResponse<T> = {
154
- data: T
155
- }
156
-
157
245
  declare module '#build/nuxt-graphql-middleware' {
246
+ export type GraphqlMiddlewareResponseUnion = ${resultTypes.join(" | ")}
158
247
  ${code}
159
248
  }
160
249
 
161
250
  declare module 'nitropack' {
162
- type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T
163
251
  interface InternalApi {
164
252
  ${nitroCode}
165
253
  }
@@ -256,6 +344,48 @@ function generateTemplates(documents, schemaPath, options) {
256
344
  });
257
345
  }
258
346
 
347
+ function getMaxLengths(documents) {
348
+ let longestOperation = 0;
349
+ let longestName = 0;
350
+ let longestPath = 0;
351
+ for (const { operation, name, relativePath } of documents) {
352
+ if (operation && operation.length > longestOperation) {
353
+ longestOperation = operation.length;
354
+ }
355
+ if (name && name.length > longestName) {
356
+ longestName = name.length;
357
+ }
358
+ if (relativePath && relativePath.length > longestPath) {
359
+ longestPath = relativePath.length;
360
+ }
361
+ }
362
+ return { longestOperation, longestName, longestPath };
363
+ }
364
+ function logDocuments(logger, documents, logEverything) {
365
+ const { longestOperation, longestName, longestPath } = getMaxLengths(documents);
366
+ logger.log(colors.green("GraphQL Document Validation"));
367
+ for (const { operation, name, relativePath, isValid, errors } of documents) {
368
+ if (logEverything || !isValid) {
369
+ let log = "";
370
+ log += (operation || "").padEnd(longestOperation + 2);
371
+ log += colors.cyan((name || "").padEnd(longestName + 2));
372
+ log += colors.dim((relativePath || "").padEnd(longestPath + 2));
373
+ log += isValid ? colors.green("\u2713") : colors.red("x");
374
+ if (!isValid && errors) {
375
+ log += "\n" + errors.map((error) => colors.red(error)).join("\n");
376
+ }
377
+ logger.log(log);
378
+ }
379
+ }
380
+ process.stdout.write("\n");
381
+ logger.restoreStd();
382
+ if (documents.some((v) => !v.isValid)) {
383
+ logger.error("GraphQL document validation failed with errors.");
384
+ } else {
385
+ logger.success("GraphQL document validation completed successfully.");
386
+ }
387
+ }
388
+
259
389
  const logger = useLogger("nuxt-graphql-middleware");
260
390
  const defaultOptions = {
261
391
  codegenConfig: {
@@ -276,115 +406,22 @@ const defaultOptions = {
276
406
  debug: false,
277
407
  includeComposables: true,
278
408
  documents: [],
279
- autoImportPatterns: [],
280
409
  devtools: true
281
410
  };
282
411
  function inlineFragments(source, resolver) {
283
- return fragmentImport(source, {
412
+ return inlineImportsWithLineToImports(source, {
284
413
  resolveImport(identifier) {
285
414
  return resolver(identifier);
286
415
  },
287
416
  resolveOptions: {
288
417
  basedir: "./"
289
418
  }
290
- });
291
- }
292
- function validateDeprecated(options) {
293
- const deprecatedKeys = [
294
- "graphqlEndpoint",
295
- "serverFetchOptions",
296
- "onServerResponse",
297
- "onServerError"
298
- ];
299
- deprecatedKeys.forEach((key) => {
300
- if (typeof options[key] === "function") {
301
- logger.error(
302
- `Providing a function for "${key}" via nuxt.config.ts has been removed. Please move the configuration to ~/app/graphqlMiddleware.serverOptions.ts.`
303
- );
304
- if (key === "graphqlEndpoint") {
305
- logger.info(`
306
- import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/dist/runtime/serverOptions'
307
- import { getHeader } from 'h3'
308
- import acceptLanguageParser from 'accept-language-parser';
309
-
310
- export default defineGraphqlServerOptions({
311
- graphqlEndpoint(event, operation, operationName) {
312
- // Get accepted languages.
313
- const acceptLanguage = getHeader('accept-language')
314
- const languages = acceptLanguageParser.parse(acceptLanguage);
315
-
316
- // Use first match or fallback to English.
317
- const language = languages[0]?.code || 'en'
318
- return \`https://api.example.com/\${language}/graphql\`
319
- }
320
- })`);
321
- }
322
- if (key === "serverFetchOptions") {
323
- logger.info(`
324
- import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/dist/runtime/serverOptions'
325
- import { getHeader } from 'h3'
326
-
327
- // Pass the cookie from the client request to the GraphQL request.
328
- export default defineGraphqlServerOptions({
329
- serverFetchOptions(event, operation, operationName) {
330
- return {
331
- headers: {
332
- Cookie: getHeader(event, 'cookie')
333
- }
334
- }
335
- }
336
- })`);
337
- }
338
- if (key === "onServerResponse") {
339
- logger.info(`
340
- import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/dist/runtime/serverOptions'
341
- import type { H3Event } from 'h3'
342
- import type { FetchResponse } from 'ofetch'
343
-
344
- export default defineGraphqlServerOptions({
345
- onServerResponse(event, graphqlResponse) {
346
- // Set a static header.
347
- event.node.res.setHeader('x-nuxt-custom-header', 'A custom header value')
348
-
349
- // Pass the set-cookie header from the GraphQL response to the client.
350
- const setCookie = graphqlResponse.headers.get('set-cookie')
351
- if (setCookie) {
352
- event.node.res.setHeader('set-cookie', setCookie)
353
- }
354
-
355
- // Add additional properties to the response.
356
- graphqlResponse._data.__customProperty = ['My', 'values']
357
-
358
- // Return the GraphQL response.
359
- return graphqlResponse._data
360
- }
361
- })`);
362
- }
363
- if (key === "onServerError") {
364
- logger.info(`
365
- import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/dist/runtime/serverOptions'
366
- import type { H3Event } from 'h3'
367
- import type { FetchError } from 'ofetch'
368
-
369
- export default defineGraphqlServerOptions({
370
- onServerError( event, error, operation, operationName) {
371
- event.setHeader('cache-control', 'no-cache')
372
- return {
373
- data: {},
374
- errors: [error.message]
375
- }
376
- }
377
- })`);
378
- }
379
- throw new TypeError("Invalid configuration for graphqlMiddleware." + key);
380
- }
381
- });
419
+ }).inlineImports;
382
420
  }
383
421
  function validateOptions(options) {
384
422
  if (!options.graphqlEndpoint) {
385
423
  throw new Error("Missing graphqlEndpoint.");
386
424
  }
387
- validateDeprecated(options);
388
425
  }
389
426
  async function getSchemaPath(options, resolver, writeToDisk = false) {
390
427
  const dest = resolver(options.schemaPath);
@@ -425,19 +462,49 @@ async function autoImportDocuments(patterns = [], srcResolver) {
425
462
  })
426
463
  );
427
464
  }
428
- function buildDocuments(providedDocuments = [], autoImportPatterns, resolver) {
429
- return autoImportDocuments(autoImportPatterns, resolver).then((importedDocuments) => {
430
- return [
431
- ...importedDocuments,
432
- ...providedDocuments.map((content) => {
433
- return {
434
- content,
435
- filename: "nuxt.config.ts"
436
- };
437
- })
438
- ].filter((v) => v.content);
439
- }).then((documents) => {
440
- return documents.map((v) => {
465
+ function inlineNestedFragments(document, fragmentMap) {
466
+ const parsed = parse(document);
467
+ const fragmentsToInline = /* @__PURE__ */ new Set();
468
+ visit(parsed, {
469
+ FragmentSpread(node) {
470
+ fragmentsToInline.add(node.name.value);
471
+ }
472
+ });
473
+ fragmentsToInline.forEach((fragmentName) => {
474
+ const fragment = fragmentMap[fragmentName];
475
+ if (fragment) {
476
+ document += "\n" + fragment;
477
+ const nestedFragmentNames = /* @__PURE__ */ new Set();
478
+ visit(parse(fragment), {
479
+ FragmentSpread(node) {
480
+ nestedFragmentNames.add(node.name.value);
481
+ }
482
+ });
483
+ nestedFragmentNames.forEach((nestedFragmentName) => {
484
+ if (!fragmentsToInline.has(nestedFragmentName)) {
485
+ fragmentsToInline.add(nestedFragmentName);
486
+ const nestedFragment = fragmentMap[nestedFragmentName];
487
+ if (nestedFragment) {
488
+ document += "\n" + nestedFragment;
489
+ }
490
+ }
491
+ });
492
+ }
493
+ });
494
+ return document;
495
+ }
496
+ async function buildDocuments(providedDocuments = [], autoImportPatterns, resolver, autoInlineFragments) {
497
+ const documents = await autoImportDocuments(autoImportPatterns, resolver).then((importedDocuments) => [
498
+ ...importedDocuments,
499
+ ...providedDocuments.map((content) => ({
500
+ content,
501
+ filename: "nuxt.config.ts"
502
+ }))
503
+ ]).then((documents2) => {
504
+ if (autoInlineFragments) {
505
+ return documents2;
506
+ }
507
+ return documents2.map((v) => {
441
508
  try {
442
509
  return {
443
510
  content: inlineFragments(v.content, resolveAlias),
@@ -452,6 +519,22 @@ function buildDocuments(providedDocuments = [], autoImportPatterns, resolver) {
452
519
  return null;
453
520
  }).filter(falsy);
454
521
  });
522
+ if (!autoInlineFragments) {
523
+ return documents;
524
+ }
525
+ const fragmentMap = {};
526
+ documents.forEach((doc) => {
527
+ const parsed = parse(doc.content);
528
+ visit(parsed, {
529
+ FragmentDefinition(node) {
530
+ fragmentMap[node.name.value] = print(node);
531
+ }
532
+ });
533
+ });
534
+ documents.forEach((doc) => {
535
+ doc.content = inlineNestedFragments(doc.content, fragmentMap);
536
+ });
537
+ return documents;
455
538
  }
456
539
  function parseDocument(document, srcDir) {
457
540
  let name = document.filename ? document.filename.replace(srcDir, "") : "";
@@ -481,9 +564,6 @@ function validateDocuments(schema, documents, srcDir) {
481
564
  document.name = operation.name?.value;
482
565
  document.operation = operation.operation;
483
566
  } else {
484
- const fragment = node.definitions.find(
485
- (v) => v.kind === "FragmentDefinition"
486
- );
487
567
  document.name = document.relativePath;
488
568
  }
489
569
  document.isValid = document.errors.length === 0;
@@ -552,7 +632,8 @@ async function generate(options, schemaPath, resolver, srcDir, logEverything = f
552
632
  const documents = await buildDocuments(
553
633
  options.documents,
554
634
  options.autoImportPatterns,
555
- resolver
635
+ resolver,
636
+ !!options.autoInlineFragments
556
637
  );
557
638
  const validated = validateDocuments(schema, documents, srcDir);
558
639
  const extracted = validated.filter(
@@ -606,27 +687,7 @@ async function generate(options, schemaPath, resolver, srcDir, logEverything = f
606
687
  );
607
688
  const hasErrors = extracted.some((v) => !v.isValid) || validated.some((v) => !v.isValid);
608
689
  if (hasErrors || logEverything) {
609
- const table = new Table({
610
- head: ["Operation", "Name", "File", "Errors"].map((v) => chalk.white(v))
611
- });
612
- extracted.forEach((document) => {
613
- if (logEverything || !document.isValid) {
614
- table.push(
615
- [
616
- document.operation || "",
617
- document.name || "",
618
- document.relativePath || "",
619
- document.errors?.join("\n\n") || ""
620
- ].map((v) => {
621
- if (document.isValid) {
622
- return v;
623
- }
624
- return chalk.red(v);
625
- })
626
- );
627
- }
628
- });
629
- logger.log("GraphQL code generation table:\n" + table.toString());
690
+ logDocuments(logger, extracted, logEverything);
630
691
  }
631
692
  process.stdout.write("\n");
632
693
  logger.restoreStd();
@@ -672,7 +733,7 @@ const module = defineNuxtModule({
672
733
  configKey: "graphqlMiddleware",
673
734
  version,
674
735
  compatibility: {
675
- nuxt: "^3.1.0"
736
+ nuxt: ">=3.1.0"
676
737
  }
677
738
  },
678
739
  defaults: defaultOptions,
@@ -682,7 +743,7 @@ const module = defineNuxtModule({
682
743
  options.autoImportPatterns = ["**/*.{gql,graphql}", "!node_modules"];
683
744
  }
684
745
  validateOptions(options);
685
- const moduleResolver = createResolver(import.meta.url).resolve;
746
+ const moduleResolver = createResolver(import.meta.url);
686
747
  const srcDir = nuxt.options.srcDir;
687
748
  const srcResolver = createResolver(srcDir).resolve;
688
749
  const schemaPath = await getSchemaPath(
@@ -698,7 +759,7 @@ const module = defineNuxtModule({
698
759
  };
699
760
  let rpc = null;
700
761
  if (options.devtools) {
701
- const clientPath = moduleResolver("./client");
762
+ const clientPath = moduleResolver.resolve("./client");
702
763
  setupDevToolsUI(nuxt, clientPath);
703
764
  const setupRpc = () => {
704
765
  rpc = extendServerRpc(RPC_NAMESPACE, {
@@ -780,25 +841,45 @@ const module = defineNuxtModule({
780
841
  nuxt.options.runtimeConfig.public["nuxt-graphql-middleware"] = {
781
842
  serverApiPrefix: options.serverApiPrefix
782
843
  };
844
+ nuxt.options.appConfig.graphqlMiddleware = {
845
+ clientCacheEnabled: !!options.clientCache?.enabled,
846
+ clientCacheMaxSize: options.clientCache?.maxSize || 100
847
+ };
783
848
  nuxt.options.runtimeConfig.graphqlMiddleware = {
784
849
  graphqlEndpoint: options.graphqlEndpoint || ""
785
850
  };
786
851
  if (options.includeComposables) {
787
852
  addImports({
788
- from: moduleResolver("./runtime/composables/useGraphqlQuery"),
853
+ from: moduleResolver.resolve("./runtime/composables/useGraphqlQuery"),
789
854
  name: "useGraphqlQuery"
790
855
  });
791
856
  addImports({
792
- from: moduleResolver("./runtime/composables/useGraphqlMutation"),
857
+ from: moduleResolver.resolve(
858
+ "./runtime/composables/useGraphqlMutation"
859
+ ),
793
860
  name: "useGraphqlMutation"
794
861
  });
795
862
  addImports({
796
- from: moduleResolver("./runtime/composables/useGraphqlState"),
863
+ from: moduleResolver.resolve("./runtime/composables/useGraphqlState"),
797
864
  name: "useGraphqlState"
798
865
  });
799
- nuxt.options.alias["#graphql-composable"] = moduleResolver(
866
+ addImports({
867
+ from: moduleResolver.resolve(
868
+ "./runtime/composables/useAsyncGraphqlQuery"
869
+ ),
870
+ name: "useAsyncGraphqlQuery"
871
+ });
872
+ nuxt.options.alias["#graphql-composable"] = moduleResolver.resolve(
800
873
  "runtime/composables/server"
801
874
  );
875
+ if (options.enableFileUploads) {
876
+ addImports({
877
+ from: moduleResolver.resolve(
878
+ "./runtime/composables/useGraphqlUploadMutation"
879
+ ),
880
+ name: "useGraphqlUploadMutation"
881
+ });
882
+ }
802
883
  }
803
884
  Object.values(GraphqlMiddlewareTemplate).forEach((filename) => {
804
885
  const result = addTemplate({
@@ -822,18 +903,18 @@ const module = defineNuxtModule({
822
903
  filename: "graphql-documents.d.ts",
823
904
  getContents: () => {
824
905
  return `
825
- import {
826
- GraphqlMiddlerwareQuery,
906
+ import type {
907
+ GraphqlMiddlewareQuery,
827
908
  GraphqlMiddlewareMutation,
828
909
  } from '#build/nuxt-graphql-middleware'
829
910
 
830
911
  declare module '#graphql-documents' {
831
912
  type Documents = {
832
- query: GraphqlMiddlerwareQuery
833
- mutation: GraphqlMiddlerwareMutation
913
+ query: GraphqlMiddlewareQuery
914
+ mutation: GraphqlMiddlewareMutation
834
915
  }
835
916
  const documents: Documents
836
- export { documents }
917
+ export { documents, Documents }
837
918
  }
838
919
  `;
839
920
  }
@@ -843,45 +924,68 @@ declare module '#graphql-documents' {
843
924
  const template = (() => {
844
925
  const resolvedFilename = `graphqlMiddleware.serverOptions.ts`;
845
926
  const maybeUserFile = fileExists(resolvedPath, extensions);
846
- if (maybeUserFile) {
847
- return addTemplate({
848
- filename: resolvedFilename,
849
- write: true,
850
- getContents: () => `export { default } from '${resolvedPath}'`
851
- });
852
- }
927
+ const moduleTypesPath = relative(
928
+ nuxt.options.buildDir,
929
+ moduleResolver.resolve("./types")
930
+ );
931
+ const serverOptionsLine = maybeUserFile ? `import serverOptions from './../app/graphqlMiddleware.serverOptions'` : `const serverOptions: GraphqlMiddlewareServerOptions = {}`;
853
932
  return addTemplate({
854
933
  filename: resolvedFilename,
855
934
  write: true,
856
- getContents: () => "export default {}"
935
+ getContents: () => `
936
+ import type { GraphqlMiddlewareServerOptions } from '${moduleTypesPath}'
937
+ ${serverOptionsLine}
938
+ import type { GraphqlServerResponse } from '#graphql-middleware/types'
939
+ import type { GraphqlMiddlewareResponseUnion } from '#build/nuxt-graphql-middleware'
940
+
941
+ type GraphqlResponseAdditions =
942
+ typeof serverOptions extends GraphqlMiddlewareServerOptions<infer R> ? R : {}
943
+
944
+ export type GraphqlResponse<T> = GraphqlServerResponse<T> & GraphqlResponseAdditions
945
+
946
+ export type GraphqlResponseTyped = GraphqlResponse<GraphqlMiddlewareResponseUnion>
947
+
948
+ export { serverOptions }
949
+ `
857
950
  });
858
951
  })();
859
952
  nuxt.options.nitro.externals = nuxt.options.nitro.externals || {};
860
953
  nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [];
861
954
  nuxt.options.nitro.externals.inline.push(template.dst);
862
955
  nuxt.options.alias["#graphql-middleware-server-options-build"] = template.dst;
956
+ nuxt.options.alias["#graphql-middleware/types"] = moduleResolver.resolve("./runtime/types");
863
957
  addServerHandler({
864
- handler: moduleResolver("./runtime/serverHandler/index"),
958
+ handler: moduleResolver.resolve("./runtime/serverHandler/index"),
865
959
  route: options.serverApiPrefix + "/:operation/:name"
866
960
  });
867
- addPlugin(moduleResolver("./runtime/plugins/provideState"), {
961
+ if (options.enableFileUploads) {
962
+ addServerHandler({
963
+ handler: moduleResolver.resolve("./runtime/serverHandler/upload"),
964
+ route: options.serverApiPrefix + "/upload/:name"
965
+ });
966
+ }
967
+ addPlugin(moduleResolver.resolve("./runtime/plugins/provideState"), {
868
968
  append: false
869
969
  });
870
970
  nuxt.hook("nitro:config", (nitroConfig) => {
871
971
  nitroConfig.externals = defu(
872
972
  typeof nitroConfig.externals === "object" ? nitroConfig.externals : {},
873
973
  {
874
- inline: [moduleResolver("./runtime")]
974
+ inline: [moduleResolver.resolve("./runtime")]
875
975
  }
876
976
  );
877
977
  });
878
- if (nuxt.options.dev) {
978
+ if (nuxt.options.dev || nuxt.options._prepare) {
879
979
  addServerHandler({
880
- handler: moduleResolver("./runtime/serverHandler/debug"),
980
+ handler: moduleResolver.resolve("./runtime/serverHandler/debug"),
881
981
  route: options.serverApiPrefix + "/debug"
882
982
  });
883
983
  nuxt.hook("nitro:build:before", (nitro) => {
884
984
  nuxt.hook("builder:watch", async (_event, path) => {
985
+ path = relative(
986
+ nuxt.options.srcDir,
987
+ resolve(nuxt.options.srcDir, path)
988
+ );
885
989
  if (!path.match(/\.(gql|graphql)$/)) {
886
990
  return;
887
991
  }