@wpnuxt/core 1.0.0-edge.9 → 2.0.0-alpha.2

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/dist/client-options.d.mts +1 -0
  2. package/dist/client-options.d.ts +1 -0
  3. package/dist/client-options.mjs +1 -0
  4. package/dist/module.d.mts +72 -82
  5. package/dist/module.d.ts +72 -82
  6. package/dist/module.json +4 -5
  7. package/dist/module.mjs +601 -271
  8. package/dist/runtime/app/graphqlMiddleware.clientOptions.d.ts +0 -0
  9. package/dist/runtime/app/graphqlMiddleware.clientOptions.js +12 -0
  10. package/dist/runtime/components/WPNuxtLogo.d.vue.ts +0 -0
  11. package/dist/runtime/components/WPNuxtLogo.vue +7 -7
  12. package/dist/runtime/components/WPNuxtLogo.vue.d.ts +0 -0
  13. package/dist/runtime/composables/useWPContent.d.ts +0 -5
  14. package/dist/runtime/composables/useWPContent.js +30 -16
  15. package/dist/runtime/plugins/graphqlConfig.d.ts +0 -0
  16. package/dist/runtime/plugins/graphqlConfig.js +17 -0
  17. package/dist/runtime/plugins/graphqlErrors.d.ts +0 -0
  18. package/dist/runtime/plugins/graphqlErrors.js +9 -0
  19. package/dist/runtime/queries/GeneralSettings.gql +0 -2
  20. package/dist/runtime/queries/Menu.gql +0 -2
  21. package/dist/runtime/queries/Node.gql +0 -3
  22. package/dist/runtime/queries/Pages.gql +0 -2
  23. package/dist/runtime/queries/Posts.gql +15 -2
  24. package/dist/runtime/queries/Viewer.gql +4 -4
  25. package/dist/runtime/queries/fragments/GeneralSettings.fragment.gql +0 -1
  26. package/dist/runtime/queries/fragments/NodeWithFeaturedImage.fragment.gql +0 -2
  27. package/dist/runtime/queries/fragments/NodeWithFeaturedImageToMediaItemConnectionEdge.fragment.gql +0 -2
  28. package/dist/runtime/queries/fragments/Page.fragment.gql +0 -4
  29. package/dist/runtime/queries/fragments/Post.fragment.gql +8 -5
  30. package/dist/runtime/server/graphqlMiddleware.serverOptions.d.ts +0 -0
  31. package/dist/runtime/server/graphqlMiddleware.serverOptions.js +18 -0
  32. package/dist/runtime/server/tsconfig.json +3 -0
  33. package/dist/runtime/types/stub.d.ts +22 -0
  34. package/dist/runtime/util/images.d.ts +0 -2
  35. package/dist/runtime/util/images.js +11 -3
  36. package/dist/server-options.d.mts +2 -0
  37. package/dist/server-options.d.ts +2 -0
  38. package/dist/server-options.mjs +1 -0
  39. package/dist/types.d.mts +2 -2
  40. package/package.json +50 -79
  41. package/README.md +0 -80
  42. package/dist/module.cjs +0 -5
  43. package/dist/runtime/app/graphqlMiddleware.serverOptions.d.ts +0 -2
  44. package/dist/runtime/app/graphqlMiddleware.serverOptions.js +0 -11
  45. package/dist/runtime/components/StagingBanner.vue +0 -107
  46. package/dist/runtime/components/WordPressLogo.vue +0 -15
  47. package/dist/runtime/composables/index.d.ts +0 -3
  48. package/dist/runtime/composables/index.js +0 -3
  49. package/dist/runtime/composables/isStaging.d.ts +0 -1
  50. package/dist/runtime/composables/isStaging.js +0 -6
  51. package/dist/runtime/composables/useFeaturedImage.d.ts +0 -2
  52. package/dist/runtime/composables/useFeaturedImage.js +0 -7
  53. package/dist/runtime/composables/usePrevNextPost.d.ts +0 -4
  54. package/dist/runtime/composables/usePrevNextPost.js +0 -25
  55. package/dist/runtime/composables/useWPUri.d.ts +0 -8
  56. package/dist/runtime/composables/useWPUri.js +0 -23
  57. package/dist/runtime/plugins/vue-sanitize-directive.d.ts +0 -2
  58. package/dist/runtime/plugins/vue-sanitize-directive.js +0 -5
  59. package/dist/runtime/server/api/purgeCache.get.d.ts +0 -5
  60. package/dist/runtime/server/api/purgeCache.get.js +0 -9
  61. package/dist/runtime/server/api/wpContent.post.d.ts +0 -9
  62. package/dist/runtime/server/api/wpContent.post.js +0 -50
  63. package/dist/runtime/server/index.d.ts +0 -1
  64. package/dist/runtime/server/index.js +0 -8
  65. package/dist/runtime/server/storage.d.ts +0 -3
  66. package/dist/runtime/server/storage.js +0 -11
  67. package/dist/runtime/util/logger.d.ts +0 -3
  68. package/dist/runtime/util/logger.js +0 -25
  69. package/dist/types.d.ts +0 -7
package/dist/module.mjs CHANGED
@@ -1,70 +1,77 @@
1
- import { promises, statSync, existsSync, cpSync } from 'node:fs';
2
- import { resolveFiles, defineNuxtModule, createResolver, addPlugin, addImports, addComponent, addServerHandler, installModule, hasNuxtModule, addTemplate, addTypeTemplate } from '@nuxt/kit';
3
- import { join } from 'pathe';
4
- import consola, { createConsola } from 'consola';
5
- import { ref } from 'vue';
1
+ import { defu } from 'defu';
2
+ import { promises, cpSync, existsSync, statSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { useLogger, createResolver, resolveFiles, defineNuxtModule, addPlugin, addImports, addComponentsDir, addTemplate, addTypeTemplate, hasNuxtModule, installModule } from '@nuxt/kit';
6
5
  import { upperFirst } from 'scule';
7
- import { parse } from 'graphql';
8
-
9
- const name = "@wpnuxt/core";
10
- const version = "1.0.0-edge.9";
6
+ import { ref } from 'vue';
7
+ import { parse, GraphQLError } from 'graphql';
8
+ import { execSync } from 'node:child_process';
11
9
 
10
+ function randHashGenerator(length = 12) {
11
+ return Math.random().toString(36).substring(2, 2 + length).toUpperCase().padEnd(length, "0");
12
+ }
12
13
  const loggerRef = ref();
13
- const initLogger = (logLevel) => {
14
- loggerRef.value = createConsola({
15
- level: logLevel ? logLevel : 3,
16
- formatOptions: {
17
- colors: true,
18
- compact: true,
19
- date: true,
20
- fancy: true
21
- }
22
- }).withTag("wpnuxt");
14
+ const initLogger = (debug) => {
15
+ loggerRef.value = useLogger("wpnuxt", { level: debug ? 4 : 3 });
23
16
  return loggerRef.value;
24
17
  };
25
- const getLogger = () => {
26
- if (loggerRef.value) {
27
- return loggerRef.value;
28
- }
29
- };
30
- function validateConfig(options) {
31
- if (!options.wordpressUrl || options.wordpressUrl.length === 0) {
32
- throw new Error("WPNuxt error: WordPress url is missing");
33
- } else if (options.wordpressUrl.substring(options.wordpressUrl.length - 1) === "/") {
34
- throw new Error("WPNuxt error: WordPress url should not have a trailing slash: " + options.wordpressUrl);
35
- }
36
- if (options.frontendUrl && options.frontendUrl.substring(options.frontendUrl.length - 1) === "/") {
37
- throw new Error("WPNuxt error: frontend url should not have a trailing slash: " + options.frontendUrl);
18
+ function getLogger() {
19
+ return loggerRef.value;
20
+ }
21
+ async function mergeQueries(nuxt, wpNuxtConfig, resolver) {
22
+ const logger = getLogger();
23
+ const baseDir = nuxt.options.srcDir || nuxt.options.rootDir;
24
+ const { resolve } = createResolver(baseDir);
25
+ const queryOutputPath = resolve(wpNuxtConfig.queries.mergedOutputFolder);
26
+ const userQueryPath = resolve(wpNuxtConfig.queries.extendFolder);
27
+ const defaultQueriesPath = resolver.resolve("./runtime/queries");
28
+ await promises.rm(queryOutputPath, { recursive: true, force: true });
29
+ cpSync(defaultQueriesPath, queryOutputPath, { recursive: true });
30
+ if (existsSync(userQueryPath)) {
31
+ logger.debug("Extending queries:", userQueryPath);
32
+ cpSync(userQueryPath, queryOutputPath, { recursive: true });
38
33
  }
34
+ logger.debug("Merged queries folder:", queryOutputPath);
35
+ return queryOutputPath;
39
36
  }
40
37
 
41
38
  const _parseDoc = async (doc) => {
42
- const { definitions } = parse(doc);
43
- const operations = definitions.filter(({ kind }) => kind === "OperationDefinition").map((definition) => {
44
- const operationDefinition = definition;
45
- if (!operationDefinition.name?.value) {
46
- throw new Error(`Operation name missing in: ${doc}`);
39
+ if (!doc || typeof doc !== "string" || doc.trim().length === 0) {
40
+ throw new Error("WPNuxt: Invalid GraphQL document - document is empty or not a string");
41
+ }
42
+ try {
43
+ const { definitions } = parse(doc);
44
+ const operations = definitions.filter(({ kind }) => kind === "OperationDefinition").map((definition) => {
45
+ const operationDefinition = definition;
46
+ if (!operationDefinition.name?.value) {
47
+ throw new Error("WPNuxt: GraphQL operation is missing a name. All queries and mutations must have a name.");
48
+ }
49
+ const query = {
50
+ name: operationDefinition.name.value.trim(),
51
+ nodes: [],
52
+ fragments: [],
53
+ params: {},
54
+ operation: operationDefinition.operation
55
+ };
56
+ processSelections(operationDefinition.selectionSet.selections, 0, query);
57
+ return query;
58
+ });
59
+ return operations;
60
+ } catch (error) {
61
+ if (error instanceof GraphQLError) {
62
+ throw new TypeError(`WPNuxt: Failed to parse GraphQL document - ${error.message}`);
47
63
  }
48
- const query = {
49
- name: operationDefinition.name.value.trim(),
50
- nodes: [],
51
- fragments: [],
52
- params: {}
53
- };
54
- processSelections(operationDefinition.selectionSet.selections, 0, query);
55
- return query;
56
- });
57
- return operations;
64
+ throw error;
65
+ }
58
66
  };
59
67
  function processSelections(selections, level, query) {
60
- if (!selections || selections.length === 0)
61
- return;
62
- if (selections.length === 1 && selections[0].kind === "Field") {
63
- query.nodes.push(selections[0].name.value.trim());
68
+ if (!selections || selections.length === 0) return;
69
+ if (selections.length === 1 && selections[0]?.kind === "Field") {
70
+ query.nodes?.push(selections[0].name.value.trim());
64
71
  }
65
72
  selections.forEach((s) => {
66
73
  if (s.kind === "FragmentSpread") {
67
- query.fragments.push(s.name.value.trim());
74
+ query.fragments?.push(s.name.value.trim());
68
75
  } else if (s.selectionSet?.selections) {
69
76
  processSelections(s.selectionSet.selections, level + 1, query);
70
77
  }
@@ -72,248 +79,393 @@ function processSelections(selections, level, query) {
72
79
  }
73
80
  const parseDoc = _parseDoc;
74
81
 
82
+ const SCHEMA_PATTERN = /schema\.(?:gql|graphql)$/i;
83
+ const allowDocument = (f, resolver) => {
84
+ if (SCHEMA_PATTERN.test(f)) return false;
85
+ try {
86
+ return statSync(resolver.resolve(f)).size > 0;
87
+ } catch {
88
+ return false;
89
+ }
90
+ };
91
+ async function generateWPNuxtComposables(ctx, queryOutputPath, resolver) {
92
+ const gqlMatch = "**/*.{gql,graphql}";
93
+ const documents = [];
94
+ const files = (await resolveFiles(queryOutputPath, [gqlMatch, "!**/schemas"], { followSymbolicLinks: false })).filter((doc) => allowDocument(doc, resolver));
95
+ documents.push(...files);
96
+ ctx.docs = documents;
97
+ await prepareContext(ctx);
98
+ }
75
99
  async function prepareContext(ctx) {
76
100
  const logger = getLogger();
77
101
  if (ctx.docs) {
78
102
  await prepareFunctions(ctx);
79
103
  }
104
+ const queries = ctx.fns.filter((f) => f.operation === "query");
105
+ const mutations = ctx.fns.filter((f) => f.operation === "mutation");
80
106
  const fnName = (fn) => ctx.composablesPrefix + upperFirst(fn);
81
- const fnExp = (q, typed = false) => {
82
- const functionName = fnName(q.name);
107
+ const mutationFnName = (fn) => `useMutation${upperFirst(fn)}`;
108
+ const formatNodes = (nodes) => nodes?.map((n) => `'${n}'`).join(",") ?? "";
109
+ const getFragmentType = (q) => {
110
+ const fragmentSuffix = q.fragments?.length && q.nodes?.includes("nodes") ? "[]" : "";
111
+ return q.fragments?.length ? q.fragments.map((f) => `${f}Fragment${fragmentSuffix}`).join(" | ") : "any";
112
+ };
113
+ const queryFnExp = (q, typed = false, lazy = false) => {
114
+ const baseName = fnName(q.name);
115
+ const functionName = lazy ? `useLazy${q.name}` : baseName;
83
116
  if (!typed) {
84
- return `export const ${functionName} = (params) => useWPContent('${q.name}', [${q.nodes?.map((n) => `'${n}'`).join(",")}], false, params)`;
117
+ if (lazy) {
118
+ return `export const ${functionName} = (params, options) => useWPContent('${q.name}', [${formatNodes(q.nodes)}], false, params, { ...options, lazy: true })`;
119
+ }
120
+ return `export const ${functionName} = (params, options) => useWPContent('${q.name}', [${formatNodes(q.nodes)}], false, params, options)`;
85
121
  }
86
- const fragmentSuffix = q.fragments?.length && q.nodes?.includes("nodes") ? "[]" : "";
87
- const fragments = q.fragments?.length ? q.fragments.map((f) => `${f}Fragment${fragmentSuffix}`).join(" | ") : "any";
88
- return ` export const ${functionName}: (params?: ${q.name}QueryVariables) => AsyncData<${fragments}, FetchError | null | undefined>`;
122
+ return ` export const ${functionName}: (params?: ${q.name}QueryVariables, options?: WPContentOptions) => WPContentResult<${getFragmentType(q)}>`;
123
+ };
124
+ const mutationFnExp = (m, typed = false) => {
125
+ const functionName = mutationFnName(m.name);
126
+ if (!typed) {
127
+ return `export const ${functionName} = (variables, options) => useGraphqlMutation('${m.name}', variables, options)`;
128
+ }
129
+ return ` export const ${functionName}: (variables: ${m.name}MutationVariables, options?: WPMutationOptions) => Promise<WPMutationResult<${m.name}Mutation>>`;
130
+ };
131
+ ctx.generateImports = () => {
132
+ const imports = [];
133
+ queries.forEach((f) => {
134
+ imports.push(queryFnExp(f, false, false));
135
+ imports.push(queryFnExp(f, false, true));
136
+ });
137
+ mutations.forEach((m) => {
138
+ imports.push(mutationFnExp(m, false));
139
+ });
140
+ return imports.join("\n");
141
+ };
142
+ const typeSet = /* @__PURE__ */ new Set();
143
+ queries.forEach((o) => {
144
+ typeSet.add(`${o.name}QueryVariables`);
145
+ o.fragments?.forEach((f) => typeSet.add(`${f}Fragment`));
146
+ });
147
+ mutations.forEach((m) => {
148
+ typeSet.add(`${m.name}MutationVariables`);
149
+ typeSet.add(`${m.name}Mutation`);
150
+ });
151
+ ctx.generateDeclarations = () => {
152
+ const declarations = [
153
+ `import type { ${[...typeSet].join(", ")} } from '#build/graphql-operations'`,
154
+ "import type { ComputedRef, Ref } from 'vue'",
155
+ "import type { AsyncDataRequestStatus } from '#app'",
156
+ "import type { GraphqlResponse } from 'nuxt-graphql-middleware/types'",
157
+ "",
158
+ "export interface WPContentOptions {",
159
+ " /** Whether to resolve the async function after loading the route, instead of blocking client-side navigation. Default: false */",
160
+ " lazy?: boolean",
161
+ " /** Whether to fetch data on the server (during SSR). Default: true */",
162
+ " server?: boolean",
163
+ " /** Whether to fetch immediately. Default: true */",
164
+ " immediate?: boolean",
165
+ " /** Watch reactive sources to auto-refresh */",
166
+ " watch?: unknown[]",
167
+ " /** Transform function to alter the result */",
168
+ " transform?: (input: unknown) => unknown",
169
+ " /** Additional options to pass to useAsyncGraphqlQuery */",
170
+ " [key: string]: unknown",
171
+ "}",
172
+ "",
173
+ "export interface WPMutationOptions {",
174
+ " /** Fetch options to pass to the request */",
175
+ " fetchOptions?: RequestInit",
176
+ " /** Additional options */",
177
+ " [key: string]: unknown",
178
+ "}",
179
+ "",
180
+ "interface WPContentResult<T> {",
181
+ " data: ComputedRef<T | undefined>",
182
+ " pending: Ref<boolean>",
183
+ " refresh: () => Promise<void>",
184
+ " execute: () => Promise<void>",
185
+ " clear: () => void",
186
+ " error: Ref<Error | undefined>",
187
+ " status: Ref<AsyncDataRequestStatus>",
188
+ "}",
189
+ "",
190
+ "type WPMutationResult<T> = GraphqlResponse<T>",
191
+ "",
192
+ "declare module '#wpnuxt' {"
193
+ ];
194
+ queries.forEach((f) => {
195
+ declarations.push(queryFnExp(f, true, false));
196
+ declarations.push(queryFnExp(f, true, true));
197
+ });
198
+ mutations.forEach((m) => {
199
+ declarations.push(mutationFnExp(m, true));
200
+ });
201
+ declarations.push("}");
202
+ return declarations.join("\n");
89
203
  };
90
- ctx.generateImports = () => [
91
- ...ctx.fns.map((f) => fnExp(f))
92
- ].join("\n");
93
- const types = [];
94
- ctx.fns.forEach((o) => types.push(...getQueryTypeTemplate(o)));
95
- ctx.generateDeclarations = () => [
96
- `import type { ${[...new Set(types)].join(", ")} } from '#build/graphql-operations'`,
97
- "import { AsyncData } from 'nuxt/app'",
98
- "import { FetchError } from 'ofetch'",
99
- "declare module '#wpnuxt' {",
100
- ...[
101
- ...ctx.fns.map((f) => fnExp(f, true))
102
- ],
103
- "}"
104
- ].join("\n");
105
- ctx.fnImports = ctx.fns.map((fn) => ({ from: "#wpnuxt", name: fnName(fn.name) }));
204
+ ctx.fnImports = [
205
+ // Auto-import query composables (regular and lazy variants)
206
+ ...queries.flatMap((fn) => [
207
+ { from: "#wpnuxt", name: fnName(fn.name) },
208
+ { from: "#wpnuxt", name: `useLazy${fn.name}` }
209
+ ]),
210
+ // Auto-import mutation composables
211
+ ...mutations.map((m) => ({ from: "#wpnuxt", name: mutationFnName(m.name) }))
212
+ ];
106
213
  logger.debug("generated WPNuxt composables: ");
107
- ctx.fns.forEach((f) => logger.debug(` ${fnName(f.name)}()`));
108
- }
109
- function getQueryTypeTemplate(q) {
110
- const types = [];
111
- types.push(`${q.name}QueryVariables`);
112
- if (q.fragments && q.fragments.length > 0) {
113
- q.fragments.forEach((f) => types.push(`${f}Fragment`));
114
- }
115
- return types;
214
+ queries.forEach((f) => {
215
+ logger.debug(` ${fnName(f.name)}()`);
216
+ logger.debug(` useLazy${f.name}()`);
217
+ });
218
+ mutations.forEach((m) => {
219
+ logger.debug(` ${mutationFnName(m.name)}()`);
220
+ });
116
221
  }
117
222
  async function prepareFunctions(ctx) {
118
223
  if (!ctx.docs) {
119
224
  getLogger().error("no GraphQL query documents were found!");
120
225
  return;
121
226
  }
122
- for await (const doc of ctx.docs) {
123
- const operations = await parseDoc(await promises.readFile(doc, "utf8"));
124
- operations.forEach((query) => {
125
- ctx.fns.push(query);
227
+ const operations = await Promise.all(
228
+ ctx.docs.map(async (doc) => {
229
+ const content = await promises.readFile(doc, "utf8");
230
+ return parseDoc(content);
231
+ })
232
+ );
233
+ operations.flat().forEach((query) => {
234
+ ctx.fns.push(query);
235
+ });
236
+ }
237
+
238
+ async function validateWordPressEndpoint(wordpressUrl, graphqlEndpoint = "/graphql", options = {}) {
239
+ const fullUrl = `${wordpressUrl}${graphqlEndpoint}`;
240
+ try {
241
+ const controller = new AbortController();
242
+ const timeout = setTimeout(() => controller.abort(), 1e4);
243
+ const response = await fetch(fullUrl, {
244
+ method: "POST",
245
+ headers: {
246
+ "Content-Type": "application/json"
247
+ },
248
+ body: JSON.stringify({
249
+ query: "{ __typename }"
250
+ }),
251
+ signal: controller.signal
126
252
  });
253
+ clearTimeout(timeout);
254
+ if (!response.ok) {
255
+ throw new Error(
256
+ `[WPNuxt] WordPress GraphQL endpoint returned HTTP ${response.status}.
257
+
258
+ URL: ${fullUrl}
259
+
260
+ Possible causes:
261
+ - The WordPress site is down or unreachable
262
+ - WPGraphQL plugin is not installed or activated
263
+ - The GraphQL endpoint path is incorrect (default: /graphql)
264
+
265
+ Check your wpNuxt.wordpressUrl configuration in nuxt.config.ts`
266
+ );
267
+ }
268
+ const data = await response.json();
269
+ if (!data || typeof data !== "object") {
270
+ throw new Error(
271
+ `[WPNuxt] WordPress GraphQL endpoint returned invalid response.
272
+
273
+ URL: ${fullUrl}
274
+
275
+ The endpoint did not return valid JSON. Make sure WPGraphQL plugin is installed and activated.`
276
+ );
277
+ }
278
+ if (data.errors && !data.data) {
279
+ const errorMessage = data.errors[0]?.message || "Unknown error";
280
+ throw new Error(
281
+ `[WPNuxt] WordPress GraphQL endpoint returned an error: ${errorMessage}
282
+
283
+ URL: ${fullUrl}
284
+
285
+ Make sure WPGraphQL plugin is installed and activated on your WordPress site.`
286
+ );
287
+ }
288
+ if (options.schemaPath && !existsSync(options.schemaPath)) {
289
+ try {
290
+ execSync(`npx get-graphql-schema "${fullUrl}" > "${options.schemaPath}"`, {
291
+ stdio: "pipe",
292
+ timeout: 6e4
293
+ // 60 second timeout
294
+ });
295
+ patchWPGraphQLSchema(options.schemaPath);
296
+ } catch (err) {
297
+ const error = err;
298
+ throw new Error(
299
+ `[WPNuxt] Failed to download GraphQL schema.
300
+
301
+ URL: ${fullUrl}
302
+ Error: ${error.stderr?.toString() || error.message}
303
+
304
+ Make sure WPGraphQL plugin is installed and activated on your WordPress site.`
305
+ );
306
+ }
307
+ }
308
+ } catch (error) {
309
+ if (error instanceof Error && error.message.startsWith("[WPNuxt]")) {
310
+ throw error;
311
+ }
312
+ const err = error;
313
+ const errorCode = err.code || err.cause?.code || "";
314
+ if (err.name === "AbortError") {
315
+ throw new Error(
316
+ `[WPNuxt] WordPress GraphQL endpoint timed out after 10 seconds.
317
+
318
+ URL: ${fullUrl}
319
+
320
+ The server did not respond in time. Check if the WordPress site is accessible.`
321
+ );
322
+ }
323
+ if (errorCode === "ENOTFOUND" || err.message?.includes("getaddrinfo")) {
324
+ throw new Error(
325
+ `[WPNuxt] WordPress site not found - DNS lookup failed.
326
+
327
+ URL: ${fullUrl}
328
+
329
+ The domain could not be resolved. Please check:
330
+ - The URL is spelled correctly (no typos)
331
+ - The domain exists and is properly configured
332
+ - Your network connection is working
333
+
334
+ Check your wpNuxt.wordpressUrl configuration in nuxt.config.ts`
335
+ );
336
+ }
337
+ if (errorCode === "ECONNREFUSED") {
338
+ throw new Error(
339
+ `[WPNuxt] Connection refused to WordPress site.
340
+
341
+ URL: ${fullUrl}
342
+
343
+ The server is not accepting connections. Check if the WordPress site is running.`
344
+ );
345
+ }
346
+ throw new Error(
347
+ `[WPNuxt] Failed to connect to WordPress GraphQL endpoint.
348
+
349
+ URL: ${fullUrl}
350
+ Error: ${err.message || "Unknown error"}
351
+
352
+ Check your wpNuxt.wordpressUrl configuration in nuxt.config.ts`
353
+ );
127
354
  }
128
355
  }
129
-
130
- const allowDocument = (f, resolver) => {
131
- const isSchema = f.match(/([^/]+)\.(gql|graphql)$/)?.[0]?.toLowerCase().includes("schema");
132
- return !isSchema && !!statSync(resolver.resolve(f)).size;
133
- };
134
- async function generateWPNuxtComposables(ctx, queryOutputPath, resolver) {
135
- const gqlMatch = "**/*.{gql,graphql}";
136
- const documents = [];
137
- const files = (await resolveFiles(queryOutputPath, [gqlMatch, "!**/schemas"], { followSymbolicLinks: false })).filter((doc) => allowDocument(doc, resolver));
138
- documents.push(...files);
139
- ctx.docs = documents;
140
- await prepareContext(ctx);
356
+ function patchWPGraphQLSchema(schemaPath) {
357
+ let schema = readFileSync(schemaPath, "utf-8");
358
+ const problematicInterfaces = [
359
+ "Connection",
360
+ "Edge",
361
+ "OneToOneConnection"
362
+ ];
363
+ problematicInterfaces.push("NodeWithEditorBlocks");
364
+ for (const iface of problematicInterfaces) {
365
+ schema = schema.replace(
366
+ new RegExp(`implements\\s+${iface}\\s*\\{`, "g"),
367
+ "{"
368
+ );
369
+ schema = schema.replace(
370
+ new RegExp(`implements\\s+${iface}\\s+&\\s+`, "g"),
371
+ "implements "
372
+ );
373
+ schema = schema.replace(
374
+ new RegExp(`\\s*&\\s*${iface}(?=\\s*[&{])`, "g"),
375
+ ""
376
+ );
377
+ }
378
+ writeFileSync(schemaPath, schema);
141
379
  }
142
380
 
143
- const defaultConfigs = {
144
- wordpressUrl: "",
145
- frontendUrl: "",
146
- defaultMenuName: "main",
147
- enableCache: true,
148
- staging: false,
149
- logLevel: 3,
150
- composablesPrefix: "useWP"
151
- };
152
- const module = defineNuxtModule({
381
+ const module$1 = defineNuxtModule({
153
382
  meta: {
154
- name,
155
- version,
156
- configKey: "wpNuxt",
157
- nuxt: ">=3.1.0"
383
+ name: "wpnuxt",
384
+ configKey: "wpNuxt"
385
+ },
386
+ defaults: {
387
+ wordpressUrl: void 0,
388
+ graphqlEndpoint: "/graphql",
389
+ queries: {
390
+ extendFolder: "extend/queries/",
391
+ mergedOutputFolder: ".queries/"
392
+ },
393
+ downloadSchema: true,
394
+ debug: false,
395
+ cache: {
396
+ enabled: true,
397
+ maxAge: 60 * 5,
398
+ // 5 minutes
399
+ swr: true
400
+ }
158
401
  },
159
- // Default configuration options of the Nuxt module
160
- defaults: defaultConfigs,
161
402
  async setup(options, nuxt) {
162
403
  const startTime = (/* @__PURE__ */ new Date()).getTime();
163
- consola.log("::: Starting WPNuxt setup ::: ");
164
- const publicWPNuxtConfig = {
165
- wordpressUrl: process.env.WPNUXT_WORDPRESS_URL || options.wordpressUrl,
166
- frontendUrl: process.env.WPNUXT_FRONTEND_URL || options.frontendUrl,
167
- defaultMenuName: process.env.WPNUXT_DEFAULT_MENU_NAME || options.defaultMenuName,
168
- enableCache: process.env.WPNUXT_ENABLE_CACHE ? process.env.WPNUXT_ENABLE_CACHE === "true" : options.enableCache,
169
- staging: process.env.WPNUXT_STAGING === "true" || options.staging,
170
- downloadSchema: process.env.WPNUXT_DOWNLOAD_SCHEMA === "true" || options.downloadSchema,
171
- logLevel: process.env.WPNUXT_LOG_LEVEL ? Number.parseInt(process.env.WPNUXT_LOG_LEVEL) : options.logLevel,
172
- composablesPrefix: process.env.WPNUXT_COMPOSABLES_PREFIX || options.composablesPrefix
173
- };
174
- nuxt.options.runtimeConfig.public.wpNuxt = publicWPNuxtConfig;
175
- validateConfig(publicWPNuxtConfig);
176
- const logger = initLogger(publicWPNuxtConfig.logLevel);
177
- logger.info("Connecting GraphQL to", publicWPNuxtConfig.wordpressUrl);
178
- logger.info("frontendUrl:", publicWPNuxtConfig.frontendUrl);
179
- if (publicWPNuxtConfig.enableCache)
180
- logger.info("Cache enabled");
181
- logger.debug("Debug mode enabled, log level:", publicWPNuxtConfig.logLevel);
182
- if (publicWPNuxtConfig.staging)
183
- logger.info("Staging enabled");
184
- const { resolve } = createResolver(import.meta.url);
185
- const resolveRuntimeModule = (path) => resolve("./runtime", path);
186
- const srcResolver = createResolver(nuxt.options.srcDir);
187
- nuxt.options.alias["#wpnuxt"] = resolve(nuxt.options.buildDir, "wpnuxt");
188
- nuxt.options.alias["#wpnuxt/*"] = resolve(nuxt.options.buildDir, "wpnuxt", "*");
189
- nuxt.options.alias["#wpnuxt/types"] = resolve("./types");
190
- nuxt.options.nitro.alias = nuxt.options.nitro.alias || {};
191
- nuxt.options.nitro.alias["#wpnuxt/types"] = resolve("./types");
192
- nuxt.options.nitro.externals = nuxt.options.nitro.externals || {};
193
- nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [];
194
- addPlugin({
195
- src: resolveRuntimeModule("plugins/vue-sanitize-directive")
196
- });
197
- addImports([
198
- { name: "isStaging", as: "isStaging", from: resolveRuntimeModule("./composables/isStaging") },
199
- { name: "useWPContent", as: "useWPContent", from: resolveRuntimeModule("./composables/useWPContent") },
200
- { name: "parseDoc", as: "parseDoc", from: resolveRuntimeModule("./composables/useParser") },
201
- { name: "usePrevNextPost", as: "usePrevNextPost", from: resolveRuntimeModule("./composables/usePrevNextPost") },
202
- { name: "loginUser", as: "loginUser", from: resolveRuntimeModule("./composables/user") },
203
- { name: "logoutUser", as: "logoutUser", from: resolveRuntimeModule("./composables/user") },
204
- { name: "getCurrentUserId", as: "getCurrentUserId", from: resolveRuntimeModule("./composables/user") },
205
- { name: "getCurrentUserName", as: "getCurrentUserName", from: resolveRuntimeModule("./composables/user") },
206
- { name: "useTokens", as: "useTokens", from: resolveRuntimeModule("./composables/useTokens") },
207
- { name: "useWPUri", as: "useWPUri", from: resolveRuntimeModule("./composables/useWPUri") },
208
- { name: "useFeaturedImage", as: "useFeaturedImage", from: resolveRuntimeModule("./composables/useFeaturedImage") }
209
- ]);
210
- addComponent({ name: "StagingBanner", filePath: resolveRuntimeModule("./components/StagingBanner") });
211
- addComponent({ name: "WPNuxtLogo", filePath: resolveRuntimeModule("./components/WPNuxtLogo") });
212
- addComponent({ name: "WordPressLogo", filePath: resolveRuntimeModule("./components/WordPressLogo") });
213
- addServerHandler({
214
- route: "/api/wpContent",
215
- handler: resolveRuntimeModule("./server/api/wpContent.post")
216
- });
217
- addServerHandler({
218
- route: "/api/purgeCache",
219
- handler: resolveRuntimeModule("./server/api/purgeCache.get")
404
+ const wpNuxtConfig = loadConfig(options, nuxt);
405
+ const logger = initLogger(wpNuxtConfig.debug);
406
+ logger.debug("Starting WPNuxt in debug mode");
407
+ const resolver = createResolver(import.meta.url);
408
+ nuxt.options.runtimeConfig.public.buildHash = randHashGenerator();
409
+ addPlugin(resolver.resolve("./runtime/plugins/graphqlConfig"));
410
+ addPlugin(resolver.resolve("./runtime/plugins/graphqlErrors"));
411
+ const mergedQueriesFolder = await mergeQueries(nuxt, wpNuxtConfig, resolver);
412
+ setupServerOptions(nuxt, resolver, logger);
413
+ setupClientOptions(nuxt, resolver, logger);
414
+ if (wpNuxtConfig.downloadSchema) {
415
+ const schemaPath = join(nuxt.options.rootDir, "schema.graphql");
416
+ logger.debug(`Validating WordPress endpoint: ${wpNuxtConfig.wordpressUrl}${wpNuxtConfig.graphqlEndpoint}`);
417
+ await validateWordPressEndpoint(
418
+ wpNuxtConfig.wordpressUrl,
419
+ wpNuxtConfig.graphqlEndpoint,
420
+ { schemaPath }
421
+ );
422
+ logger.debug("WordPress endpoint validation passed");
423
+ }
424
+ await registerModules(nuxt, resolver, wpNuxtConfig, mergedQueriesFolder);
425
+ nuxt.hook("devtools:customTabs", (tabs) => {
426
+ const middlewareTab = tabs.find((tab) => tab.name === "nuxt-graphql-middleware");
427
+ if (middlewareTab) {
428
+ middlewareTab.title = "WPNuxt GraphQL";
429
+ middlewareTab.icon = "simple-icons:wordpress";
430
+ }
220
431
  });
221
- await installModule("@vueuse/nuxt", {});
222
- const queryOutputPath = resolve((nuxt.options.srcDir || nuxt.options.rootDir) + "/.queries/");
223
- await promises.rm(queryOutputPath, { recursive: true, force: true });
224
- const userQueryPath = "~/extend/queries/".replace(/^(~~|@@)/, nuxt.options.rootDir).replace(/^(~|@)/, nuxt.options.srcDir);
225
- const userQueryPathExists = existsSync(userQueryPath);
226
- cpSync(resolveRuntimeModule("./queries/"), queryOutputPath, { recursive: true });
227
- if (hasNuxtModule("@wpnuxt/blocks")) {
228
- for (const m of nuxt.options._installedModules) {
229
- if (m.meta.name === "@wpnuxt/blocks" && m.entryPath) {
230
- logger.debug("Loading queries from @wpnuxt/blocks");
231
- let blocksQueriesPath;
232
- if (m.entryPath.startsWith("../")) {
233
- blocksQueriesPath = join(nuxt.options.rootDir, "../", m.entryPath, "./runtime/queries/");
234
- } else {
235
- blocksQueriesPath = join("./node_modules", m.entryPath, "dist/runtime/queries/");
236
- }
237
- cpSync(blocksQueriesPath, queryOutputPath, { recursive: true });
432
+ if (wpNuxtConfig.cache?.enabled !== false) {
433
+ const maxAge = wpNuxtConfig.cache?.maxAge ?? 300;
434
+ nuxt.options.nitro.routeRules = nuxt.options.nitro.routeRules || {};
435
+ nuxt.options.nitro.routeRules["/api/wpnuxt/**"] = {
436
+ cache: {
437
+ maxAge,
438
+ swr: wpNuxtConfig.cache?.swr !== false
238
439
  }
239
- }
240
- } else {
241
- logger.debug("Tip: Install the @wpnuxt/blocks module if you want to render Gutenberg blocks with separate vue components");
242
- addTemplate({
243
- write: true,
244
- filename: "wpnuxt/blocks.mjs",
245
- getContents: () => `export { }`
246
- });
247
- nuxt.options.alias["#wpnuxt/blocks"] = resolve(nuxt.options.buildDir, "wpnuxt/blocks");
440
+ };
441
+ logger.debug(`Server-side caching enabled for GraphQL requests (maxAge: ${maxAge}s, SWR: ${wpNuxtConfig.cache?.swr !== false})`);
248
442
  }
249
- if (userQueryPathExists) {
250
- logger.debug("Extending queries:", userQueryPath);
251
- cpSync(resolve(userQueryPath), queryOutputPath, { recursive: true });
252
- }
253
- logger.debug("Copied merged queries in folder:", queryOutputPath);
254
- await installModule("nuxt-graphql-middleware", {
255
- debug: publicWPNuxtConfig.logLevel ? publicWPNuxtConfig.logLevel > 3 : false,
256
- graphqlEndpoint: `${publicWPNuxtConfig.wordpressUrl}/graphql`,
257
- downloadSchema: publicWPNuxtConfig.downloadSchema,
258
- codegenConfig: {
259
- silent: false,
260
- skipTypename: true,
261
- useTypeImports: true,
262
- // inlineFragmentTypes: 'combine',
263
- dedupeFragments: true,
264
- onlyOperationTypes: true,
265
- avoidOptionals: false,
266
- maybeValue: "T | undefined",
267
- disableOnBuild: false,
268
- gqlImport: "graphql-request#wpnuxt",
269
- namingConvention: {
270
- enumValues: "change-case-all#upperCaseFirst"
271
- },
272
- documents: [
273
- resolve("!./graphql/**/*")
274
- ]
275
- },
276
- codegenSchemaConfig: {
277
- urlSchemaOptions: {
278
- headers: {
279
- Authorization: "server-token"
280
- }
281
- }
282
- },
283
- outputDocuments: true,
284
- autoImportPatterns: queryOutputPath,
285
- includeComposables: true,
286
- devtools: true
287
- });
288
- const resolvedPath = resolveRuntimeModule("./app/graphqlMiddleware.serverOptions");
289
- const template = addTemplate({
290
- filename: "graphqlMiddleware.serverOptions.ts",
291
- write: true,
292
- getContents: () => `
293
- import type { GraphqlMiddlewareServerOptions } from '#graphql-middleware/types'
294
- import serverOptions from '${resolvedPath}'
295
- import type { GraphqlServerResponse } from '#graphql-middleware/types'
296
- import type { GraphqlMiddlewareResponseUnion } from '#build/nuxt-graphql-middleware'
297
-
298
- type GraphqlResponseAdditions =
299
- typeof serverOptions extends GraphqlMiddlewareServerOptions<infer R> ? R : {}
300
-
301
- export type GraphqlResponse<T> = GraphqlServerResponse<T> & GraphqlResponseAdditions
302
-
303
- export type GraphqlResponseTyped = GraphqlResponse<GraphqlMiddlewareResponseUnion>
304
-
305
- export { serverOptions }
306
- `
443
+ configureVercelSettings(nuxt, logger);
444
+ addImports([
445
+ { name: "useWPContent", as: "useWPContent", from: resolver.resolve("./runtime/composables/useWPContent") },
446
+ { name: "useAsyncWPContent", as: "useAsyncWPContent", from: resolver.resolve("./runtime/composables/useWPContent") }
447
+ // Note: useGraphqlMutation is auto-imported via nuxt-graphql-middleware with includeComposables: true
448
+ ]);
449
+ addComponentsDir({
450
+ path: resolver.resolve("./runtime/components"),
451
+ pathPrefix: false,
452
+ prefix: "",
453
+ global: true
307
454
  });
308
- nuxt.options.nitro.externals.inline.push(template.dst);
309
- nuxt.options.alias["#graphql-middleware-server-options-build"] = template.dst;
310
455
  logger.trace("Start generating composables");
311
- const ctx = await {
456
+ const ctx = {
312
457
  fns: [],
313
458
  fnImports: [],
314
- composablesPrefix: publicWPNuxtConfig.composablesPrefix
459
+ composablesPrefix: "use"
315
460
  };
316
- await generateWPNuxtComposables(ctx, queryOutputPath, srcResolver);
461
+ await generateWPNuxtComposables(ctx, mergedQueriesFolder, createResolver(nuxt.options.srcDir));
462
+ nuxt.options.alias["#wpnuxt"] = resolver.resolve(nuxt.options.buildDir, "wpnuxt");
463
+ nuxt.options.alias["#wpnuxt/*"] = resolver.resolve(nuxt.options.buildDir, "wpnuxt", "*");
464
+ nuxt.options.alias["#wpnuxt/types"] = resolver.resolve("./types");
465
+ nuxt.options.nitro.alias = nuxt.options.nitro.alias || {};
466
+ nuxt.options.nitro.alias["#wpnuxt/types"] = resolver.resolve("./types");
467
+ nuxt.options.nitro.externals = nuxt.options.nitro.externals || {};
468
+ nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [];
317
469
  addTemplate({
318
470
  write: true,
319
471
  filename: "wpnuxt/index.mjs",
@@ -327,16 +479,194 @@ const module = defineNuxtModule({
327
479
  nuxt.hook("imports:extend", (autoimports) => {
328
480
  autoimports.push(...ctx.fnImports || []);
329
481
  });
330
- nuxt.hook("nitro:init", async (nitro) => {
331
- const keys = await nitro.storage.getKeys("cache:content");
332
- keys.forEach(async (key) => {
333
- if (key.startsWith("cache:content"))
334
- await nitro.storage.removeItem(key);
335
- });
336
- });
337
- const endTime = (/* @__PURE__ */ new Date()).getTime();
338
- logger.success("::: Finished WPNuxt setup in " + (endTime - startTime) + "ms ::: ");
482
+ logger.trace("Finished generating composables");
483
+ logger.info(`WPNuxt module loaded in ${(/* @__PURE__ */ new Date()).getTime() - startTime}ms`);
339
484
  }
340
485
  });
486
+ function loadConfig(options, nuxt) {
487
+ const config = defu({
488
+ wordpressUrl: process.env.WPNUXT_WORDPRESS_URL,
489
+ graphqlEndpoint: process.env.WPNUXT_GRAPHQL_ENDPOINT,
490
+ // Only override downloadSchema if env var is explicitly set
491
+ downloadSchema: process.env.WPNUXT_DOWNLOAD_SCHEMA !== void 0 ? process.env.WPNUXT_DOWNLOAD_SCHEMA === "true" : void 0,
492
+ debug: process.env.WPNUXT_DEBUG ? process.env.WPNUXT_DEBUG === "true" : void 0
493
+ }, options);
494
+ if (config.downloadSchema === void 0) {
495
+ config.downloadSchema = true;
496
+ }
497
+ nuxt.options.runtimeConfig.public.wordpressUrl = config.wordpressUrl;
498
+ nuxt.options.runtimeConfig.public.wpNuxt = {
499
+ wordpressUrl: config.wordpressUrl,
500
+ graphqlEndpoint: config.graphqlEndpoint,
501
+ cache: {
502
+ enabled: config.cache?.enabled ?? true,
503
+ maxAge: config.cache?.maxAge ?? 300,
504
+ swr: config.cache?.swr ?? true
505
+ }
506
+ };
507
+ if (!config.wordpressUrl?.trim()) {
508
+ throw new Error("WPNuxt error: WordPress url is missing");
509
+ }
510
+ if (config.wordpressUrl.endsWith("/")) {
511
+ throw new Error(`WPNuxt error: WordPress url should not have a trailing slash: ${config.wordpressUrl}`);
512
+ }
513
+ return config;
514
+ }
515
+ const SERVER_OPTIONS_TEMPLATE = `import { defineGraphqlServerOptions } from '@wpnuxt/core/server-options'
516
+ import { getHeader, getCookie } from 'h3'
517
+ import { useRuntimeConfig } from '#imports'
518
+
519
+ /**
520
+ * WPNuxt default server options for nuxt-graphql-middleware.
521
+ *
522
+ * This enables:
523
+ * - Cookie forwarding for WordPress preview mode
524
+ * - Authorization header forwarding for authenticated requests
525
+ * - Auth token from cookie for @wpnuxt/auth
526
+ * - Consistent error logging
527
+ *
528
+ * Users can customize by creating their own server/graphqlMiddleware.serverOptions.ts
529
+ */
530
+ export default defineGraphqlServerOptions({
531
+ async serverFetchOptions(event, _operation, _operationName, _context) {
532
+ // Get auth token from Authorization header or from cookie
533
+ let authorization = getHeader(event, 'authorization') || ''
534
+
535
+ // If no Authorization header, check for auth token in cookie (@wpnuxt/auth)
536
+ if (!authorization) {
537
+ const config = useRuntimeConfig().public.wpNuxtAuth as { cookieName?: string } | undefined
538
+ const cookieName = config?.cookieName || 'wpnuxt-auth-token'
539
+ const authToken = getCookie(event, cookieName)
540
+ if (authToken) {
541
+ authorization = \`Bearer \${authToken}\`
542
+ }
543
+ }
544
+
545
+ return {
546
+ headers: {
547
+ // Forward WordPress auth cookies for previews
548
+ Cookie: getHeader(event, 'cookie') || '',
549
+ // Forward authorization header or token from cookie
550
+ Authorization: authorization
551
+ }
552
+ }
553
+ },
554
+
555
+ async onServerError(event, error, _operation, operationName) {
556
+ const url = event.node.req.url || 'unknown'
557
+ console.error(\`[WPNuxt] GraphQL error in \${operationName} (\${url}):\`, error.message)
558
+ }
559
+ })
560
+ `;
561
+ function setupServerOptions(nuxt, _resolver, logger) {
562
+ const serverDir = nuxt.options.serverDir;
563
+ const targetPath = join(serverDir, "graphqlMiddleware.serverOptions.ts");
564
+ if (existsSync(targetPath)) {
565
+ logger.debug("Using existing graphqlMiddleware.serverOptions.ts from project");
566
+ return;
567
+ }
568
+ if (!existsSync(serverDir)) {
569
+ mkdirSync(serverDir, { recursive: true });
570
+ }
571
+ writeFileSync(targetPath, SERVER_OPTIONS_TEMPLATE);
572
+ logger.debug("Created graphqlMiddleware.serverOptions.ts with WPNuxt defaults (cookie/auth forwarding)");
573
+ }
574
+ const CLIENT_OPTIONS_TEMPLATE = `import { defineGraphqlClientOptions } from '@wpnuxt/core/client-options'
575
+ import { useRoute } from '#imports'
576
+
577
+ /**
578
+ * WPNuxt default client options for nuxt-graphql-middleware.
579
+ *
580
+ * This enables passing client context to the server for:
581
+ * - Preview mode (passes preview flag and token from URL query params)
582
+ *
583
+ * The context is available in serverFetchOptions via context.client
584
+ * All values must be strings (nuxt-graphql-middleware requirement)
585
+ *
586
+ * Users can customize by creating their own app/graphqlMiddleware.clientOptions.ts
587
+ */
588
+ export default defineGraphqlClientOptions<{
589
+ preview?: string
590
+ previewToken?: string
591
+ }>({
592
+ buildClientContext() {
593
+ const route = useRoute()
594
+
595
+ return {
596
+ // Context values must be strings - use 'true'/'false' instead of boolean
597
+ preview: route.query.preview === 'true' ? 'true' : undefined,
598
+ previewToken: route.query.token as string | undefined
599
+ }
600
+ }
601
+ })
602
+ `;
603
+ function setupClientOptions(nuxt, _resolver, logger) {
604
+ const appDir = nuxt.options.dir.app;
605
+ const targetPath = join(appDir, "graphqlMiddleware.clientOptions.ts");
606
+ if (existsSync(targetPath)) {
607
+ logger.debug("Using existing graphqlMiddleware.clientOptions.ts from project");
608
+ return;
609
+ }
610
+ if (!existsSync(appDir)) {
611
+ mkdirSync(appDir, { recursive: true });
612
+ }
613
+ writeFileSync(targetPath, CLIENT_OPTIONS_TEMPLATE);
614
+ logger.debug("Created graphqlMiddleware.clientOptions.ts with WPNuxt defaults (preview mode support)");
615
+ }
616
+ function configureVercelSettings(nuxt, logger) {
617
+ const isVercel = process.env.VERCEL === "1" || nuxt.options.nitro.preset === "vercel";
618
+ if (isVercel) {
619
+ logger.debug("Vercel deployment detected, applying recommended settings");
620
+ nuxt.options.nitro.future = nuxt.options.nitro.future || {};
621
+ if (nuxt.options.nitro.future.nativeSWR === void 0) {
622
+ nuxt.options.nitro.future.nativeSWR = true;
623
+ logger.debug("Enabled nitro.future.nativeSWR for Vercel ISR compatibility");
624
+ }
625
+ nuxt.options.routeRules = nuxt.options.routeRules || {};
626
+ if (!nuxt.options.routeRules["/**"]) {
627
+ nuxt.options.routeRules["/**"] = { ssr: true };
628
+ logger.debug("Enabled SSR for all routes (routeRules['/**'] = { ssr: true })");
629
+ }
630
+ }
631
+ }
632
+ async function registerModules(nuxt, resolver, wpNuxtConfig, mergedQueriesFolder) {
633
+ const logger = getLogger();
634
+ async function registerModule(name, key, options) {
635
+ if (!hasNuxtModule(name)) {
636
+ await installModule(name, options);
637
+ } else {
638
+ logger.debug(`${name} module already registered, using the 'graphqlMiddleware' config from nuxt.config.ts`);
639
+ nuxt.options[key] = defu(nuxt.options[key], options);
640
+ }
641
+ }
642
+ await registerModule("nuxt-graphql-middleware", "graphql", {
643
+ debug: wpNuxtConfig.debug,
644
+ graphqlEndpoint: `${wpNuxtConfig.wordpressUrl}${wpNuxtConfig.graphqlEndpoint}`,
645
+ autoImportPatterns: [mergedQueriesFolder],
646
+ includeComposables: true,
647
+ downloadSchema: wpNuxtConfig.downloadSchema ?? true,
648
+ enableFileUploads: true,
649
+ // Use WPNuxt-branded API route prefix
650
+ serverApiPrefix: "/api/wpnuxt",
651
+ clientCache: {
652
+ // Enable or disable the caching feature.
653
+ enabled: true,
654
+ // Cache a maximum of 50 queries (default: 100).
655
+ maxSize: 50
656
+ },
657
+ codegenConfig: {
658
+ // WordPress-specific scalar mappings
659
+ scalars: {
660
+ DateTime: "string",
661
+ ID: "string"
662
+ }
663
+ },
664
+ experimental: {
665
+ // Use improved query parameter encoding for better URL handling
666
+ improvedQueryParamEncoding: true
667
+ }
668
+ });
669
+ await registerModule("@radya/nuxt-dompurify", "dompurify", {});
670
+ }
341
671
 
342
- export { module as default };
672
+ export { module$1 as default };