nuxt-graphql-middleware 4.0.0-beta.9 → 4.1.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.
Files changed (69) hide show
  1. package/README.md +10 -2
  2. package/dist/client/200.html +10 -16
  3. package/dist/client/404.html +10 -16
  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 -0
  10. package/dist/client/_nuxt/builds/meta/debd7d31-13de-43c8-a23f-9d618b1b6aee.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 -16
  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 +241 -156
  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 +6 -4
  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 -8
  51. package/dist/types.d.ts +2 -8
  52. package/package.json +50 -36
  53. package/dist/client/_nuxt/_plugin-vue_export-helper.c27b6911.js +0 -1
  54. package/dist/client/_nuxt/entry.1bc811cf.css +0 -1
  55. package/dist/client/_nuxt/entry.ea5ff097.js +0 -7
  56. package/dist/client/_nuxt/error-404.0c27f143.js +0 -1
  57. package/dist/client/_nuxt/error-404.a6f724cc.css +0 -1
  58. package/dist/client/_nuxt/error-500.0ea30584.js +0 -1
  59. package/dist/client/_nuxt/error-500.d92554dd.css +0 -1
  60. package/dist/client/_nuxt/index.3f9296a3.css +0 -1
  61. package/dist/client/_nuxt/index.e982558e.js +0 -2
  62. package/dist/client/_nuxt/vue.f36acd1f.b03bdbb5.js +0 -1
  63. package/dist/runtime/composables/nuxtApp.mjs +0 -15
  64. package/dist/runtime/composables/useGraphqlQuery.mjs +0 -9
  65. package/dist/runtime/plugins/provideState.mjs +0 -7
  66. /package/dist/runtime/composables/{shared.mjs → shared.js} +0 -0
  67. /package/dist/runtime/serverHandler/{debug.mjs → debug.js} +0 -0
  68. /package/dist/runtime/serverOptions/{defineGraphqlServerOptions.mjs → defineGraphqlServerOptions.js} +0 -0
  69. /package/dist/runtime/settings/{index.mjs → index.js} +0 -0
package/dist/module.mjs CHANGED
@@ -1,18 +1,20 @@
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
14
  import Table from 'cli-table';
14
15
  import chalk from 'chalk';
15
16
  import { concatAST, parse, print, visit, Kind, Source } from 'graphql';
17
+ import { falsy } from '../dist/runtime/helpers/index.js';
16
18
  import { generate as generate$1, executeCodegen } from '@graphql-codegen/cli';
17
19
  import * as PluginTypescript from '@graphql-codegen/typescript';
18
20
  import * as PluginTypescriptOperations from '@graphql-codegen/typescript-operations';
@@ -20,7 +22,7 @@ import * as PluginSchemaAst from '@graphql-codegen/schema-ast';
20
22
  import { pascalCase } from 'change-case-all';
21
23
 
22
24
  const name = "nuxt-graphql-middleware";
23
- const version = "4.0.0-beta.9";
25
+ const version = "4.1.0";
24
26
 
25
27
  const DEVTOOLS_UI_ROUTE = "/__nuxt-graphql-middleware";
26
28
  const DEVTOOLS_UI_LOCAL_PORT = 3300;
@@ -63,19 +65,102 @@ function setupDevToolsUI(nuxt, clientPath) {
63
65
  });
64
66
  }
65
67
 
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 || {});
68
+ const importSyntaxRE = /^#import (?:'([^']*)'|"([^"]*)")/;
69
+ const matchImport = (value = "") => {
70
+ if (!value) {
71
+ return void 0;
72
+ }
73
+ if (value.indexOf("#import") !== 0) {
74
+ return void 0;
75
+ }
76
+ const matched = value.match(importSyntaxRE);
77
+ if (matched === null) {
78
+ return void 0;
79
+ }
80
+ const importIdentifierMatch = value.match(importSyntaxRE) || [];
81
+ const importIdentifier = importIdentifierMatch[1] ?? importIdentifierMatch[2];
82
+ if (importIdentifier === void 0) {
83
+ return void 0;
84
+ }
85
+ return { importIdentifier };
86
+ };
72
87
 
73
- function falsy(value) {
74
- return value !== null && value !== void 0;
88
+ const lineEndingRE = /\r\n|\n/;
89
+ function* linesWithInlinedImportsOf(fileContents, inlineImportsOptions, visited) {
90
+ const {
91
+ resolveOptions = {},
92
+ resolveImport,
93
+ fs: nodeFs = fs,
94
+ throwIfImportNotFound
95
+ } = inlineImportsOptions;
96
+ const { basedir } = resolveOptions;
97
+ if (typeof basedir !== "string") {
98
+ throw new TypeError(
99
+ "inlineImports requires options.resolverOptions.basedir be set"
100
+ );
101
+ }
102
+ if (!resolveImport) {
103
+ throw new TypeError("inlineImports requires options.resolveImport be set");
104
+ }
105
+ let lineNumber = 0;
106
+ for (const line of fileContents.split(lineEndingRE)) {
107
+ ++lineNumber;
108
+ const matched = matchImport(line);
109
+ if (matched) {
110
+ const importIdentifier = matched.importIdentifier;
111
+ let filename;
112
+ try {
113
+ filename = resolveImport(importIdentifier, resolveOptions);
114
+ } catch (err) {
115
+ if (throwIfImportNotFound === false) {
116
+ continue;
117
+ }
118
+ throw err;
119
+ }
120
+ if (visited.has(filename)) {
121
+ continue;
122
+ } else {
123
+ visited.add(filename);
124
+ }
125
+ const fragmentSource = nodeFs.readFileSync(filename, "utf8");
126
+ const line2 = inlineImportsWithLineToImports(
127
+ fragmentSource,
128
+ {
129
+ resolveImport,
130
+ resolveOptions: {
131
+ basedir: dirname(filename)
132
+ }
133
+ },
134
+ visited
135
+ );
136
+ yield { line: line2.inlineImports, match: true, lineNumber, filename };
137
+ } else {
138
+ yield { line, match: false, lineNumber };
139
+ }
140
+ }
141
+ }
142
+ function inlineImportsWithLineToImports(fileContents, options, visited = /* @__PURE__ */ new Set()) {
143
+ const inlineImportsResult = [];
144
+ const lineToImports = /* @__PURE__ */ new Map();
145
+ for (const { line, match, lineNumber, filename } of linesWithInlinedImportsOf(
146
+ fileContents,
147
+ options,
148
+ visited
149
+ )) {
150
+ inlineImportsResult.push(line);
151
+ if (match) {
152
+ lineToImports.set(lineNumber, { filename, line });
153
+ }
154
+ }
155
+ return {
156
+ inlineImports: inlineImportsResult.join("\n"),
157
+ lineToImports
158
+ };
75
159
  }
76
160
 
77
161
  function getCodeResult(operations, typeName, serverApiPrefix) {
78
162
  const imports = [];
163
+ const resultTypes = [];
79
164
  let code = "";
80
165
  let nitroCode = "";
81
166
  const names = Object.keys(operations);
@@ -84,6 +169,7 @@ function getCodeResult(operations, typeName, serverApiPrefix) {
84
169
  const nitroLines = [];
85
170
  names.forEach((name) => {
86
171
  const nameResult = pascalCase(name + typeName);
172
+ resultTypes.push(nameResult);
87
173
  imports.push(nameResult);
88
174
  const nameVariables = pascalCase(name + typeName + "Variables");
89
175
  const { hasVariables, variablesOptional } = operations[name];
@@ -95,7 +181,9 @@ function getCodeResult(operations, typeName, serverApiPrefix) {
95
181
  ` ${name}: [${variablesType}, ${variablesOptional ? "true" : "false"}, ${nameResult}]`
96
182
  );
97
183
  nitroLines.push(
98
- ` '${serverApiPrefix}/${typeName.toLowerCase()}/${name}': GraphqlMiddlewareResponse<Awaited<${nameResult}>>`
184
+ ` '${serverApiPrefix}/${typeName.toLowerCase()}/${name}': {
185
+ 'default': GraphqlResponse<${nameResult}>
186
+ }`
99
187
  );
100
188
  });
101
189
  code += ` export type GraphqlMiddleware${typeName} = {
@@ -104,7 +192,7 @@ ${lines.join(",\n")}
104
192
  `;
105
193
  nitroCode += `${nitroLines.join("\n")}`;
106
194
  }
107
- return { code, imports, nitroCode };
195
+ return { code, imports, nitroCode, resultTypes };
108
196
  }
109
197
  const plugin$1 = (_schema, documents, config) => {
110
198
  const allAst = concatAST(documents.map((v) => v.document).filter(falsy));
@@ -129,6 +217,7 @@ const plugin$1 = (_schema, documents, config) => {
129
217
  let code = "";
130
218
  let nitroCode = "";
131
219
  const imports = [];
220
+ const resultTypes = [];
132
221
  const resultQuery = getCodeResult(
133
222
  operations.query,
134
223
  "Query",
@@ -137,6 +226,7 @@ const plugin$1 = (_schema, documents, config) => {
137
226
  code += resultQuery.code;
138
227
  nitroCode += resultQuery.nitroCode;
139
228
  imports.push(...resultQuery.imports);
229
+ resultTypes.push(...resultQuery.resultTypes);
140
230
  const resultMutation = getCodeResult(
141
231
  operations.mutation,
142
232
  "Mutation",
@@ -145,21 +235,20 @@ const plugin$1 = (_schema, documents, config) => {
145
235
  code += "\n" + resultMutation.code;
146
236
  nitroCode += "\n" + resultMutation.nitroCode;
147
237
  imports.push(...resultMutation.imports);
148
- return `import {
238
+ resultTypes.push(...resultMutation.resultTypes);
239
+ return `
240
+ import type { GraphqlResponse } from '#graphql-middleware-server-options-build'
241
+ import type {
149
242
  ${imports.join(",\n ")}
150
243
  } from './graphql-operations'
151
244
 
152
245
 
153
- type GraphqlMiddlewareResponse<T> = {
154
- data: T
155
- }
156
-
157
246
  declare module '#build/nuxt-graphql-middleware' {
247
+ export type GraphqlMiddlewareResponseUnion = ${resultTypes.join(" | ")}
158
248
  ${code}
159
249
  }
160
250
 
161
251
  declare module 'nitropack' {
162
- type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T
163
252
  interface InternalApi {
164
253
  ${nitroCode}
165
254
  }
@@ -280,111 +369,19 @@ const defaultOptions = {
280
369
  devtools: true
281
370
  };
282
371
  function inlineFragments(source, resolver) {
283
- return fragmentImport(source, {
372
+ return inlineImportsWithLineToImports(source, {
284
373
  resolveImport(identifier) {
285
374
  return resolver(identifier);
286
375
  },
287
376
  resolveOptions: {
288
377
  basedir: "./"
289
378
  }
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
- });
379
+ }).inlineImports;
382
380
  }
383
381
  function validateOptions(options) {
384
382
  if (!options.graphqlEndpoint) {
385
383
  throw new Error("Missing graphqlEndpoint.");
386
384
  }
387
- validateDeprecated(options);
388
385
  }
389
386
  async function getSchemaPath(options, resolver, writeToDisk = false) {
390
387
  const dest = resolver(options.schemaPath);
@@ -425,25 +422,56 @@ async function autoImportDocuments(patterns = [], srcResolver) {
425
422
  })
426
423
  );
427
424
  }
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) => {
425
+ function inlineNestedFragments(document, fragmentMap) {
426
+ const parsed = parse(document);
427
+ const fragmentsToInline = /* @__PURE__ */ new Set();
428
+ visit(parsed, {
429
+ FragmentSpread(node) {
430
+ fragmentsToInline.add(node.name.value);
431
+ }
432
+ });
433
+ fragmentsToInline.forEach((fragmentName) => {
434
+ const fragment = fragmentMap[fragmentName];
435
+ if (fragment) {
436
+ document += "\n" + fragment;
437
+ const nestedFragmentNames = /* @__PURE__ */ new Set();
438
+ visit(parse(fragment), {
439
+ FragmentSpread(node) {
440
+ nestedFragmentNames.add(node.name.value);
441
+ }
442
+ });
443
+ nestedFragmentNames.forEach((nestedFragmentName) => {
444
+ if (!fragmentsToInline.has(nestedFragmentName)) {
445
+ fragmentsToInline.add(nestedFragmentName);
446
+ const nestedFragment = fragmentMap[nestedFragmentName];
447
+ if (nestedFragment) {
448
+ document += "\n" + nestedFragment;
449
+ }
450
+ }
451
+ });
452
+ }
453
+ });
454
+ return document;
455
+ }
456
+ async function buildDocuments(providedDocuments = [], autoImportPatterns, resolver, autoInlineFragments) {
457
+ const documents = await autoImportDocuments(autoImportPatterns, resolver).then((importedDocuments) => [
458
+ ...importedDocuments,
459
+ ...providedDocuments.map((content) => ({
460
+ content,
461
+ filename: "nuxt.config.ts"
462
+ }))
463
+ ]).then((documents2) => {
464
+ if (autoInlineFragments) {
465
+ return documents2;
466
+ }
467
+ return documents2.map((v) => {
441
468
  try {
442
469
  return {
443
470
  content: inlineFragments(v.content, resolveAlias),
444
471
  filename: v.filename
445
472
  };
446
473
  } catch (e) {
474
+ logger.error(e);
447
475
  logger.error(
448
476
  "Failed to inline fragments for document: " + v.filename
449
477
  );
@@ -451,6 +479,22 @@ function buildDocuments(providedDocuments = [], autoImportPatterns, resolver) {
451
479
  return null;
452
480
  }).filter(falsy);
453
481
  });
482
+ if (!autoInlineFragments) {
483
+ return documents;
484
+ }
485
+ const fragmentMap = {};
486
+ documents.forEach((doc) => {
487
+ const parsed = parse(doc.content);
488
+ visit(parsed, {
489
+ FragmentDefinition(node) {
490
+ fragmentMap[node.name.value] = print(node);
491
+ }
492
+ });
493
+ });
494
+ documents.forEach((doc) => {
495
+ doc.content = inlineNestedFragments(doc.content, fragmentMap);
496
+ });
497
+ return documents;
454
498
  }
455
499
  function parseDocument(document, srcDir) {
456
500
  let name = document.filename ? document.filename.replace(srcDir, "") : "";
@@ -480,9 +524,6 @@ function validateDocuments(schema, documents, srcDir) {
480
524
  document.name = operation.name?.value;
481
525
  document.operation = operation.operation;
482
526
  } else {
483
- const fragment = node.definitions.find(
484
- (v) => v.kind === "FragmentDefinition"
485
- );
486
527
  document.name = document.relativePath;
487
528
  }
488
529
  document.isValid = document.errors.length === 0;
@@ -551,7 +592,8 @@ async function generate(options, schemaPath, resolver, srcDir, logEverything = f
551
592
  const documents = await buildDocuments(
552
593
  options.documents,
553
594
  options.autoImportPatterns,
554
- resolver
595
+ resolver,
596
+ !!options.autoInlineFragments
555
597
  );
556
598
  const validated = validateDocuments(schema, documents, srcDir);
557
599
  const extracted = validated.filter(
@@ -625,7 +667,7 @@ async function generate(options, schemaPath, resolver, srcDir, logEverything = f
625
667
  );
626
668
  }
627
669
  });
628
- logger.log(table.toString());
670
+ logger.log("GraphQL code generation table:\n" + table.toString());
629
671
  }
630
672
  process.stdout.write("\n");
631
673
  logger.restoreStd();
@@ -671,7 +713,7 @@ const module = defineNuxtModule({
671
713
  configKey: "graphqlMiddleware",
672
714
  version,
673
715
  compatibility: {
674
- nuxt: "^3.1.0"
716
+ nuxt: ">=3.1.0"
675
717
  }
676
718
  },
677
719
  defaults: defaultOptions,
@@ -681,7 +723,7 @@ const module = defineNuxtModule({
681
723
  options.autoImportPatterns = ["**/*.{gql,graphql}", "!node_modules"];
682
724
  }
683
725
  validateOptions(options);
684
- const moduleResolver = createResolver(import.meta.url).resolve;
726
+ const moduleResolver = createResolver(import.meta.url);
685
727
  const srcDir = nuxt.options.srcDir;
686
728
  const srcResolver = createResolver(srcDir).resolve;
687
729
  const schemaPath = await getSchemaPath(
@@ -697,7 +739,7 @@ const module = defineNuxtModule({
697
739
  };
698
740
  let rpc = null;
699
741
  if (options.devtools) {
700
- const clientPath = moduleResolver("./client");
742
+ const clientPath = moduleResolver.resolve("./client");
701
743
  setupDevToolsUI(nuxt, clientPath);
702
744
  const setupRpc = () => {
703
745
  rpc = extendServerRpc(RPC_NAMESPACE, {
@@ -779,25 +821,45 @@ const module = defineNuxtModule({
779
821
  nuxt.options.runtimeConfig.public["nuxt-graphql-middleware"] = {
780
822
  serverApiPrefix: options.serverApiPrefix
781
823
  };
824
+ nuxt.options.appConfig.graphqlMiddleware = {
825
+ clientCacheEnabled: !!options.clientCache?.enabled,
826
+ clientCacheMaxSize: options.clientCache?.maxSize || 100
827
+ };
782
828
  nuxt.options.runtimeConfig.graphqlMiddleware = {
783
829
  graphqlEndpoint: options.graphqlEndpoint || ""
784
830
  };
785
831
  if (options.includeComposables) {
786
832
  addImports({
787
- from: moduleResolver("./runtime/composables/useGraphqlQuery"),
833
+ from: moduleResolver.resolve("./runtime/composables/useGraphqlQuery"),
788
834
  name: "useGraphqlQuery"
789
835
  });
790
836
  addImports({
791
- from: moduleResolver("./runtime/composables/useGraphqlMutation"),
837
+ from: moduleResolver.resolve(
838
+ "./runtime/composables/useGraphqlMutation"
839
+ ),
792
840
  name: "useGraphqlMutation"
793
841
  });
794
842
  addImports({
795
- from: moduleResolver("./runtime/composables/useGraphqlState"),
843
+ from: moduleResolver.resolve("./runtime/composables/useGraphqlState"),
796
844
  name: "useGraphqlState"
797
845
  });
798
- nuxt.options.alias["#graphql-composable"] = moduleResolver(
846
+ addImports({
847
+ from: moduleResolver.resolve(
848
+ "./runtime/composables/useAsyncGraphqlQuery"
849
+ ),
850
+ name: "useAsyncGraphqlQuery"
851
+ });
852
+ nuxt.options.alias["#graphql-composable"] = moduleResolver.resolve(
799
853
  "runtime/composables/server"
800
854
  );
855
+ if (options.enableFileUploads) {
856
+ addImports({
857
+ from: moduleResolver.resolve(
858
+ "./runtime/composables/useGraphqlUploadMutation"
859
+ ),
860
+ name: "useGraphqlUploadMutation"
861
+ });
862
+ }
801
863
  }
802
864
  Object.values(GraphqlMiddlewareTemplate).forEach((filename) => {
803
865
  const result = addTemplate({
@@ -821,18 +883,18 @@ const module = defineNuxtModule({
821
883
  filename: "graphql-documents.d.ts",
822
884
  getContents: () => {
823
885
  return `
824
- import {
825
- GraphqlMiddlerwareQuery,
886
+ import type {
887
+ GraphqlMiddlewareQuery,
826
888
  GraphqlMiddlewareMutation,
827
889
  } from '#build/nuxt-graphql-middleware'
828
890
 
829
891
  declare module '#graphql-documents' {
830
892
  type Documents = {
831
- query: GraphqlMiddlerwareQuery
832
- mutation: GraphqlMiddlerwareMutation
893
+ query: GraphqlMiddlewareQuery
894
+ mutation: GraphqlMiddlewareMutation
833
895
  }
834
896
  const documents: Documents
835
- export { documents }
897
+ export { documents, Documents }
836
898
  }
837
899
  `;
838
900
  }
@@ -842,45 +904,68 @@ declare module '#graphql-documents' {
842
904
  const template = (() => {
843
905
  const resolvedFilename = `graphqlMiddleware.serverOptions.ts`;
844
906
  const maybeUserFile = fileExists(resolvedPath, extensions);
845
- if (maybeUserFile) {
846
- return addTemplate({
847
- filename: resolvedFilename,
848
- write: true,
849
- getContents: () => `export { default } from '${resolvedPath}'`
850
- });
851
- }
907
+ const moduleTypesPath = relative(
908
+ nuxt.options.buildDir,
909
+ moduleResolver.resolve("./types")
910
+ );
911
+ const serverOptionsLine = maybeUserFile ? `import serverOptions from './../app/graphqlMiddleware.serverOptions'` : `const serverOptions: GraphqlMiddlewareServerOptions = {}`;
852
912
  return addTemplate({
853
913
  filename: resolvedFilename,
854
914
  write: true,
855
- getContents: () => "export default {}"
915
+ getContents: () => `
916
+ import type { GraphqlMiddlewareServerOptions } from '${moduleTypesPath}'
917
+ ${serverOptionsLine}
918
+ import type { GraphqlServerResponse } from '#graphql-middleware/types'
919
+ import type { GraphqlMiddlewareResponseUnion } from '#build/nuxt-graphql-middleware'
920
+
921
+ type GraphqlResponseAdditions =
922
+ typeof serverOptions extends GraphqlMiddlewareServerOptions<infer R> ? R : {}
923
+
924
+ export type GraphqlResponse<T> = GraphqlServerResponse<T> & GraphqlResponseAdditions
925
+
926
+ export type GraphqlResponseTyped = GraphqlResponse<GraphqlMiddlewareResponseUnion>
927
+
928
+ export { serverOptions }
929
+ `
856
930
  });
857
931
  })();
858
932
  nuxt.options.nitro.externals = nuxt.options.nitro.externals || {};
859
933
  nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [];
860
934
  nuxt.options.nitro.externals.inline.push(template.dst);
861
935
  nuxt.options.alias["#graphql-middleware-server-options-build"] = template.dst;
936
+ nuxt.options.alias["#graphql-middleware/types"] = moduleResolver.resolve("./runtime/types");
862
937
  addServerHandler({
863
- handler: moduleResolver("./runtime/serverHandler/index"),
938
+ handler: moduleResolver.resolve("./runtime/serverHandler/index"),
864
939
  route: options.serverApiPrefix + "/:operation/:name"
865
940
  });
866
- addPlugin(moduleResolver("./runtime/plugins/provideState"), {
941
+ if (options.enableFileUploads) {
942
+ addServerHandler({
943
+ handler: moduleResolver.resolve("./runtime/serverHandler/upload"),
944
+ route: options.serverApiPrefix + "/upload/:name"
945
+ });
946
+ }
947
+ addPlugin(moduleResolver.resolve("./runtime/plugins/provideState"), {
867
948
  append: false
868
949
  });
869
950
  nuxt.hook("nitro:config", (nitroConfig) => {
870
951
  nitroConfig.externals = defu(
871
952
  typeof nitroConfig.externals === "object" ? nitroConfig.externals : {},
872
953
  {
873
- inline: [moduleResolver("./runtime")]
954
+ inline: [moduleResolver.resolve("./runtime")]
874
955
  }
875
956
  );
876
957
  });
877
- if (nuxt.options.dev) {
958
+ if (nuxt.options.dev || nuxt.options._prepare) {
878
959
  addServerHandler({
879
- handler: moduleResolver("./runtime/serverHandler/debug"),
960
+ handler: moduleResolver.resolve("./runtime/serverHandler/debug"),
880
961
  route: options.serverApiPrefix + "/debug"
881
962
  });
882
963
  nuxt.hook("nitro:build:before", (nitro) => {
883
964
  nuxt.hook("builder:watch", async (_event, path) => {
965
+ path = relative(
966
+ nuxt.options.srcDir,
967
+ resolve(nuxt.options.srcDir, path)
968
+ );
884
969
  if (!path.match(/\.(gql|graphql)$/)) {
885
970
  return;
886
971
  }
@@ -1,5 +1,10 @@
1
1
  import type { FetchOptions } from 'ofetch';
2
- export declare function performRequest(operation: string, operationName: string, method: 'get' | 'post', options: FetchOptions): Promise<{
3
- data: any;
4
- errors: any[];
5
- }>;
2
+ import { GraphqlMiddlewareCache } from '../helpers/ClientCache.js';
3
+ import type { GraphqlResponse } from '#graphql-middleware-server-options-build';
4
+ import type { RequestCacheOptions } from '#graphql-middleware/types';
5
+ export declare function performRequest<T>(operation: string, operationName: string, method: 'get' | 'post', options: FetchOptions, cacheOptions?: RequestCacheOptions): Promise<GraphqlResponse<T>>;
6
+ declare module '#app' {
7
+ interface NuxtApp {
8
+ $graphqlCache?: GraphqlMiddlewareCache;
9
+ }
10
+ }
@@ -0,0 +1,47 @@
1
+ import { useGraphqlState } from "./useGraphqlState.js";
2
+ import { getEndpoint } from "./shared.js";
3
+ import { hash } from "ohash";
4
+ import { GraphqlMiddlewareCache } from "../helpers/ClientCache.js";
5
+ import { useNuxtApp, useAppConfig } from "#imports";
6
+ export function performRequest(operation, operationName, method, options, cacheOptions) {
7
+ const state = useGraphqlState();
8
+ const app = useNuxtApp();
9
+ if (!state) {
10
+ console.error(
11
+ `A GraphQL composable for ${operation} "${operationName}" was called before the "nuxt-graphql-middleware-provide-state" plugin could provide the state, which might lead to unexpected behaviour. Make sure that custom plugins that perform GraphQL requests are executed after "nuxt-graphql-middleware-provide-state" by setting it as a dependency via "dependsOn".`
12
+ );
13
+ }
14
+ const key = `${operation}:${operationName}:${hash(options.params)}`;
15
+ if (cacheOptions) {
16
+ const config = useAppConfig();
17
+ if (import.meta.client && cacheOptions.client && config.graphqlMiddleware.clientCacheEnabled) {
18
+ if (!app.$graphqlCache) {
19
+ app.$graphqlCache = new GraphqlMiddlewareCache(
20
+ config.graphqlMiddleware.clientCacheMaxSize
21
+ );
22
+ }
23
+ const cached = app.$graphqlCache.get(key);
24
+ if (cached) {
25
+ return cached;
26
+ }
27
+ }
28
+ }
29
+ const promise = $fetch(
30
+ getEndpoint(operation, operationName),
31
+ {
32
+ ...state && state.fetchOptions ? state.fetchOptions : {},
33
+ ...options,
34
+ method
35
+ }
36
+ ).then((v) => {
37
+ return {
38
+ ...v,
39
+ data: v.data,
40
+ errors: v.errors || []
41
+ };
42
+ });
43
+ if (import.meta.client && cacheOptions?.client && app.$graphqlCache) {
44
+ app.$graphqlCache.set(key, promise);
45
+ }
46
+ return promise;
47
+ }