nuxt-graphql-middleware 5.2.3 → 5.3.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 (133) hide show
  1. package/README.md +2 -0
  2. package/dist/client/200.html +1 -1
  3. package/dist/client/404.html +1 -1
  4. package/dist/client/_nuxt/CqRv5mwS.js +2 -0
  5. package/dist/client/_nuxt/{gyQx9VSj.js → D95LLO0l.js} +1 -1
  6. package/dist/client/_nuxt/{DyBqp5hr.js → DZ-uq6Vd.js} +1 -1
  7. package/dist/client/_nuxt/DrXVleME.js +4 -0
  8. package/dist/client/_nuxt/{BPB7Y782.js → Dx-h1-qv.js} +1 -1
  9. package/dist/client/_nuxt/builds/latest.json +1 -1
  10. package/dist/client/_nuxt/builds/meta/efa6c0a0-833e-4e5a-bc2d-ba9d0d3e4562.json +1 -0
  11. package/dist/client/index.html +1 -1
  12. package/dist/module.d.mts +1 -1
  13. package/dist/module.json +3 -3
  14. package/dist/module.mjs +1526 -70
  15. package/dist/runtime/components/CodeFrame.d.vue.ts +8 -0
  16. package/dist/runtime/components/CodeFrame.vue.d.ts +2 -1
  17. package/dist/runtime/components/DevModeOverlay.d.vue.ts +4 -0
  18. package/dist/runtime/components/DevModeOverlay.vue.d.ts +2 -1
  19. package/dist/runtime/components/ErrorExtensions.d.vue.ts +6 -0
  20. package/dist/runtime/components/ErrorExtensions.vue.d.ts +2 -1
  21. package/dist/runtime/components/ErrorGroup.d.vue.ts +10 -0
  22. package/dist/runtime/components/ErrorGroup.vue.d.ts +2 -1
  23. package/dist/runtime/helpers/composables.d.ts +1 -40
  24. package/dist/runtime/helpers/composables.js +3 -12
  25. package/dist/runtime/helpers/shared-types.d.ts +40 -0
  26. package/dist/runtime/helpers/shared-types.js +12 -0
  27. package/dist/runtime/server/api/doRequest.d.ts +2 -0
  28. package/dist/runtime/server/api/doRequest.js +18 -0
  29. package/dist/runtime/server/helpers/index.js +1 -1
  30. package/dist/runtime/server/mcp/handler.d.ts +2 -0
  31. package/dist/runtime/server/mcp/handler.js +63 -0
  32. package/dist/runtime/server/mcp/resources/docs.d.ts +2 -0
  33. package/dist/runtime/server/mcp/resources/docs.js +36 -0
  34. package/dist/runtime/server/mcp/tools/fragments-get/index.d.ts +1 -0
  35. package/dist/runtime/server/mcp/tools/fragments-get/index.js +35 -0
  36. package/dist/runtime/server/mcp/tools/fragments-get/types.d.ts +20 -0
  37. package/dist/runtime/server/mcp/tools/fragments-get/types.js +13 -0
  38. package/dist/runtime/server/mcp/tools/fragments-get-source/index.d.ts +1 -0
  39. package/dist/runtime/server/mcp/tools/fragments-get-source/index.js +34 -0
  40. package/dist/runtime/server/mcp/tools/fragments-get-source/types.d.ts +10 -0
  41. package/dist/runtime/server/mcp/tools/fragments-get-source/types.js +9 -0
  42. package/dist/runtime/server/mcp/tools/fragments-list/index.d.ts +1 -0
  43. package/dist/runtime/server/mcp/tools/fragments-list/index.js +36 -0
  44. package/dist/runtime/server/mcp/tools/fragments-list/types.d.ts +20 -0
  45. package/dist/runtime/server/mcp/tools/fragments-list/types.js +14 -0
  46. package/dist/runtime/server/mcp/tools/fragments-list-for-type/index.d.ts +1 -0
  47. package/dist/runtime/server/mcp/tools/fragments-list-for-type/index.js +39 -0
  48. package/dist/runtime/server/mcp/tools/fragments-list-for-type/types.d.ts +31 -0
  49. package/dist/runtime/server/mcp/tools/fragments-list-for-type/types.js +23 -0
  50. package/dist/runtime/server/mcp/tools/graphql-execute/index.d.ts +1 -0
  51. package/dist/runtime/server/mcp/tools/graphql-execute/index.js +59 -0
  52. package/dist/runtime/server/mcp/tools/module-get-config/index.d.ts +1 -0
  53. package/dist/runtime/server/mcp/tools/module-get-config/index.js +23 -0
  54. package/dist/runtime/server/mcp/tools/module-get-config/types.d.ts +39 -0
  55. package/dist/runtime/server/mcp/tools/module-get-config/types.js +26 -0
  56. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/index.d.ts +1 -0
  57. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/index.js +36 -0
  58. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/types.d.ts +49 -0
  59. package/dist/runtime/server/mcp/tools/nitro-graphql-server-utils-example/types.js +24 -0
  60. package/dist/runtime/server/mcp/tools/operations-execute/index.d.ts +1 -0
  61. package/dist/runtime/server/mcp/tools/operations-execute/index.js +63 -0
  62. package/dist/runtime/server/mcp/tools/operations-get/index.d.ts +1 -0
  63. package/dist/runtime/server/mcp/tools/operations-get/index.js +40 -0
  64. package/dist/runtime/server/mcp/tools/operations-get/types.d.ts +32 -0
  65. package/dist/runtime/server/mcp/tools/operations-get/types.js +18 -0
  66. package/dist/runtime/server/mcp/tools/operations-get-field-usage/index.d.ts +1 -0
  67. package/dist/runtime/server/mcp/tools/operations-get-field-usage/index.js +39 -0
  68. package/dist/runtime/server/mcp/tools/operations-get-field-usage/types.d.ts +38 -0
  69. package/dist/runtime/server/mcp/tools/operations-get-field-usage/types.js +19 -0
  70. package/dist/runtime/server/mcp/tools/operations-get-source/index.d.ts +1 -0
  71. package/dist/runtime/server/mcp/tools/operations-get-source/index.js +39 -0
  72. package/dist/runtime/server/mcp/tools/operations-get-source/types.d.ts +10 -0
  73. package/dist/runtime/server/mcp/tools/operations-get-source/types.js +9 -0
  74. package/dist/runtime/server/mcp/tools/operations-list/index.d.ts +1 -0
  75. package/dist/runtime/server/mcp/tools/operations-list/index.js +46 -0
  76. package/dist/runtime/server/mcp/tools/operations-list/types.d.ts +53 -0
  77. package/dist/runtime/server/mcp/tools/operations-list/types.js +33 -0
  78. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/index.d.ts +1 -0
  79. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/index.js +37 -0
  80. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/types.d.ts +24 -0
  81. package/dist/runtime/server/mcp/tools/schema-get-interface-implementors/types.js +16 -0
  82. package/dist/runtime/server/mcp/tools/schema-get-type/index.d.ts +1 -0
  83. package/dist/runtime/server/mcp/tools/schema-get-type/index.js +31 -0
  84. package/dist/runtime/server/mcp/tools/schema-get-type/types.d.ts +112 -0
  85. package/dist/runtime/server/mcp/tools/schema-get-type/types.js +45 -0
  86. package/dist/runtime/server/mcp/tools/schema-get-type-definition/index.d.ts +1 -0
  87. package/dist/runtime/server/mcp/tools/schema-get-type-definition/index.js +33 -0
  88. package/dist/runtime/server/mcp/tools/schema-get-type-definition/types.d.ts +10 -0
  89. package/dist/runtime/server/mcp/tools/schema-get-type-definition/types.js +9 -0
  90. package/dist/runtime/server/mcp/tools/schema-get-type-usage/index.d.ts +1 -0
  91. package/dist/runtime/server/mcp/tools/schema-get-type-usage/index.js +35 -0
  92. package/dist/runtime/server/mcp/tools/schema-get-type-usage/types.d.ts +39 -0
  93. package/dist/runtime/server/mcp/tools/schema-get-type-usage/types.js +17 -0
  94. package/dist/runtime/server/mcp/tools/schema-get-union-members/index.d.ts +1 -0
  95. package/dist/runtime/server/mcp/tools/schema-get-union-members/index.js +35 -0
  96. package/dist/runtime/server/mcp/tools/schema-get-union-members/types.d.ts +24 -0
  97. package/dist/runtime/server/mcp/tools/schema-get-union-members/types.js +16 -0
  98. package/dist/runtime/server/mcp/tools/schema-list-types/index.d.ts +1 -0
  99. package/dist/runtime/server/mcp/tools/schema-list-types/index.js +37 -0
  100. package/dist/runtime/server/mcp/tools/schema-list-types/types.d.ts +53 -0
  101. package/dist/runtime/server/mcp/tools/schema-list-types/types.js +21 -0
  102. package/dist/runtime/server/mcp/tools/schema-validate-document/index.d.ts +1 -0
  103. package/dist/runtime/server/mcp/tools/schema-validate-document/index.js +31 -0
  104. package/dist/runtime/server/mcp/tools/schema-validate-document/types.d.ts +26 -0
  105. package/dist/runtime/server/mcp/tools/schema-validate-document/types.js +21 -0
  106. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/index.d.ts +1 -0
  107. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/index.js +36 -0
  108. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/types.d.ts +49 -0
  109. package/dist/runtime/server/mcp/tools/vue-graphql-composable-example/types.js +24 -0
  110. package/dist/runtime/server/mcp/utils/index.d.ts +48 -0
  111. package/dist/runtime/server/mcp/utils/index.js +35 -0
  112. package/dist/runtime/server/utils/useGraphqlMutation.d.ts +1 -1
  113. package/dist/runtime/server/utils/useGraphqlMutation.js +1 -1
  114. package/dist/runtime/server/utils/useGraphqlQuery.d.ts +1 -1
  115. package/dist/runtime/server/utils/useGraphqlQuery.js +1 -1
  116. package/dist/shared/{nuxt-graphql-middleware.ct2xvPoD.d.mts → nuxt-graphql-middleware.COufMnWs.d.mts} +119 -2
  117. package/dist/utils.d.mts +1 -1
  118. package/docs/composables/useAsyncGraphqlQuery.md +313 -0
  119. package/docs/composables/useGraphqlMutation.md +29 -0
  120. package/docs/composables/useGraphqlQuery.md +73 -0
  121. package/docs/composables/useGraphqlState.md +58 -0
  122. package/docs/composables/useGraphqlUploadMutation.md +57 -0
  123. package/docs/configuration/client-options.md +121 -0
  124. package/docs/configuration/module-hooks.md +112 -0
  125. package/docs/configuration/module-utils.md +53 -0
  126. package/docs/configuration/module.md +415 -0
  127. package/docs/configuration/runtime-config.md +23 -0
  128. package/docs/configuration/server-options.md +230 -0
  129. package/package.json +101 -44
  130. package/dist/client/_nuxt/Bkyil6hz.js +0 -2
  131. package/dist/client/_nuxt/C9p-Va5c.js +0 -29
  132. package/dist/client/_nuxt/builds/meta/77b9a31d-6d5c-4e28-9320-cbd287a46883.json +0 -1
  133. package/dist/runtime/server/tsconfig.json +0 -3
package/dist/module.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { fileURLToPath } from 'url';
2
- import { useLogger, addTemplate, addServerTemplate, addTypeTemplate, createResolver, resolveAlias, resolveFiles, addPlugin, addServerHandler, addImports, addServerImports, useNitro, defineNuxtModule } from '@nuxt/kit';
3
- import { existsSync, promises } from 'node:fs';
4
- import { basename } from 'node:path';
2
+ import { useLogger, addTemplate, addServerTemplate, createResolver, resolveAlias, resolveFiles, addPlugin, addServerHandler, addImports, addServerImports, useNitro, defineNuxtModule, addDevServerHandler } from '@nuxt/kit';
3
+ import { existsSync, promises, readFileSync } from 'node:fs';
4
+ import { basename, join as join$1, dirname, isAbsolute, relative as relative$1 } from 'node:path';
5
5
  import { relative, join } from 'pathe';
6
- import { printSourceLocation, parse, Source, OperationTypeNode } from 'graphql';
6
+ import { printSourceLocation, parse, Source, OperationTypeNode, isObjectType, isInputObjectType, isEnumType, isUnionType, isInterfaceType, isScalarType, isNonNullType, isListType, printType, TypeInfo, visit, visitWithTypeInfo } from 'graphql';
7
7
  import { Generator, FieldNotFoundError, TypeNotFoundError, FragmentNotFoundError } from 'graphql-typescript-deluxe';
8
8
  import color from 'picocolors';
9
9
  import { validateGraphQlDocuments } from '@graphql-tools/utils';
@@ -18,9 +18,10 @@ import isUnicodeSupported from 'is-unicode-supported';
18
18
  import { hash } from 'ohash';
19
19
  import { existsSync as existsSync$1 } from 'fs';
20
20
  import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
21
+ import { defineEventHandler, readBody, createError } from 'h3';
21
22
 
22
23
  const name = "nuxt-graphql-middleware";
23
- const version = "5.2.3";
24
+ const version = "5.3.1";
24
25
 
25
26
  const logger = useLogger("nuxt-graphql-middleware");
26
27
  const defaultOptions = {
@@ -33,6 +34,7 @@ const defaultOptions = {
33
34
  documents: [],
34
35
  devtools: true,
35
36
  errorOverlay: true,
37
+ logOnlyErrors: true,
36
38
  graphqlConfigFilePath: "./graphql.config.ts",
37
39
  experimental: {
38
40
  improvedQueryParamEncoding: false
@@ -40,6 +42,9 @@ const defaultOptions = {
40
42
  clientCache: {
41
43
  enabled: false,
42
44
  maxSize: 100
45
+ },
46
+ mcp: {
47
+ enabled: false
43
48
  }
44
49
  };
45
50
  function validateOptions(options) {
@@ -161,6 +166,8 @@ class Collector {
161
166
  mappedOptions.output.buildTypeDocFilePath = (filePath) => {
162
167
  if (filePath.startsWith("/")) {
163
168
  return this.filePathToBuildRelative(filePath);
169
+ } else if (filePath.startsWith("hook:")) {
170
+ return "./../nuxt-graphql-middleware/hook-documents.graphql";
164
171
  }
165
172
  return filePath;
166
173
  };
@@ -199,6 +206,14 @@ class Collector {
199
206
  * The generated template contents.
200
207
  */
201
208
  templateResult = /* @__PURE__ */ new Map();
209
+ /**
210
+ * Operations with full metadata for MCP tools.
211
+ */
212
+ operations = [];
213
+ /**
214
+ * Fragments with full metadata for MCP tools.
215
+ */
216
+ fragments = [];
202
217
  isInitialised = false;
203
218
  async reset() {
204
219
  this.files.clear();
@@ -218,6 +233,9 @@ class Collector {
218
233
  filePathToSourceRelative(filePath) {
219
234
  if (filePath.startsWith("/")) {
220
235
  return "./" + relative(process.cwd(), filePath);
236
+ } else if (filePath.startsWith("hook:")) {
237
+ const hookPathAbsolute = this.helper.paths.moduleBuildDir + "/hook-documents.graphql";
238
+ return "./" + relative(process.cwd(), hookPathAbsolute);
221
239
  }
222
240
  return filePath;
223
241
  }
@@ -292,7 +310,7 @@ class Collector {
292
310
  } else {
293
311
  this.operationTimestamps.set(operation.graphqlName, operation.timestamp);
294
312
  }
295
- const shouldLog = errors.length || !this.helper.options.logOnlyErrors;
313
+ const shouldLog = errors.length || !this.helper.isPrepare && !this.helper.options.logOnlyErrors;
296
314
  if (shouldLog) {
297
315
  logEntries.push(this.operationToLogEntry(operation, errors));
298
316
  }
@@ -306,6 +324,40 @@ class Collector {
306
324
  throw new Error("GraphQL errors");
307
325
  }
308
326
  await this.helper.nuxt.callHook("nuxt-graphql-middleware:build", { output });
327
+ if (this.helper.isDev) {
328
+ this.operations = operations.map((op) => {
329
+ const fragmentDeps = op.getGraphQLFragmentDependencies().map((name) => fragmentMap.get(name) || "").join("\n");
330
+ const source = operationSourceMap.get(op.graphqlName) || "";
331
+ const sourceFull = [source, fragmentDeps].join("\n");
332
+ return {
333
+ name: op.graphqlName,
334
+ type: op.operationType,
335
+ filePath: op.filePath,
336
+ relativeFilePath: this.filePathToSourceRelative(op.filePath),
337
+ hasVariables: op.hasVariables,
338
+ needsVariables: op.needsVariables,
339
+ variablesTypeName: op.variablesTypeName,
340
+ responseTypeName: op.typeName,
341
+ source,
342
+ sourceFull
343
+ };
344
+ });
345
+ const outputFragments = output.getFragments();
346
+ this.fragments = outputFragments.map((frag) => {
347
+ const source = fragmentMap.get(frag.node.name.value) || "";
348
+ const fragmentDeps = frag.getGraphQLFragmentDependencies().map((name) => fragmentMap.get(name) || "").join("\n");
349
+ const sourceFull = [source, fragmentDeps].join("\n");
350
+ return {
351
+ name: frag.node.name.value,
352
+ typeName: frag.node.typeCondition.name.value,
353
+ filePath: frag.filePath,
354
+ relativeFilePath: this.filePathToSourceRelative(frag.filePath),
355
+ source,
356
+ sourceFull,
357
+ dependencies: frag.getGraphQLFragmentDependencies()
358
+ };
359
+ });
360
+ }
309
361
  if (this.helper.isDev) {
310
362
  for (const code of generatedCode) {
311
363
  const id = `${code.identifier}_${code.graphqlName}`;
@@ -313,7 +365,7 @@ class Collector {
313
365
  if (this.rpcItems.get(id)?.timestamp === code.timestamp) {
314
366
  continue;
315
367
  }
316
- const fragmentDepdendencies = code.getGraphQLFragmentDependencies().map((name) => fragmentMap.get(name) || "").join("\n\n");
368
+ const fragmentDepdendencies = code.getGraphQLFragmentDependencies().map((name) => fragmentMap.get(name) || "").join("\n");
317
369
  this.rpcItems.set(id, {
318
370
  id,
319
371
  timestamp: code.timestamp,
@@ -426,7 +478,9 @@ class Collector {
426
478
  await this.addFile(filePath);
427
479
  }
428
480
  await this.buildState();
429
- logger.success("All GraphQL documents are valid.");
481
+ if (!this.helper.isPrepare) {
482
+ logger.success("All GraphQL documents are valid.");
483
+ }
430
484
  } catch (e) {
431
485
  this.logError(e);
432
486
  throw new Error("GraphQL document validation failed.");
@@ -586,16 +640,10 @@ class Collector {
586
640
  if (template.buildTypes) {
587
641
  const path = template.options.path;
588
642
  const filename = template.options.path + ".d.ts";
589
- addTypeTemplate(
590
- {
591
- filename,
592
- write: true,
593
- getContents: () => this.getTemplate(path, "types")
594
- },
595
- {
596
- nuxt: true,
597
- nitro: true
598
- }
643
+ this.helper.registerTypeTemplate(
644
+ filename,
645
+ () => this.getTemplate(path, "types"),
646
+ template.options.context
599
647
  );
600
648
  }
601
649
  }
@@ -616,6 +664,30 @@ class Collector {
616
664
  getHookFiles() {
617
665
  return [...this.hookFiles.values()];
618
666
  }
667
+ /**
668
+ * Get all operations with metadata (for MCP tools).
669
+ */
670
+ getOperations() {
671
+ return this.operations;
672
+ }
673
+ /**
674
+ * Get all fragments for a specific GraphQL type (for MCP tools).
675
+ */
676
+ getFragmentsForType(typeName) {
677
+ return this.fragments.filter((frag) => frag.typeName === typeName);
678
+ }
679
+ /**
680
+ * Get all fragments (for MCP tools).
681
+ */
682
+ getFragments() {
683
+ return this.fragments;
684
+ }
685
+ /**
686
+ * Get a fragment by name (for MCP tools).
687
+ */
688
+ getFragment(name) {
689
+ return this.fragments.find((frag) => frag.name === name);
690
+ }
619
691
  }
620
692
 
621
693
  class SchemaProvider {
@@ -667,7 +739,11 @@ class SchemaProvider {
667
739
  );
668
740
  throw new Error("Missing GraphQL schema.");
669
741
  }
670
- logger.info(`Loading GraphQL schema from disk: ${this.helper.paths.schema}`);
742
+ if (!this.helper.isPrepare) {
743
+ logger.info(
744
+ `Loading GraphQL schema from disk: ${this.helper.paths.schema}`
745
+ );
746
+ }
671
747
  return await fs.readFile(this.helper.paths.schema).then((v) => v.toString());
672
748
  }
673
749
  /**
@@ -720,7 +796,7 @@ class SchemaProvider {
720
796
  * @param forceDownload - Forces downloading the schema.
721
797
  */
722
798
  async loadSchema(opts) {
723
- if (opts?.forceDisk) {
799
+ if (opts?.forceDisk || this.helper.isPrepare) {
724
800
  this.schemaContent = await this.loadSchemaFromDisk();
725
801
  } else if (this.helper.options.downloadSchema || opts?.forceDownload) {
726
802
  this.schemaContent = await this.downloadSchema();
@@ -817,9 +893,72 @@ ${color.cyan(S_BAR_END)}
817
893
  }
818
894
  }
819
895
 
896
+ function defineImport(name, description, context) {
897
+ const docsPath = context === "nuxt" ? "composables" : "server-utils";
898
+ return {
899
+ name,
900
+ description,
901
+ context,
902
+ docsUrl: `https://nuxt-graphql-middleware.dulnan.net/${docsPath}/${name}.html`
903
+ };
904
+ }
905
+ const useGraphqlQuery = defineImport(
906
+ "useGraphqlQuery",
907
+ "Perform a GraphQL query via the middleware. Returns a promise. Can be used anywhere - in components, plugins, other composables, event handlers, or inside useAsyncData.",
908
+ "nuxt"
909
+ );
910
+ const useAsyncGraphqlQuery = defineImport(
911
+ "useAsyncGraphqlQuery",
912
+ "SSR-compatible, reactive data fetching. Must be called at the root of a component setup or inside another composable. Same limitations as useAsyncData.",
913
+ "nuxt"
914
+ );
915
+ const useGraphqlMutation = defineImport(
916
+ "useGraphqlMutation",
917
+ "Perform a GraphQL mutation via the middleware. Returns a promise. Can be used anywhere - in components, plugins, other composables, or event handlers.",
918
+ "nuxt"
919
+ );
920
+ const useGraphqlUploadMutation = defineImport(
921
+ "useGraphqlUploadMutation",
922
+ "Perform a GraphQL mutation via the middleware with support for file uploads. Returns a promise. Can be used anywhere - in components, plugins, other composables, or event handlers.",
923
+ "nuxt"
924
+ );
925
+ const useGraphqlState = defineImport(
926
+ "useGraphqlState",
927
+ "allows you to set fetch options for the useGraphqlQuery, useAsyncGraphqlQuery and useGraphqlMutation composables. One common use case is to pass custom request headers to the GraphQL middleware request.",
928
+ "nuxt"
929
+ );
930
+ const COMPOSABLES = {
931
+ useGraphqlQuery,
932
+ useGraphqlMutation,
933
+ useAsyncGraphqlQuery,
934
+ useGraphqlUploadMutation,
935
+ useGraphqlState
936
+ };
937
+ const serverUseGraphqlQuery = defineImport(
938
+ "useGraphqlQuery",
939
+ "Perform a GraphQL query via the middleware in a Nitro server context. Auto-imported and available in event handlers, server plugins, and other server-side code.",
940
+ "nitro"
941
+ );
942
+ const serverUseGraphqlMutation = defineImport(
943
+ "useGraphqlMutation",
944
+ "Perform a GraphQL mutation via the middleware in a Nitro server context. Auto-imported and available in event handlers, server plugins, and other server-side code.",
945
+ "nitro"
946
+ );
947
+ const doGraphqlRequest = defineImport(
948
+ "doGraphqlRequest",
949
+ "Perform a raw GraphQL request in a Nitro server context. Provides low-level access to execute arbitrary GraphQL queries and mutations.",
950
+ "nitro"
951
+ );
952
+ const SERVER_UTILS = {
953
+ useGraphqlQuery: serverUseGraphqlQuery,
954
+ useGraphqlMutation: serverUseGraphqlMutation,
955
+ doGraphqlRequest
956
+ };
957
+
820
958
  class ModuleHelper {
821
959
  constructor(nuxt, moduleUrl, options) {
822
960
  this.nuxt = nuxt;
961
+ this.isPrepare = nuxt.options._prepare;
823
962
  const mergedOptions = defu(
824
963
  {},
825
964
  options,
@@ -897,6 +1036,7 @@ class ModuleHelper {
897
1036
  resolvers;
898
1037
  paths;
899
1038
  isDev;
1039
+ isPrepare;
900
1040
  options;
901
1041
  prompt = new ConsolePrompt();
902
1042
  nitroExternals = [];
@@ -926,7 +1066,9 @@ class ModuleHelper {
926
1066
  );
927
1067
  }
928
1068
  }
929
- logger.info("No graphqlMiddleware.serverOptions file found.");
1069
+ if (!this.isPrepare) {
1070
+ logger.info("No graphqlMiddleware.serverOptions file found.");
1071
+ }
930
1072
  return null;
931
1073
  }
932
1074
  findClientOptions() {
@@ -1029,10 +1171,38 @@ ${content.trim()}`;
1029
1171
  template.buildTypes(this)
1030
1172
  );
1031
1173
  const filename = template.options.path + ".d.ts";
1032
- addTypeTemplate({
1174
+ this.registerTypeTemplate(
1033
1175
  filename,
1034
- write: true,
1035
- getContents: () => content
1176
+ () => content,
1177
+ template.options.context
1178
+ );
1179
+ }
1180
+ }
1181
+ /**
1182
+ * Register a type template without adding to globalTypeFiles.
1183
+ *
1184
+ * Uses addTemplate instead of addTypeTemplate to avoid Vue compiler-sfc
1185
+ * issue where exported types from globalTypeFiles cannot be resolved.
1186
+ * @see https://github.com/nuxt/nuxt/issues/33694
1187
+ */
1188
+ registerTypeTemplate(filename, getContents, context) {
1189
+ const resolvedTemplate = addTemplate({
1190
+ filename,
1191
+ write: true,
1192
+ getContents
1193
+ });
1194
+ const forNuxt = context === "nuxt" || context === "both";
1195
+ const forNitro = context === "nitro" || context === "both";
1196
+ if (forNuxt) {
1197
+ this.nuxt.hook("prepare:types", (payload) => {
1198
+ payload.references ||= [];
1199
+ payload.references.push({ path: resolvedTemplate.dst });
1200
+ });
1201
+ }
1202
+ if (forNitro) {
1203
+ this.nuxt.hook("nitro:prepare:types", (payload) => {
1204
+ payload.references ||= [];
1205
+ payload.references.push({ path: resolvedTemplate.dst });
1036
1206
  });
1037
1207
  }
1038
1208
  }
@@ -1049,16 +1219,26 @@ ${content.trim()}`;
1049
1219
  });
1050
1220
  }
1051
1221
  addComposable(name) {
1222
+ const composable = COMPOSABLES[name];
1052
1223
  addImports({
1053
1224
  from: this.resolvers.module.resolve("./runtime/composables/" + name),
1054
- name
1225
+ name,
1226
+ meta: {
1227
+ description: composable.description,
1228
+ docsUrl: composable.docsUrl
1229
+ }
1055
1230
  });
1056
1231
  }
1057
1232
  addServerUtil(name) {
1233
+ const serverUtil = SERVER_UTILS[name];
1058
1234
  addServerImports([
1059
1235
  {
1060
1236
  from: this.resolvers.module.resolve("./runtime/server/utils/" + name),
1061
- name
1237
+ name,
1238
+ meta: {
1239
+ description: serverUtil.description,
1240
+ docsUrl: serverUtil.docsUrl
1241
+ }
1062
1242
  }
1063
1243
  ]);
1064
1244
  }
@@ -1082,7 +1262,7 @@ function defineStaticTemplate(options, build, buildTypes) {
1082
1262
  }
1083
1263
 
1084
1264
  const ClientOptions = defineStaticTemplate(
1085
- { path: "nuxt-graphql-middleware/client-options" },
1265
+ { path: "nuxt-graphql-middleware/client-options", context: "both" },
1086
1266
  (helper) => {
1087
1267
  if (helper.paths.clientOptions) {
1088
1268
  const pathRelative = helper.toModuleBuildRelative(
@@ -1102,21 +1282,21 @@ export { clientOptions }
1102
1282
  return `import type { GraphqlClientOptions } from '${helper.paths.runtimeTypes}'
1103
1283
  import clientOptionsImport from '${pathRelative}'
1104
1284
 
1105
- declare export const clientOptions: GraphqlClientOptions|undefined
1285
+ export declare const clientOptions: GraphqlClientOptions|undefined
1106
1286
  export type GraphqlClientContext = typeof clientOptionsImport extends GraphqlClientOptions<infer R> ? R : {}
1107
1287
  `;
1108
1288
  }
1109
1289
  return `
1110
1290
  import type { GraphqlClientOptions } from '${helper.paths.runtimeTypes}'
1111
1291
 
1112
- declare export const clientOptions: GraphqlClientOptions|undefined
1292
+ export declare const clientOptions: GraphqlClientOptions|undefined
1113
1293
  export type GraphqlClientContext = {}
1114
1294
  `;
1115
1295
  }
1116
1296
  );
1117
1297
 
1118
1298
  const Config = defineStaticTemplate(
1119
- { path: "nuxt-graphql-middleware/config" },
1299
+ { path: "nuxt-graphql-middleware/config", context: "both" },
1120
1300
  (helper) => {
1121
1301
  const experimentalQueryParamEncoding = !!helper.options.experimental.improvedQueryParamEncoding;
1122
1302
  const clientCacheEnabledAtBuild = !!helper.options.clientCache.enabled;
@@ -1129,16 +1309,20 @@ export const importMetaClient = import.meta.client
1129
1309
  },
1130
1310
  () => {
1131
1311
  return `
1132
- declare export const experimentalQueryParamEncoding: boolean
1133
- declare export const clientCacheEnabledAtBuild: boolean
1134
- declare export const importMetaServer: boolean
1135
- declare export const importMetaClient: boolean
1312
+ export declare const experimentalQueryParamEncoding: boolean
1313
+ export declare const clientCacheEnabledAtBuild: boolean
1314
+ export declare const importMetaServer: boolean
1315
+ export declare const importMetaClient: boolean
1136
1316
  `;
1137
1317
  }
1138
1318
  );
1139
1319
 
1140
1320
  const Documents = defineGeneratorTemplate(
1141
- { path: "nuxt-graphql-middleware/documents", virtual: true },
1321
+ {
1322
+ path: "nuxt-graphql-middleware/documents",
1323
+ virtual: true,
1324
+ context: "nitro"
1325
+ },
1142
1326
  (output, helper) => {
1143
1327
  return output.getOperationsFile({
1144
1328
  exportName: "documents",
@@ -1160,7 +1344,7 @@ declare module '#nuxt-graphql-middleware/documents' {
1160
1344
  );
1161
1345
 
1162
1346
  const GraphqlConfig = defineStaticTemplate(
1163
- { path: "nuxt-graphql-middleware/graphql.config" },
1347
+ { path: "nuxt-graphql-middleware/graphql.config", context: "nuxt" },
1164
1348
  (helper) => {
1165
1349
  const patterns = helper.options.autoImportPatterns || [];
1166
1350
  const configPath = helper.resolvers.root.resolve(
@@ -1203,15 +1387,15 @@ import type { IGraphQLProject } from 'graphql-config'
1203
1387
 
1204
1388
  type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
1205
1389
 
1206
- const config: WithRequired<IGraphQLProject, 'schema' | 'documents'>;
1390
+ declare const config: WithRequired<IGraphQLProject, 'schema' | 'documents'>
1207
1391
 
1208
- export default config;
1392
+ export default config
1209
1393
  `;
1210
1394
  }
1211
1395
  );
1212
1396
 
1213
1397
  const Helpers = defineStaticTemplate(
1214
- { path: "nuxt-graphql-middleware/helpers" },
1398
+ { path: "nuxt-graphql-middleware/helpers", context: "both" },
1215
1399
  (helper) => {
1216
1400
  return `export const serverApiPrefix = '${helper.options.serverApiPrefix}'
1217
1401
  export function getEndpoint(operation, operationName) {
@@ -1220,8 +1404,8 @@ export function getEndpoint(operation, operationName) {
1220
1404
  `;
1221
1405
  },
1222
1406
  () => {
1223
- return `export const serverApiPrefix: string;
1224
- export function getEndpoint(operation: string, operationName: string): string`;
1407
+ return `export declare const serverApiPrefix: string
1408
+ export declare function getEndpoint(operation: string, operationName: string): string`;
1225
1409
  }
1226
1410
  );
1227
1411
 
@@ -1229,7 +1413,8 @@ const HookDocuments = defineGeneratorTemplate(
1229
1413
  {
1230
1414
  path: "nuxt-graphql-middleware/hook-documents.graphql",
1231
1415
  virtual: false,
1232
- isFullPath: true
1416
+ isFullPath: true,
1417
+ context: "nuxt"
1233
1418
  },
1234
1419
  (_output, _helper, collector) => {
1235
1420
  return collector.getHookDocuments().map((v) => {
@@ -1245,7 +1430,8 @@ ${v.source}
1245
1430
  const HookFiles = defineGeneratorTemplate(
1246
1431
  {
1247
1432
  path: "nuxt-graphql-middleware/hook-files",
1248
- virtual: false
1433
+ virtual: false,
1434
+ context: "nuxt"
1249
1435
  },
1250
1436
  (_output, helper, collector) => {
1251
1437
  const configPath = helper.resolvers.root.resolve(
@@ -1259,11 +1445,13 @@ const HookFiles = defineGeneratorTemplate(
1259
1445
  });
1260
1446
  return `export const hookFiles = ${JSON.stringify(files, null, 2)}`;
1261
1447
  },
1262
- null
1448
+ () => {
1449
+ return `export declare const hookFiles: string[]`;
1450
+ }
1263
1451
  );
1264
1452
 
1265
1453
  const NitroTypes = defineGeneratorTemplate(
1266
- { path: "nuxt-graphql-middleware/nitro" },
1454
+ { path: "nuxt-graphql-middleware/nitro", context: "nitro" },
1267
1455
  null,
1268
1456
  (output, helper) => {
1269
1457
  const operations = output.getCollectedOperations();
@@ -1293,7 +1481,11 @@ ${endpoints.sort().join("\n")}
1293
1481
  );
1294
1482
 
1295
1483
  const OperationHashes = defineGeneratorTemplate(
1296
- { path: "nuxt-graphql-middleware/operation-hashes", virtual: true },
1484
+ {
1485
+ path: "nuxt-graphql-middleware/operation-hashes",
1486
+ virtual: true,
1487
+ context: "nuxt"
1488
+ },
1297
1489
  (output, helper) => {
1298
1490
  if (helper.isDev) {
1299
1491
  return `export const operationHashes = {}`;
@@ -1333,7 +1525,7 @@ declare module '#nuxt-graphql-middleware/operation-hashes' {
1333
1525
  );
1334
1526
 
1335
1527
  const OperationTypesAll = defineGeneratorTemplate(
1336
- { path: "nuxt-graphql-middleware/operation-types" },
1528
+ { path: "nuxt-graphql-middleware/operation-types", context: "both" },
1337
1529
  () => `export {}`,
1338
1530
  (output) => {
1339
1531
  return output.getOperationTypesFile({
@@ -1343,7 +1535,7 @@ const OperationTypesAll = defineGeneratorTemplate(
1343
1535
  );
1344
1536
 
1345
1537
  const Operations = defineGeneratorTemplate(
1346
- { path: "graphql-operations/index" },
1538
+ { path: "graphql-operations/index", context: "both" },
1347
1539
  (output) => {
1348
1540
  const typesFile = output.getOperations("js");
1349
1541
  return typesFile.getSource();
@@ -1355,7 +1547,7 @@ const Operations = defineGeneratorTemplate(
1355
1547
  );
1356
1548
 
1357
1549
  const OperationVariables = defineGeneratorTemplate(
1358
- { path: "nuxt-graphql-middleware/operation-variables" },
1550
+ { path: "nuxt-graphql-middleware/operation-variables", context: "nitro" },
1359
1551
  (output) => {
1360
1552
  const operations = output.getCollectedOperations().reduce((acc, collectedOperation) => {
1361
1553
  const node = collectedOperation.node;
@@ -1368,13 +1560,13 @@ const OperationVariables = defineGeneratorTemplate(
1368
1560
  },
1369
1561
  () => {
1370
1562
  return `
1371
- declare export const operationVariables: Record<string, string[]>
1563
+ export declare const operationVariables: Record<string, string[]>
1372
1564
  `;
1373
1565
  }
1374
1566
  );
1375
1567
 
1376
1568
  const Response = defineGeneratorTemplate(
1377
- { path: "nuxt-graphql-middleware/response" },
1569
+ { path: "nuxt-graphql-middleware/response", context: "both" },
1378
1570
  null,
1379
1571
  (output, helper) => {
1380
1572
  const operations = output.getCollectedOperations();
@@ -1396,7 +1588,7 @@ declare module '#nuxt-graphql-middleware/response' {
1396
1588
  );
1397
1589
 
1398
1590
  const ServerOptions = defineStaticTemplate(
1399
- { path: "nuxt-graphql-middleware/server-options" },
1591
+ { path: "nuxt-graphql-middleware/server-options", context: "both" },
1400
1592
  (helper) => {
1401
1593
  const resolvedPathRelative = helper.paths.serverOptions ? helper.toModuleBuildRelative(helper.paths.serverOptions) : null;
1402
1594
  const serverOptionsLine = resolvedPathRelative ? `import serverOptions from '${resolvedPathRelative}'` : `const serverOptions = {}`;
@@ -1418,13 +1610,13 @@ type AdditionsFromServerOptions = typeof serverOptionsImport extends GraphqlMidd
1418
1610
 
1419
1611
  export type GraphqlResponseAdditions = Omit<AdditionsFromServerOptions, 'data' | 'errors'>
1420
1612
 
1421
- declare export const serverOptions: GraphqlMiddlewareServerOptions
1613
+ export declare const serverOptions: GraphqlMiddlewareServerOptions
1422
1614
  `;
1423
1615
  }
1424
1616
  return `
1425
1617
  import type { GraphqlMiddlewareServerOptions } from '${helper.paths.runtimeTypes}'
1426
1618
 
1427
- declare export const serverOptions: GraphqlMiddlewareServerOptions
1619
+ export declare const serverOptions: GraphqlMiddlewareServerOptions
1428
1620
 
1429
1621
  export type GraphqlResponseAdditions = object
1430
1622
  `;
@@ -1432,7 +1624,7 @@ export type GraphqlResponseAdditions = object
1432
1624
  );
1433
1625
 
1434
1626
  const Sources = defineGeneratorTemplate(
1435
- { path: "nuxt-graphql-middleware/sources" },
1627
+ { path: "nuxt-graphql-middleware/sources", context: "nuxt" },
1436
1628
  (output, helper) => {
1437
1629
  const operations = output.getCollectedOperations();
1438
1630
  const srcDir = helper.paths.root;
@@ -1450,7 +1642,125 @@ export const operationSources = {
1450
1642
  `;
1451
1643
  },
1452
1644
  () => {
1453
- return `export const operationSources: Record<string, string>`;
1645
+ return `export declare const operationSources: Record<string, string>`;
1646
+ }
1647
+ );
1648
+
1649
+ const DOCS = [
1650
+ // Composables
1651
+ {
1652
+ path: "composables/useGraphqlQuery",
1653
+ file: "composables/useGraphqlQuery.md",
1654
+ name: "useGraphqlQuery",
1655
+ description: "Execute a GraphQL query using $fetch"
1656
+ },
1657
+ {
1658
+ path: "composables/useGraphqlMutation",
1659
+ file: "composables/useGraphqlMutation.md",
1660
+ name: "useGraphqlMutation",
1661
+ description: "Execute a GraphQL mutation using $fetch"
1662
+ },
1663
+ {
1664
+ path: "composables/useAsyncGraphqlQuery",
1665
+ file: "composables/useAsyncGraphqlQuery.md",
1666
+ name: "useAsyncGraphqlQuery",
1667
+ description: "SSR-compatible GraphQL query with useAsyncData"
1668
+ },
1669
+ {
1670
+ path: "composables/useGraphqlState",
1671
+ file: "composables/useGraphqlState.md",
1672
+ name: "useGraphqlState",
1673
+ description: "Access cached GraphQL query state"
1674
+ },
1675
+ {
1676
+ path: "composables/useGraphqlUploadMutation",
1677
+ file: "composables/useGraphqlUploadMutation.md",
1678
+ name: "useGraphqlUploadMutation",
1679
+ description: "GraphQL mutation with file upload support"
1680
+ },
1681
+ // Configuration
1682
+ {
1683
+ path: "configuration/module",
1684
+ file: "configuration/module.md",
1685
+ name: "Module Configuration",
1686
+ description: "Configure the nuxt-graphql-middleware module options"
1687
+ },
1688
+ {
1689
+ path: "configuration/client-options",
1690
+ file: "configuration/client-options.md",
1691
+ name: "Client Options",
1692
+ description: "Configure client-side GraphQL request behavior"
1693
+ },
1694
+ {
1695
+ path: "configuration/server-options",
1696
+ file: "configuration/server-options.md",
1697
+ name: "Server Options",
1698
+ description: "Configure server-side GraphQL request handling"
1699
+ },
1700
+ {
1701
+ path: "configuration/module-hooks",
1702
+ file: "configuration/module-hooks.md",
1703
+ name: "Module Hooks",
1704
+ description: "Use Nuxt hooks to customize module behavior"
1705
+ },
1706
+ {
1707
+ path: "configuration/module-utils",
1708
+ file: "configuration/module-utils.md",
1709
+ name: "Module Utils",
1710
+ description: "Utility functions for working with the module"
1711
+ },
1712
+ {
1713
+ path: "configuration/runtime-config",
1714
+ file: "configuration/runtime-config.md",
1715
+ name: "Runtime Config",
1716
+ description: "Configure runtime settings via Nuxt runtime config"
1717
+ }
1718
+ ];
1719
+ const MCP = defineStaticTemplate(
1720
+ { path: "nuxt-graphql-middleware/mcp", context: "nitro" },
1721
+ (helper) => {
1722
+ const mcpServerRoute = helper.options.mcp.route ?? "/mcp/nuxt-graphql-middleware";
1723
+ const devServerUrl = helper.isDev ? `http://${helper.nuxt.options.devServer.host || "localhost"}:${helper.nuxt.options.devServer.port || 3e3}` : "";
1724
+ const docsDir = helper.resolvers.module.resolve("../docs");
1725
+ const entries = [];
1726
+ if (helper.isDev || helper.isPrepare) {
1727
+ for (const doc of DOCS) {
1728
+ const filePath = join$1(docsDir, doc.file);
1729
+ try {
1730
+ const content = readFileSync(filePath, "utf-8");
1731
+ entries.push({
1732
+ uri: `docs://${doc.path}`,
1733
+ name: doc.name,
1734
+ description: doc.description,
1735
+ content
1736
+ });
1737
+ } catch {
1738
+ }
1739
+ }
1740
+ }
1741
+ const includeComposables = !!helper.options.includeComposables;
1742
+ return `
1743
+ export const mcpServerRoute = ${JSON.stringify(mcpServerRoute)}
1744
+ export const devServerUrl = ${JSON.stringify(devServerUrl)}
1745
+ export const includeComposables = ${JSON.stringify(includeComposables)}
1746
+ export const docs = ${JSON.stringify(entries, null, 2)}
1747
+ `;
1748
+ },
1749
+ () => {
1750
+ return `
1751
+ export declare const mcpServerRoute: string
1752
+ export declare const devServerUrl: string
1753
+ export declare const includeComposables: boolean
1754
+
1755
+ export type Doc = {
1756
+ uri: string
1757
+ name: string
1758
+ description: string
1759
+ content: string
1760
+ }
1761
+
1762
+ export declare const docs: Doc[]
1763
+ `;
1454
1764
  }
1455
1765
  );
1456
1766
 
@@ -1469,7 +1779,8 @@ const TEMPLATES = [
1469
1779
  OperationVariables,
1470
1780
  Response,
1471
1781
  ServerOptions,
1472
- Sources
1782
+ Sources,
1783
+ MCP
1473
1784
  ];
1474
1785
 
1475
1786
  const DEVTOOLS_UI_ROUTE = "/__nuxt-graphql-middleware";
@@ -1533,6 +1844,8 @@ class DevModeHandler {
1533
1844
  this.onViteServerCreated.bind(this)
1534
1845
  );
1535
1846
  this.nuxt.hook("builder:watch", this.onBuilderWatch.bind(this));
1847
+ const additionalFoldersToWatch = this.getAdditionalWatchFolders();
1848
+ this.helper.nuxt.options.watch.push(...additionalFoldersToWatch);
1536
1849
  if (this.helper.options.devtools) {
1537
1850
  const clientPath = this.helper.resolvers.module.resolve("./client");
1538
1851
  setupDevToolsUI(this.nuxt, clientPath);
@@ -1642,6 +1955,34 @@ class DevModeHandler {
1642
1955
  data: { operations }
1643
1956
  });
1644
1957
  }
1958
+ /**
1959
+ * Get additional folders that need to be watched.
1960
+ */
1961
+ getAdditionalWatchFolders() {
1962
+ const folders = /* @__PURE__ */ new Set();
1963
+ const srcDir = this.helper.nuxt.options.srcDir;
1964
+ const rootDir = this.helper.nuxt.options.rootDir;
1965
+ for (const pattern of this.helper.options.autoImportPatterns) {
1966
+ if (pattern.startsWith("!")) {
1967
+ continue;
1968
+ }
1969
+ const match = pattern.match(/[*?{[]/);
1970
+ if (!match || match.index === void 0) {
1971
+ folders.add(dirname(pattern));
1972
+ } else {
1973
+ const pathBeforeGlob = pattern.slice(0, match.index);
1974
+ const folder = pathBeforeGlob.endsWith("/") ? pathBeforeGlob.slice(0, -1) : dirname(pathBeforeGlob);
1975
+ if (folder && folder !== ".") {
1976
+ folders.add(folder);
1977
+ }
1978
+ }
1979
+ }
1980
+ return [...folders].filter((folder) => {
1981
+ return !folder.startsWith(srcDir) && folder !== rootDir;
1982
+ }).map((folder) => {
1983
+ return relative(srcDir, folder);
1984
+ });
1985
+ }
1645
1986
  }
1646
1987
 
1647
1988
  class ModuleContext {
@@ -1722,7 +2063,1108 @@ class ModuleContext {
1722
2063
  }
1723
2064
  }
1724
2065
 
1725
- const module = defineNuxtModule({
2066
+ function createNameFilter(pattern) {
2067
+ try {
2068
+ const regex = new RegExp(pattern);
2069
+ return (name) => regex.test(name);
2070
+ } catch {
2071
+ return (name) => name.includes(pattern);
2072
+ }
2073
+ }
2074
+
2075
+ function handleListOperations(collector, nameFilter, typeFilter) {
2076
+ let operations = collector.getOperations();
2077
+ if (nameFilter) {
2078
+ const filterFn = createNameFilter(nameFilter);
2079
+ operations = operations.filter((op) => filterFn(op.name));
2080
+ }
2081
+ if (typeFilter) {
2082
+ operations = operations.filter((op) => op.type === typeFilter);
2083
+ }
2084
+ return { operations };
2085
+ }
2086
+
2087
+ function handleGetOperation(collector, name) {
2088
+ const operations = collector.getOperations();
2089
+ const operation = operations.find((op) => op.name === name);
2090
+ if (!operation) {
2091
+ return { operation: null, error: `Operation "${name}" not found` };
2092
+ }
2093
+ return { operation };
2094
+ }
2095
+
2096
+ function handleGetOperationSource(collector, name, includeDependencies = false) {
2097
+ const operations = collector.getOperations();
2098
+ const operation = operations.find((op) => op.name === name);
2099
+ if (!operation) {
2100
+ return { source: null, error: `Operation "${name}" not found` };
2101
+ }
2102
+ const source = includeDependencies ? operation.sourceFull : operation.source;
2103
+ return { source };
2104
+ }
2105
+
2106
+ function handleListFragments(collector, nameFilter) {
2107
+ let fragments = collector.getFragments();
2108
+ if (nameFilter) {
2109
+ const filterFn = createNameFilter(nameFilter);
2110
+ fragments = fragments.filter((frag) => filterFn(frag.name));
2111
+ }
2112
+ return { fragments };
2113
+ }
2114
+
2115
+ function handleGetFragment(collector, name) {
2116
+ const fragment = collector.getFragment(name);
2117
+ if (!fragment) {
2118
+ return { fragment: null, error: `Fragment "${name}" not found` };
2119
+ }
2120
+ return { fragment };
2121
+ }
2122
+
2123
+ function handleGetFragmentSource(collector, name, includeDependencies = false) {
2124
+ const fragment = collector.getFragment(name);
2125
+ if (!fragment) {
2126
+ return { source: null, error: `Fragment "${name}" not found` };
2127
+ }
2128
+ const source = includeDependencies ? fragment.sourceFull : fragment.source;
2129
+ return { source };
2130
+ }
2131
+
2132
+ function handleGetFragmentsForType(collector, name) {
2133
+ return { fragments: collector.getFragmentsForType(name) };
2134
+ }
2135
+
2136
+ function formatType$2(type) {
2137
+ return type.toString();
2138
+ }
2139
+ function isNonNull(type) {
2140
+ return isNonNullType(type);
2141
+ }
2142
+ function isList(type) {
2143
+ if (isNonNullType(type)) {
2144
+ return isListType(type.ofType);
2145
+ }
2146
+ return isListType(type);
2147
+ }
2148
+ function mapField(field) {
2149
+ return {
2150
+ name: field.name,
2151
+ description: field.description || null,
2152
+ type: formatType$2(field.type),
2153
+ isNonNull: isNonNull(field.type),
2154
+ isList: isList(field.type),
2155
+ deprecationReason: "deprecationReason" in field ? field.deprecationReason || null : null
2156
+ };
2157
+ }
2158
+ function mapEnumValue(value) {
2159
+ return {
2160
+ name: value.name,
2161
+ description: value.description || null
2162
+ };
2163
+ }
2164
+ function handleGetSchemaType(schema, name) {
2165
+ const type = schema.getType(name);
2166
+ if (!type) {
2167
+ return { type: null, error: `Type "${name}" not found in schema` };
2168
+ }
2169
+ const info = {
2170
+ name: type.name,
2171
+ kind: "UNKNOWN",
2172
+ description: type.description || null,
2173
+ fields: null,
2174
+ enumValues: null,
2175
+ possibleTypes: null,
2176
+ interfaces: null
2177
+ };
2178
+ if (isObjectType(type)) {
2179
+ info.kind = "OBJECT";
2180
+ info.fields = Object.values(type.getFields()).map(mapField);
2181
+ info.interfaces = type.getInterfaces().map((i) => i.name);
2182
+ } else if (isInputObjectType(type)) {
2183
+ info.kind = "INPUT_OBJECT";
2184
+ info.fields = Object.values(type.getFields()).map(mapField);
2185
+ } else if (isEnumType(type)) {
2186
+ info.kind = "ENUM";
2187
+ info.enumValues = type.getValues().map(mapEnumValue);
2188
+ } else if (isUnionType(type)) {
2189
+ info.kind = "UNION";
2190
+ info.possibleTypes = type.getTypes().map((t) => t.name);
2191
+ } else if (isInterfaceType(type)) {
2192
+ info.kind = "INTERFACE";
2193
+ info.fields = Object.values(type.getFields()).map(mapField);
2194
+ } else if (isScalarType(type)) {
2195
+ info.kind = "SCALAR";
2196
+ }
2197
+ return { type: info };
2198
+ }
2199
+
2200
+ function handleGetSchemaTypeDefinition(schema, name) {
2201
+ const type = schema.getType(name);
2202
+ if (!type) {
2203
+ return { definition: null, error: `Type "${name}" not found in schema` };
2204
+ }
2205
+ return { definition: printType(type) };
2206
+ }
2207
+
2208
+ function getTypeKind(type) {
2209
+ if (isObjectType(type)) return "OBJECT";
2210
+ if (isInputObjectType(type)) return "INPUT_OBJECT";
2211
+ if (isEnumType(type)) return "ENUM";
2212
+ if (isUnionType(type)) return "UNION";
2213
+ if (isInterfaceType(type)) return "INTERFACE";
2214
+ if (isScalarType(type)) return "SCALAR";
2215
+ return null;
2216
+ }
2217
+ function handleListSchemaTypes(schema, kind) {
2218
+ const typeMap = schema.getTypeMap();
2219
+ const types = [];
2220
+ for (const [name, type] of Object.entries(typeMap)) {
2221
+ if (name.startsWith("__")) {
2222
+ continue;
2223
+ }
2224
+ const typeKind = getTypeKind(type);
2225
+ if (!typeKind) {
2226
+ continue;
2227
+ }
2228
+ if (kind && typeKind !== kind) {
2229
+ continue;
2230
+ }
2231
+ types.push({
2232
+ name: type.name,
2233
+ kind: typeKind,
2234
+ description: type.description || null
2235
+ });
2236
+ }
2237
+ types.sort((a, b) => a.name.localeCompare(b.name));
2238
+ return { types };
2239
+ }
2240
+
2241
+ function handleGetTypesImplementingInterface(schema, interfaceName) {
2242
+ const interfaceType = schema.getType(interfaceName);
2243
+ if (!interfaceType) {
2244
+ return {
2245
+ interfaceName,
2246
+ types: [],
2247
+ error: `Type "${interfaceName}" not found in schema`
2248
+ };
2249
+ }
2250
+ if (!isInterfaceType(interfaceType)) {
2251
+ return {
2252
+ interfaceName,
2253
+ types: [],
2254
+ error: `Type "${interfaceName}" is not an interface`
2255
+ };
2256
+ }
2257
+ const implementingTypes = schema.getPossibleTypes(interfaceType);
2258
+ const types = implementingTypes.map((type) => ({
2259
+ name: type.name,
2260
+ description: type.description || null
2261
+ }));
2262
+ types.sort((a, b) => a.name.localeCompare(b.name));
2263
+ return { interfaceName, types };
2264
+ }
2265
+
2266
+ function handleGetUnionMembers(schema, unionName) {
2267
+ const unionType = schema.getType(unionName);
2268
+ if (!unionType) {
2269
+ return {
2270
+ unionName,
2271
+ members: [],
2272
+ error: `Type "${unionName}" not found in schema`
2273
+ };
2274
+ }
2275
+ if (!isUnionType(unionType)) {
2276
+ return {
2277
+ unionName,
2278
+ members: [],
2279
+ error: `Type "${unionName}" is not a union`
2280
+ };
2281
+ }
2282
+ const memberTypes = unionType.getTypes();
2283
+ const members = memberTypes.map((type) => ({
2284
+ name: type.name,
2285
+ description: type.description || null
2286
+ }));
2287
+ members.sort((a, b) => a.name.localeCompare(b.name));
2288
+ return { unionName, members };
2289
+ }
2290
+
2291
+ function getNamedType(type) {
2292
+ if (isNonNullType(type) || isListType(type)) {
2293
+ return getNamedType(type.ofType);
2294
+ }
2295
+ return "name" in type ? type.name : "";
2296
+ }
2297
+ function handleGetTypeUsage(schema, typeName) {
2298
+ const targetType = schema.getType(typeName);
2299
+ if (!targetType) {
2300
+ return {
2301
+ typeName,
2302
+ usages: [],
2303
+ error: `Type "${typeName}" not found in schema`
2304
+ };
2305
+ }
2306
+ const usages = [];
2307
+ const typeMap = schema.getTypeMap();
2308
+ for (const [name, type] of Object.entries(typeMap)) {
2309
+ if (name.startsWith("__")) {
2310
+ continue;
2311
+ }
2312
+ if (isObjectType(type) || isInterfaceType(type)) {
2313
+ const fields = type.getFields();
2314
+ for (const [fieldName, field] of Object.entries(fields)) {
2315
+ const returnTypeName = getNamedType(field.type);
2316
+ if (returnTypeName === typeName) {
2317
+ usages.push({
2318
+ typeName: name,
2319
+ fieldName,
2320
+ usageType: "return_type"
2321
+ });
2322
+ }
2323
+ for (const arg of field.args) {
2324
+ const argTypeName = getNamedType(arg.type);
2325
+ if (argTypeName === typeName) {
2326
+ usages.push({
2327
+ typeName: name,
2328
+ fieldName: `${fieldName}(${arg.name})`,
2329
+ usageType: "argument"
2330
+ });
2331
+ }
2332
+ }
2333
+ }
2334
+ }
2335
+ if (isInputObjectType(type)) {
2336
+ const fields = type.getFields();
2337
+ for (const [fieldName, field] of Object.entries(fields)) {
2338
+ const fieldTypeName = getNamedType(field.type);
2339
+ if (fieldTypeName === typeName) {
2340
+ usages.push({
2341
+ typeName: name,
2342
+ fieldName,
2343
+ usageType: "input_field"
2344
+ });
2345
+ }
2346
+ }
2347
+ }
2348
+ }
2349
+ usages.sort((a, b) => {
2350
+ const typeCompare = a.typeName.localeCompare(b.typeName);
2351
+ if (typeCompare !== 0) return typeCompare;
2352
+ return a.fieldName.localeCompare(b.fieldName);
2353
+ });
2354
+ return { typeName, usages };
2355
+ }
2356
+
2357
+ function handleGetFieldUsage(collector, schema, typeName, fieldName) {
2358
+ const type = schema.getType(typeName);
2359
+ if (!type) {
2360
+ return {
2361
+ typeName,
2362
+ fieldName,
2363
+ usages: [],
2364
+ error: `Type "${typeName}" not found in schema`
2365
+ };
2366
+ }
2367
+ if (!isObjectType(type) && !isInterfaceType(type)) {
2368
+ return {
2369
+ typeName,
2370
+ fieldName,
2371
+ usages: [],
2372
+ error: `Type "${typeName}" is not an object or interface type`
2373
+ };
2374
+ }
2375
+ const fields = type.getFields();
2376
+ if (!fields[fieldName]) {
2377
+ return {
2378
+ typeName,
2379
+ fieldName,
2380
+ usages: [],
2381
+ error: `Field "${fieldName}" not found on type "${typeName}"`
2382
+ };
2383
+ }
2384
+ const usages = [];
2385
+ const operations = collector.getOperations();
2386
+ const fragments = collector.getFragments();
2387
+ for (const operation of operations) {
2388
+ if (hasFieldUsage(schema, operation.source, typeName, fieldName)) {
2389
+ usages.push({
2390
+ kind: "operation",
2391
+ name: operation.name,
2392
+ filePath: operation.relativeFilePath
2393
+ });
2394
+ }
2395
+ }
2396
+ for (const fragment of fragments) {
2397
+ if (hasFieldUsage(schema, fragment.source, typeName, fieldName)) {
2398
+ usages.push({
2399
+ kind: "fragment",
2400
+ name: fragment.name,
2401
+ filePath: fragment.relativeFilePath
2402
+ });
2403
+ }
2404
+ }
2405
+ return {
2406
+ typeName,
2407
+ fieldName,
2408
+ usages
2409
+ };
2410
+ }
2411
+ function hasFieldUsage(schema, source, targetTypeName, targetFieldName) {
2412
+ try {
2413
+ const document = parse(source);
2414
+ const typeInfo = new TypeInfo(schema);
2415
+ let found = false;
2416
+ visit(
2417
+ document,
2418
+ visitWithTypeInfo(typeInfo, {
2419
+ Field: {
2420
+ enter(node) {
2421
+ if (found) return;
2422
+ const parentType = typeInfo.getParentType();
2423
+ if (!parentType) return;
2424
+ const parentTypeName = parentType.name;
2425
+ const fieldName = node.name.value;
2426
+ if (parentTypeName === targetTypeName && fieldName === targetFieldName) {
2427
+ found = true;
2428
+ return;
2429
+ }
2430
+ if (isObjectType(parentType)) {
2431
+ const interfaces = parentType.getInterfaces();
2432
+ for (const iface of interfaces) {
2433
+ if (iface.name === targetTypeName && fieldName === targetFieldName) {
2434
+ const ifaceFields = iface.getFields();
2435
+ if (ifaceFields[targetFieldName]) {
2436
+ found = true;
2437
+ return;
2438
+ }
2439
+ }
2440
+ }
2441
+ }
2442
+ const targetType = schema.getType(targetTypeName);
2443
+ if (targetType && isObjectType(targetType)) {
2444
+ const targetInterfaces = targetType.getInterfaces();
2445
+ for (const iface of targetInterfaces) {
2446
+ if (parentTypeName === iface.name && fieldName === targetFieldName) {
2447
+ found = true;
2448
+ return;
2449
+ }
2450
+ }
2451
+ }
2452
+ }
2453
+ }
2454
+ })
2455
+ );
2456
+ return found;
2457
+ } catch {
2458
+ return false;
2459
+ }
2460
+ }
2461
+
2462
+ function collectFragmentInfo(documentSource) {
2463
+ const usedFragments = /* @__PURE__ */ new Set();
2464
+ const definedFragments = /* @__PURE__ */ new Set();
2465
+ try {
2466
+ const document = parse(documentSource);
2467
+ visit(document, {
2468
+ FragmentSpread(node) {
2469
+ usedFragments.add(node.name.value);
2470
+ },
2471
+ FragmentDefinition(node) {
2472
+ definedFragments.add(node.name.value);
2473
+ }
2474
+ });
2475
+ } catch {
2476
+ }
2477
+ return { usedFragments, definedFragments };
2478
+ }
2479
+ function collectRequiredFragments(fragmentNames, collector, collected = /* @__PURE__ */ new Map()) {
2480
+ for (const name of fragmentNames) {
2481
+ if (collected.has(name)) {
2482
+ continue;
2483
+ }
2484
+ const fragment = collector.getFragment(name);
2485
+ if (!fragment) {
2486
+ continue;
2487
+ }
2488
+ collected.set(name, fragment.source);
2489
+ if (fragment.dependencies.length > 0) {
2490
+ collectRequiredFragments(
2491
+ new Set(fragment.dependencies),
2492
+ collector,
2493
+ collected
2494
+ );
2495
+ }
2496
+ }
2497
+ return collected;
2498
+ }
2499
+ function handleValidateDocument(schema, collector, documentSource) {
2500
+ try {
2501
+ const { usedFragments, definedFragments } = collectFragmentInfo(documentSource);
2502
+ const missingFragments = /* @__PURE__ */ new Set();
2503
+ for (const name of usedFragments) {
2504
+ if (!definedFragments.has(name)) {
2505
+ missingFragments.add(name);
2506
+ }
2507
+ }
2508
+ const requiredFragments = collectRequiredFragments(
2509
+ missingFragments,
2510
+ collector
2511
+ );
2512
+ let fullDocument = documentSource;
2513
+ if (requiredFragments.size > 0) {
2514
+ const fragmentSources = [...requiredFragments.values()].join("\n\n");
2515
+ fullDocument = `${documentSource}
2516
+
2517
+ ${fragmentSources}`;
2518
+ }
2519
+ const source = new Source(fullDocument, "input");
2520
+ const document = parse(source);
2521
+ const errors = validateGraphQlDocuments(schema, [document]);
2522
+ if (errors.length === 0) {
2523
+ return {
2524
+ valid: true,
2525
+ errors: []
2526
+ };
2527
+ }
2528
+ return {
2529
+ valid: false,
2530
+ errors: errors.map((error) => ({
2531
+ message: error.message,
2532
+ locations: error.locations?.map((loc) => ({
2533
+ line: loc.line,
2534
+ column: loc.column
2535
+ }))
2536
+ }))
2537
+ };
2538
+ } catch (error) {
2539
+ const message = error instanceof Error ? error.message : "Unknown parsing error";
2540
+ const locations = error && typeof error === "object" && "locations" in error && Array.isArray(error.locations) ? error.locations.map((loc) => ({
2541
+ line: loc.line,
2542
+ column: loc.column
2543
+ })) : void 0;
2544
+ return {
2545
+ valid: false,
2546
+ errors: [{ message, locations }]
2547
+ };
2548
+ }
2549
+ }
2550
+
2551
+ function getMockValueForType$1(typeNode, varName) {
2552
+ if (typeNode.kind === "NonNullType") {
2553
+ return getMockValueForType$1(typeNode.type, varName);
2554
+ }
2555
+ if (typeNode.kind === "ListType") {
2556
+ const innerValue = getMockValueForType$1(typeNode.type, varName);
2557
+ return `[${innerValue}]`;
2558
+ }
2559
+ if (typeNode.kind === "NamedType") {
2560
+ const typeName = typeNode.name.value;
2561
+ switch (typeName) {
2562
+ case "String":
2563
+ return `'${varName}_value'`;
2564
+ case "Int":
2565
+ return "1";
2566
+ case "Float":
2567
+ return "1.0";
2568
+ case "Boolean":
2569
+ return "true";
2570
+ case "ID":
2571
+ return `'${varName}_id'`;
2572
+ default:
2573
+ return `{ /* placeholder for: ${typeName} */ }`;
2574
+ }
2575
+ }
2576
+ return `'${varName}'`;
2577
+ }
2578
+ function formatType$1(typeNode) {
2579
+ if (typeNode.kind === "NonNullType") {
2580
+ return `${formatType$1(typeNode.type)}!`;
2581
+ }
2582
+ if (typeNode.kind === "ListType") {
2583
+ return `[${formatType$1(typeNode.type)}]`;
2584
+ }
2585
+ if (typeNode.kind === "NamedType") {
2586
+ return typeNode.name.value;
2587
+ }
2588
+ return "unknown";
2589
+ }
2590
+ function getBaseTypeName$1(typeNode) {
2591
+ if (typeNode.kind === "NonNullType") {
2592
+ return getBaseTypeName$1(typeNode.type);
2593
+ }
2594
+ if (typeNode.kind === "ListType") {
2595
+ return getBaseTypeName$1(typeNode.type);
2596
+ }
2597
+ if (typeNode.kind === "NamedType") {
2598
+ return typeNode.name.value;
2599
+ }
2600
+ return null;
2601
+ }
2602
+ function extractVariables$1(source) {
2603
+ try {
2604
+ const doc = parse(source);
2605
+ const operation = doc.definitions.find(
2606
+ (def) => def.kind === "OperationDefinition"
2607
+ );
2608
+ if (!operation || operation.kind !== "OperationDefinition") {
2609
+ return [];
2610
+ }
2611
+ const variables = operation.variableDefinitions || [];
2612
+ return variables.map((varDef) => ({
2613
+ name: varDef.variable.name.value,
2614
+ type: formatType$1(varDef.type),
2615
+ mockValue: getMockValueForType$1(varDef.type, varDef.variable.name.value)
2616
+ }));
2617
+ } catch {
2618
+ return [];
2619
+ }
2620
+ }
2621
+ function extractVariableTypeNames$1(source) {
2622
+ try {
2623
+ const doc = parse(source);
2624
+ const operation = doc.definitions.find(
2625
+ (def) => def.kind === "OperationDefinition"
2626
+ );
2627
+ if (!operation || operation.kind !== "OperationDefinition") {
2628
+ return [];
2629
+ }
2630
+ const typeNames = /* @__PURE__ */ new Set();
2631
+ const variables = operation.variableDefinitions || [];
2632
+ for (const varDef of variables) {
2633
+ const typeName = getBaseTypeName$1(varDef.type);
2634
+ if (typeName) {
2635
+ typeNames.add(typeName);
2636
+ }
2637
+ }
2638
+ return Array.from(typeNames);
2639
+ } catch {
2640
+ return [];
2641
+ }
2642
+ }
2643
+ function buildImports$1(schema, variablesTypeName, responseTypeName, variableTypeNames, hasVariables) {
2644
+ const imports = [];
2645
+ imports.push({
2646
+ typeName: responseTypeName,
2647
+ description: "Response type for the operation"
2648
+ });
2649
+ if (hasVariables) {
2650
+ imports.push({
2651
+ typeName: variablesTypeName,
2652
+ description: "Variables type for the operation"
2653
+ });
2654
+ }
2655
+ for (const typeName of variableTypeNames) {
2656
+ const schemaType = schema.getType(typeName);
2657
+ if (!schemaType) continue;
2658
+ if (isScalarType(schemaType)) continue;
2659
+ if (isEnumType(schemaType)) {
2660
+ imports.push({
2661
+ typeName,
2662
+ description: `Enum type used in variables`
2663
+ });
2664
+ } else if (isInputObjectType(schemaType)) {
2665
+ imports.push({
2666
+ typeName,
2667
+ description: `Input object type used in variables`
2668
+ });
2669
+ }
2670
+ }
2671
+ return imports;
2672
+ }
2673
+ function generateExamples$1(operationName, operationType, variables, variablesTypeName, responseTypeName) {
2674
+ const examples = [];
2675
+ const hasVariables = variables.length > 0;
2676
+ const variablesObject = hasVariables ? `{ ${variables.map((v) => `${v.name}: ${v.mockValue}`).join(", ")} }` : "";
2677
+ const variablesObjectIndented = hasVariables ? `{
2678
+ ${variables.map((v) => `${v.name}: ${v.mockValue}`).join(",\n ")},
2679
+ }` : "";
2680
+ if (operationType === "query") {
2681
+ const transformDescription = `// The type of "graphqlResponse.data" is ${responseTypeName}. Prepare the data here before returning it.`;
2682
+ if (hasVariables) {
2683
+ examples.push({
2684
+ description: COMPOSABLES.useAsyncGraphqlQuery.description,
2685
+ documentationUrl: COMPOSABLES.useAsyncGraphqlQuery.docsUrl,
2686
+ code: `import type { ${variablesTypeName} } from '#graphql-operations'
2687
+
2688
+ const variables = computed<${variablesTypeName}>(() => {
2689
+ return ${variablesObjectIndented}
2690
+ })
2691
+
2692
+ const { data } = await useAsyncGraphqlQuery(
2693
+ '${operationName}',
2694
+ variables,
2695
+ // Same options as useAsyncData.
2696
+ {
2697
+ transform: function (graphqlResponse) {
2698
+ // ${transformDescription}
2699
+ return graphqlResponse.data
2700
+ },
2701
+ },
2702
+ )
2703
+
2704
+ // data is reactive, data.value is ${responseTypeName} | undefined
2705
+ console.log(data.value)`
2706
+ });
2707
+ } else {
2708
+ examples.push({
2709
+ description: COMPOSABLES.useAsyncGraphqlQuery.description,
2710
+ documentationUrl: COMPOSABLES.useAsyncGraphqlQuery.docsUrl,
2711
+ code: `const { data } = await useAsyncGraphqlQuery(
2712
+ '${operationName}',
2713
+ null,
2714
+ // Same options as useAsyncData.
2715
+ {
2716
+ transform: function (graphqlResponse) {
2717
+ // ${transformDescription}
2718
+ return graphqlResponse.data
2719
+ },
2720
+ },
2721
+ )
2722
+
2723
+ // data is reactive, data.value is ${responseTypeName} | undefined
2724
+ console.log(data.value)`
2725
+ });
2726
+ }
2727
+ if (hasVariables) {
2728
+ examples.push({
2729
+ description: COMPOSABLES.useGraphqlQuery.description,
2730
+ documentationUrl: COMPOSABLES.useGraphqlQuery.docsUrl,
2731
+ code: `const response = await useGraphqlQuery('${operationName}', ${variablesObject})
2732
+
2733
+ // response.data is ${responseTypeName} | undefined
2734
+ console.log(response.data)`
2735
+ });
2736
+ } else {
2737
+ examples.push({
2738
+ description: COMPOSABLES.useGraphqlQuery.description,
2739
+ documentationUrl: COMPOSABLES.useGraphqlQuery.docsUrl,
2740
+ code: `const response = await useGraphqlQuery('${operationName}')
2741
+
2742
+ // response.data is ${responseTypeName} | undefined
2743
+ console.log(response.data)`
2744
+ });
2745
+ }
2746
+ } else {
2747
+ if (hasVariables) {
2748
+ examples.push({
2749
+ description: COMPOSABLES.useGraphqlMutation.description,
2750
+ documentationUrl: COMPOSABLES.useGraphqlMutation.docsUrl,
2751
+ code: `const response = await useGraphqlMutation('${operationName}', ${variablesObject})
2752
+
2753
+ // response.data is ${responseTypeName} | undefined
2754
+ console.log(response.data)`
2755
+ });
2756
+ } else {
2757
+ examples.push({
2758
+ description: COMPOSABLES.useGraphqlMutation.description,
2759
+ documentationUrl: COMPOSABLES.useGraphqlMutation.docsUrl,
2760
+ code: `const response = await useGraphqlMutation('${operationName}')
2761
+
2762
+ // response.data is ${responseTypeName} | undefined
2763
+ console.log(response.data)`
2764
+ });
2765
+ }
2766
+ }
2767
+ return examples;
2768
+ }
2769
+ function handleGetComposableExamples(collector, schema, operationName) {
2770
+ const operations = collector.getOperations();
2771
+ const operation = operations.find((op) => op.name === operationName);
2772
+ if (!operation) {
2773
+ return { error: `Operation "${operationName}" not found` };
2774
+ }
2775
+ const variables = extractVariables$1(operation.source);
2776
+ const variableTypeNames = extractVariableTypeNames$1(operation.source);
2777
+ const examples = generateExamples$1(
2778
+ operationName,
2779
+ operation.type,
2780
+ variables,
2781
+ operation.variablesTypeName,
2782
+ operation.responseTypeName
2783
+ );
2784
+ const imports = buildImports$1(
2785
+ schema,
2786
+ operation.variablesTypeName,
2787
+ operation.responseTypeName,
2788
+ variableTypeNames,
2789
+ variables.length > 0
2790
+ );
2791
+ return { examples, imports };
2792
+ }
2793
+
2794
+ function getMockValueForType(typeNode, varName) {
2795
+ if (typeNode.kind === "NonNullType") {
2796
+ return getMockValueForType(typeNode.type, varName);
2797
+ }
2798
+ if (typeNode.kind === "ListType") {
2799
+ const innerValue = getMockValueForType(typeNode.type, varName);
2800
+ return `[${innerValue}]`;
2801
+ }
2802
+ if (typeNode.kind === "NamedType") {
2803
+ const typeName = typeNode.name.value;
2804
+ switch (typeName) {
2805
+ case "String":
2806
+ return `'${varName}_value'`;
2807
+ case "Int":
2808
+ return "1";
2809
+ case "Float":
2810
+ return "1.0";
2811
+ case "Boolean":
2812
+ return "true";
2813
+ case "ID":
2814
+ return `'${varName}_id'`;
2815
+ default:
2816
+ return `{ /* placeholder for: ${typeName} */ }`;
2817
+ }
2818
+ }
2819
+ return `'${varName}'`;
2820
+ }
2821
+ function formatType(typeNode) {
2822
+ if (typeNode.kind === "NonNullType") {
2823
+ return `${formatType(typeNode.type)}!`;
2824
+ }
2825
+ if (typeNode.kind === "ListType") {
2826
+ return `[${formatType(typeNode.type)}]`;
2827
+ }
2828
+ if (typeNode.kind === "NamedType") {
2829
+ return typeNode.name.value;
2830
+ }
2831
+ return "unknown";
2832
+ }
2833
+ function getBaseTypeName(typeNode) {
2834
+ if (typeNode.kind === "NonNullType") {
2835
+ return getBaseTypeName(typeNode.type);
2836
+ }
2837
+ if (typeNode.kind === "ListType") {
2838
+ return getBaseTypeName(typeNode.type);
2839
+ }
2840
+ if (typeNode.kind === "NamedType") {
2841
+ return typeNode.name.value;
2842
+ }
2843
+ return null;
2844
+ }
2845
+ function extractVariables(source) {
2846
+ try {
2847
+ const doc = parse(source);
2848
+ const operation = doc.definitions.find(
2849
+ (def) => def.kind === "OperationDefinition"
2850
+ );
2851
+ if (!operation || operation.kind !== "OperationDefinition") {
2852
+ return [];
2853
+ }
2854
+ const variables = operation.variableDefinitions || [];
2855
+ return variables.map((varDef) => ({
2856
+ name: varDef.variable.name.value,
2857
+ type: formatType(varDef.type),
2858
+ mockValue: getMockValueForType(varDef.type, varDef.variable.name.value)
2859
+ }));
2860
+ } catch {
2861
+ return [];
2862
+ }
2863
+ }
2864
+ function extractVariableTypeNames(source) {
2865
+ try {
2866
+ const doc = parse(source);
2867
+ const operation = doc.definitions.find(
2868
+ (def) => def.kind === "OperationDefinition"
2869
+ );
2870
+ if (!operation || operation.kind !== "OperationDefinition") {
2871
+ return [];
2872
+ }
2873
+ const typeNames = /* @__PURE__ */ new Set();
2874
+ const variables = operation.variableDefinitions || [];
2875
+ for (const varDef of variables) {
2876
+ const typeName = getBaseTypeName(varDef.type);
2877
+ if (typeName) {
2878
+ typeNames.add(typeName);
2879
+ }
2880
+ }
2881
+ return Array.from(typeNames);
2882
+ } catch {
2883
+ return [];
2884
+ }
2885
+ }
2886
+ function buildImports(schema, variablesTypeName, responseTypeName, variableTypeNames, hasVariables) {
2887
+ const imports = [];
2888
+ imports.push({
2889
+ typeName: responseTypeName,
2890
+ description: "Response type for the operation"
2891
+ });
2892
+ if (hasVariables) {
2893
+ imports.push({
2894
+ typeName: variablesTypeName,
2895
+ description: "Variables type for the operation"
2896
+ });
2897
+ }
2898
+ for (const typeName of variableTypeNames) {
2899
+ const schemaType = schema.getType(typeName);
2900
+ if (!schemaType) continue;
2901
+ if (isScalarType(schemaType)) continue;
2902
+ if (isEnumType(schemaType)) {
2903
+ imports.push({
2904
+ typeName,
2905
+ description: `Enum type used in variables`
2906
+ });
2907
+ } else if (isInputObjectType(schemaType)) {
2908
+ imports.push({
2909
+ typeName,
2910
+ description: `Input object type used in variables`
2911
+ });
2912
+ }
2913
+ }
2914
+ return imports;
2915
+ }
2916
+ function generateExamples(operationName, operationType, variables, responseTypeName) {
2917
+ const examples = [];
2918
+ const hasVariables = variables.length > 0;
2919
+ const variablesObject = hasVariables ? `{ ${variables.map((v) => `${v.name}: ${v.mockValue}`).join(", ")} }` : "";
2920
+ if (operationType === "query") {
2921
+ if (hasVariables) {
2922
+ examples.push({
2923
+ description: SERVER_UTILS.useGraphqlQuery.description,
2924
+ documentationUrl: SERVER_UTILS.useGraphqlQuery.docsUrl,
2925
+ code: `export default defineEventHandler(async (event) => {
2926
+ const response = await useGraphqlQuery('${operationName}', ${variablesObject})
2927
+
2928
+ // response.data is ${responseTypeName} | undefined
2929
+ return response.data
2930
+ })`
2931
+ });
2932
+ } else {
2933
+ examples.push({
2934
+ description: SERVER_UTILS.useGraphqlQuery.description,
2935
+ documentationUrl: SERVER_UTILS.useGraphqlQuery.docsUrl,
2936
+ code: `export default defineEventHandler(async (event) => {
2937
+ const response = await useGraphqlQuery('${operationName}')
2938
+
2939
+ // response.data is ${responseTypeName} | undefined
2940
+ return response.data
2941
+ })`
2942
+ });
2943
+ }
2944
+ } else {
2945
+ if (hasVariables) {
2946
+ examples.push({
2947
+ description: SERVER_UTILS.useGraphqlMutation.description,
2948
+ documentationUrl: SERVER_UTILS.useGraphqlMutation.docsUrl,
2949
+ code: `export default defineEventHandler(async (event) => {
2950
+ const response = await useGraphqlMutation('${operationName}', ${variablesObject})
2951
+
2952
+ // response.data is ${responseTypeName} | undefined
2953
+ return response.data
2954
+ })`
2955
+ });
2956
+ } else {
2957
+ examples.push({
2958
+ description: SERVER_UTILS.useGraphqlMutation.description,
2959
+ documentationUrl: SERVER_UTILS.useGraphqlMutation.docsUrl,
2960
+ code: `export default defineEventHandler(async (event) => {
2961
+ const response = await useGraphqlMutation('${operationName}')
2962
+
2963
+ // response.data is ${responseTypeName} | undefined
2964
+ return response.data
2965
+ })`
2966
+ });
2967
+ }
2968
+ }
2969
+ examples.push({
2970
+ description: SERVER_UTILS.doGraphqlRequest.description,
2971
+ documentationUrl: SERVER_UTILS.doGraphqlRequest.docsUrl,
2972
+ code: `export default defineEventHandler(async (event) => {
2973
+ // Use doGraphqlRequest for raw GraphQL requests with custom query strings
2974
+ const response = await doGraphqlRequest({
2975
+ query: \`
2976
+ ${operationType} ${operationName}${hasVariables ? `(${variables.map((v) => `$${v.name}: ${v.type}`).join(", ")})` : ""} {
2977
+ # Your query fields here
2978
+ }
2979
+ \`,${hasVariables ? `
2980
+ variables: ${variablesObject},` : ""}
2981
+ operationName: '${operationName}',
2982
+ })
2983
+
2984
+ return response.data
2985
+ })`
2986
+ });
2987
+ return examples;
2988
+ }
2989
+ function handleGetServerUtilsExamples(collector, schema, operationName) {
2990
+ const operations = collector.getOperations();
2991
+ const operation = operations.find((op) => op.name === operationName);
2992
+ if (!operation) {
2993
+ return { error: `Operation "${operationName}" not found` };
2994
+ }
2995
+ const variables = extractVariables(operation.source);
2996
+ const variableTypeNames = extractVariableTypeNames(operation.source);
2997
+ const examples = generateExamples(
2998
+ operationName,
2999
+ operation.type,
3000
+ variables,
3001
+ operation.responseTypeName
3002
+ );
3003
+ const imports = buildImports(
3004
+ schema,
3005
+ operation.variablesTypeName,
3006
+ operation.responseTypeName,
3007
+ variableTypeNames,
3008
+ variables.length > 0
3009
+ );
3010
+ return { examples, imports };
3011
+ }
3012
+
3013
+ function makeRelative(rootDir, path) {
3014
+ if (!path) {
3015
+ return null;
3016
+ }
3017
+ if (isAbsolute(path)) {
3018
+ const rel = relative$1(rootDir, path);
3019
+ if (!rel.startsWith(".")) {
3020
+ return "./" + rel;
3021
+ }
3022
+ return rel;
3023
+ }
3024
+ if (!path.startsWith(".")) {
3025
+ return "./" + path;
3026
+ }
3027
+ return path;
3028
+ }
3029
+ function handleGetModuleConfig(helper) {
3030
+ const rootDir = helper.nuxt.options.rootDir;
3031
+ return {
3032
+ autoImportPatterns: (helper.options.autoImportPatterns || []).map(
3033
+ (pattern) => makeRelative(rootDir, pattern)
3034
+ ),
3035
+ paths: {
3036
+ runtimeTypes: makeRelative(rootDir, helper.paths.runtimeTypes),
3037
+ schema: makeRelative(rootDir, helper.paths.schema),
3038
+ serverOptions: makeRelative(rootDir, helper.paths.serverOptions),
3039
+ clientOptions: makeRelative(rootDir, helper.paths.clientOptions),
3040
+ documentTypes: makeRelative(
3041
+ rootDir,
3042
+ helper.paths.moduleTypesDir + "/index.d.ts"
3043
+ )
3044
+ }
3045
+ };
3046
+ }
3047
+
3048
+ function requireName(body) {
3049
+ const name = body.name;
3050
+ if (!name) {
3051
+ throw createError({
3052
+ statusCode: 400,
3053
+ message: 'Missing "name" parameter in request body'
3054
+ });
3055
+ }
3056
+ return name;
3057
+ }
3058
+ function createMcpDevHandler(collector, schemaProvider, helper) {
3059
+ return defineEventHandler(async (event) => {
3060
+ const body = await readBody(event);
3061
+ const tool = body?.tool;
3062
+ if (!tool) {
3063
+ throw createError({
3064
+ statusCode: 400,
3065
+ message: 'Missing "tool" parameter in request body'
3066
+ });
3067
+ }
3068
+ switch (tool) {
3069
+ // Operation tools
3070
+ case "operations-list":
3071
+ return handleListOperations(
3072
+ collector,
3073
+ body.nameFilter,
3074
+ body.type
3075
+ );
3076
+ case "operations-get":
3077
+ return handleGetOperation(collector, requireName(body));
3078
+ case "operations-get-source":
3079
+ return handleGetOperationSource(
3080
+ collector,
3081
+ requireName(body),
3082
+ body.includeDependencies
3083
+ );
3084
+ // Fragment tools
3085
+ case "fragments-list":
3086
+ return handleListFragments(
3087
+ collector,
3088
+ body.nameFilter
3089
+ );
3090
+ case "fragments-get":
3091
+ return handleGetFragment(collector, requireName(body));
3092
+ case "fragments-get-source":
3093
+ return handleGetFragmentSource(
3094
+ collector,
3095
+ requireName(body),
3096
+ body.includeDependencies
3097
+ );
3098
+ case "fragments-list-for-type":
3099
+ return handleGetFragmentsForType(collector, requireName(body));
3100
+ // Schema tools
3101
+ case "schema-get-type":
3102
+ return handleGetSchemaType(
3103
+ schemaProvider.getSchema(),
3104
+ requireName(body)
3105
+ );
3106
+ case "schema-get-type-definition":
3107
+ return handleGetSchemaTypeDefinition(
3108
+ schemaProvider.getSchema(),
3109
+ requireName(body)
3110
+ );
3111
+ case "schema-list-types":
3112
+ return handleListSchemaTypes(
3113
+ schemaProvider.getSchema(),
3114
+ body.kind
3115
+ );
3116
+ case "schema-get-interface-implementors":
3117
+ return handleGetTypesImplementingInterface(
3118
+ schemaProvider.getSchema(),
3119
+ requireName(body)
3120
+ );
3121
+ case "schema-get-union-members":
3122
+ return handleGetUnionMembers(
3123
+ schemaProvider.getSchema(),
3124
+ requireName(body)
3125
+ );
3126
+ case "schema-get-type-usage":
3127
+ return handleGetTypeUsage(schemaProvider.getSchema(), requireName(body));
3128
+ case "operations-get-field-usage":
3129
+ return handleGetFieldUsage(
3130
+ collector,
3131
+ schemaProvider.getSchema(),
3132
+ body.typeName,
3133
+ body.fieldName
3134
+ );
3135
+ case "schema-validate-document":
3136
+ return handleValidateDocument(
3137
+ schemaProvider.getSchema(),
3138
+ collector,
3139
+ body.document
3140
+ );
3141
+ // Composable examples tool
3142
+ case "vue-graphql-composable-example":
3143
+ return handleGetComposableExamples(
3144
+ collector,
3145
+ schemaProvider.getSchema(),
3146
+ requireName(body)
3147
+ );
3148
+ // Server utils examples tool
3149
+ case "nitro-graphql-server-utils-example":
3150
+ return handleGetServerUtilsExamples(
3151
+ collector,
3152
+ schemaProvider.getSchema(),
3153
+ requireName(body)
3154
+ );
3155
+ // Module config tool
3156
+ case "module-get-config":
3157
+ return handleGetModuleConfig(helper);
3158
+ default:
3159
+ throw createError({
3160
+ statusCode: 400,
3161
+ message: `Unknown tool: ${tool}`
3162
+ });
3163
+ }
3164
+ });
3165
+ }
3166
+
3167
+ const module$1 = defineNuxtModule({
1726
3168
  meta: {
1727
3169
  name,
1728
3170
  configKey: "graphqlMiddleware",
@@ -1783,22 +3225,36 @@ const module = defineNuxtModule({
1783
3225
  collector.addTemplate(template);
1784
3226
  }
1785
3227
  });
1786
- helper.applyBuildConfig();
3228
+ if (helper.isDev) {
3229
+ const devModeHandler = new DevModeHandler(
3230
+ nuxt,
3231
+ schemaProvider,
3232
+ collector,
3233
+ helper
3234
+ );
3235
+ devModeHandler.init();
3236
+ }
3237
+ const mcpToolkitInstalled = nuxt.options.modules.some(
3238
+ (v) => v === "@nuxtjs/mcp-toolkit"
3239
+ );
3240
+ if (helper.isDev && mcpToolkitInstalled && helper.options.mcp.enabled) {
3241
+ nuxt.hook("mcp:definitions:paths", (paths) => {
3242
+ const mcpPath = helper.resolvers.module.resolve("./runtime/server/mcp");
3243
+ paths.handlers ||= [];
3244
+ paths.handlers.push(mcpPath);
3245
+ });
3246
+ addDevServerHandler({
3247
+ route: "/__nuxt_graphql_middleware/mcp",
3248
+ handler: createMcpDevHandler(collector, schemaProvider, helper)
3249
+ });
3250
+ helper.addServerHandler("doRequest", "/do-request", "post");
3251
+ }
1787
3252
  nuxt.hooks.hookOnce("modules:done", async () => {
1788
3253
  await nuxt.hooks.callHook("nuxt-graphql-middleware:init", moduleContext);
1789
3254
  await collector.init();
1790
3255
  });
1791
- if (!helper.isDev) {
1792
- return;
1793
- }
1794
- const devModeHandler = new DevModeHandler(
1795
- nuxt,
1796
- schemaProvider,
1797
- collector,
1798
- helper
1799
- );
1800
- devModeHandler.init();
3256
+ helper.applyBuildConfig();
1801
3257
  }
1802
3258
  });
1803
3259
 
1804
- export { module as default };
3260
+ export { module$1 as default };