@wpnuxt/core 1.0.0-edge.30 → 1.0.0-edge.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/module.d.mts +8 -0
- package/dist/module.json +6 -4
- package/dist/module.mjs +164 -97
- package/dist/runtime/components/ContentRenderer.d.vue.ts +7 -0
- package/dist/runtime/components/ContentRenderer.vue.d.ts +2 -1
- package/dist/runtime/components/StagingBanner.d.vue.ts +3 -0
- package/dist/runtime/components/StagingBanner.vue +15 -12
- package/dist/runtime/components/StagingBanner.vue.d.ts +2 -1
- package/dist/runtime/components/WPContent.d.vue.ts +7 -0
- package/dist/runtime/components/WPContent.vue.d.ts +2 -1
- package/dist/runtime/components/WPNuxtLogo.d.vue.ts +6 -0
- package/dist/runtime/components/WPNuxtLogo.vue.d.ts +2 -1
- package/dist/runtime/components/WordPressLogo.d.vue.ts +3 -0
- package/dist/runtime/components/WordPressLogo.vue.d.ts +2 -1
- package/dist/runtime/composables/usePrevNextPost.d.ts +2 -2
- package/dist/runtime/composables/usePrevNextPost.js +5 -5
- package/dist/runtime/composables/useWPContent.d.ts +6 -4
- package/dist/runtime/composables/useWPContent.js +54 -15
- package/dist/runtime/plugins/vue-sanitize-directive.d.ts +6 -2
- package/dist/runtime/server/api/{config.js → _wpnuxt/config.js} +2 -1
- package/dist/runtime/server/api/_wpnuxt/content.post.d.ts +10 -0
- package/dist/runtime/server/api/_wpnuxt/content.post.js +105 -0
- package/dist/runtime/server/nitro.d.ts +3 -0
- package/dist/runtime/types.d.ts +87 -0
- package/package.json +30 -31
- package/dist/runtime/composables/index.d.ts +0 -3
- package/dist/runtime/composables/index.js +0 -3
- package/dist/runtime/server/api/wpContent.post.d.ts +0 -6
- package/dist/runtime/server/api/wpContent.post.js +0 -46
- /package/dist/runtime/server/api/{config.d.ts → _wpnuxt/config.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -67,14 +67,14 @@ pnpm run release
|
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
<!-- Badges -->
|
|
70
|
-
[npm-version-src]: https://img.shields.io/npm/v/@
|
|
71
|
-
[npm-version-href]: https://www.npmjs.com/package/@
|
|
70
|
+
[npm-version-src]: https://img.shields.io/npm/v/@wpnuxt/core/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
71
|
+
[npm-version-href]: https://www.npmjs.com/package/@wpnuxt/core
|
|
72
72
|
|
|
73
|
-
[npm-downloads-src]: https://img.shields.io/npm/dm/@
|
|
74
|
-
[npm-downloads-href]: https://www.npmjs.com/package/@
|
|
73
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/@wpnuxt/core.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
74
|
+
[npm-downloads-href]: https://www.npmjs.com/package/@wpnuxt/core
|
|
75
75
|
|
|
76
|
-
[license-src]: https://img.shields.io/npm/l/@
|
|
77
|
-
[license-href]: https://www.npmjs.com/package/@
|
|
76
|
+
[license-src]: https://img.shields.io/npm/l/@wpnuxt/core?style=flat&colorA=18181B&colorB=28CF8D
|
|
77
|
+
[license-href]: https://www.npmjs.com/package/@wpnuxt/core
|
|
78
78
|
|
|
79
79
|
[nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
|
|
80
80
|
[nuxt-href]: https://nuxt.com
|
package/dist/module.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
import { OperationTypeNode } from 'graphql';
|
|
2
3
|
|
|
3
4
|
interface WPNuxtConfig {
|
|
4
5
|
|
|
@@ -22,6 +23,13 @@ interface WPNuxtConfig {
|
|
|
22
23
|
|
|
23
24
|
enableCache?: boolean
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Cache duration in seconds for WordPress content
|
|
28
|
+
*
|
|
29
|
+
* @default 300 (5 minutes)
|
|
30
|
+
*/
|
|
31
|
+
cacheMaxAge?: number
|
|
32
|
+
|
|
25
33
|
staging?: boolean
|
|
26
34
|
|
|
27
35
|
/**
|
package/dist/module.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wpnuxt/core",
|
|
3
|
-
"version": "1.0.0-edge.
|
|
3
|
+
"version": "1.0.0-edge.31",
|
|
4
4
|
"configKey": "wpNuxt",
|
|
5
|
-
"
|
|
5
|
+
"compatibility": {
|
|
6
|
+
"nuxt": ">=3.1.0"
|
|
7
|
+
},
|
|
6
8
|
"builder": {
|
|
7
|
-
"@nuxt/module-builder": "1.0.
|
|
8
|
-
"unbuild": "3.
|
|
9
|
+
"@nuxt/module-builder": "1.0.2",
|
|
10
|
+
"unbuild": "3.6.1"
|
|
9
11
|
}
|
|
10
12
|
}
|
package/dist/module.mjs
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
|
-
import { createResolver,
|
|
1
|
+
import { createResolver, addTemplate, hasNuxtModule, resolveFiles, defineNuxtModule, addPlugin, addImportsDir, addComponentsDir, addServerHandler, installModule, addTypeTemplate } from '@nuxt/kit';
|
|
2
2
|
import { createConsola, consola } from 'consola';
|
|
3
|
-
import { promises, existsSync,
|
|
4
|
-
import { ref } from 'vue';
|
|
3
|
+
import { promises, existsSync, statSync } from 'node:fs';
|
|
5
4
|
import { join } from 'pathe';
|
|
6
5
|
import { upperFirst } from 'scule';
|
|
7
6
|
import { parse } from 'graphql';
|
|
8
7
|
|
|
9
8
|
const name = "@wpnuxt/core";
|
|
10
|
-
const version = "1.0.0-edge.
|
|
9
|
+
const version = "1.0.0-edge.31";
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
let loggerInstance;
|
|
13
12
|
const initLogger = (logLevel) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
if (!loggerInstance) {
|
|
14
|
+
loggerInstance = createConsola({
|
|
15
|
+
level: logLevel ?? 3,
|
|
16
|
+
formatOptions: {
|
|
17
|
+
colors: true,
|
|
18
|
+
compact: true,
|
|
19
|
+
date: true,
|
|
20
|
+
fancy: true
|
|
21
|
+
}
|
|
22
|
+
}).withTag("wpnuxt");
|
|
23
|
+
}
|
|
24
|
+
return loggerInstance;
|
|
24
25
|
};
|
|
25
26
|
const getLogger = () => {
|
|
26
|
-
|
|
27
|
-
return loggerRef.value;
|
|
28
|
-
}
|
|
27
|
+
return loggerInstance;
|
|
29
28
|
};
|
|
30
29
|
function validateConfig(options) {
|
|
31
30
|
if (!options.wordpressUrl || options.wordpressUrl.length === 0) {
|
|
@@ -45,42 +44,98 @@ async function mergeQueries(nuxt) {
|
|
|
45
44
|
await promises.rm(queryOutputPath, { recursive: true, force: true });
|
|
46
45
|
const userQueryPath = "~/extend/queries/".replace(/^(~~|@@)/, nuxt.options.rootDir).replace(/^(~|@)/, nuxt.options.srcDir);
|
|
47
46
|
const userQueryPathExists = existsSync(userQueryPath);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
const queryFiles = /* @__PURE__ */ new Map();
|
|
48
|
+
await copyAndTrack(resolveRuntimeModule("./queries/"), queryOutputPath, queryFiles, "runtime");
|
|
49
|
+
const blocksPath = getAddOnModuleQueriesPath("@wpnuxt/blocks", nuxt);
|
|
50
|
+
if (blocksPath) {
|
|
51
|
+
logger?.debug("Loading queries from @wpnuxt/blocks");
|
|
52
|
+
await copyAndTrack(blocksPath, queryOutputPath, queryFiles, "@wpnuxt/blocks");
|
|
53
|
+
}
|
|
54
|
+
const authPath = getAddOnModuleQueriesPath("@wpnuxt/auth", nuxt);
|
|
55
|
+
if (authPath) {
|
|
56
|
+
logger?.debug("Loading queries from @wpnuxt/auth");
|
|
57
|
+
await copyAndTrack(authPath, queryOutputPath, queryFiles, "@wpnuxt/auth");
|
|
58
|
+
}
|
|
51
59
|
if (userQueryPathExists) {
|
|
52
|
-
logger
|
|
53
|
-
|
|
60
|
+
logger?.debug("Extending queries:", userQueryPath);
|
|
61
|
+
await copyAndTrack(resolve(userQueryPath), queryOutputPath, queryFiles, "user");
|
|
62
|
+
const conflicts = detectQueryConflicts(queryFiles);
|
|
63
|
+
if (conflicts.length > 0) {
|
|
64
|
+
logger?.warn("Query file conflicts detected:");
|
|
65
|
+
conflicts.forEach((conflict) => {
|
|
66
|
+
logger?.warn(` - ${conflict.file} exists in multiple sources: ${conflict.sources.join(", ")}`);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
if (!blocksPath) {
|
|
71
|
+
const moduleName = "wpnuxt/blocks";
|
|
72
|
+
addTemplate({
|
|
73
|
+
write: true,
|
|
74
|
+
filename: moduleName + ".mjs",
|
|
75
|
+
getContents: () => `export { }`
|
|
76
|
+
});
|
|
77
|
+
nuxt.options.alias["#" + moduleName] = resolve(nuxt.options.buildDir, moduleName);
|
|
78
|
+
}
|
|
79
|
+
if (!authPath) {
|
|
80
|
+
const moduleName = "wpnuxt/auth";
|
|
81
|
+
addTemplate({
|
|
82
|
+
write: true,
|
|
83
|
+
filename: moduleName + ".mjs",
|
|
84
|
+
getContents: () => `export { }`
|
|
85
|
+
});
|
|
86
|
+
nuxt.options.alias["#" + moduleName] = resolve(nuxt.options.buildDir, moduleName);
|
|
87
|
+
}
|
|
54
88
|
}
|
|
55
|
-
logger
|
|
89
|
+
logger?.debug("Copied merged queries in folder:", queryOutputPath);
|
|
56
90
|
return queryOutputPath;
|
|
57
91
|
}
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
92
|
+
async function copyAndTrack(sourcePath, destPath, fileMap, sourceLabel) {
|
|
93
|
+
try {
|
|
94
|
+
const entries = await promises.readdir(sourcePath, { withFileTypes: true });
|
|
95
|
+
await promises.mkdir(destPath, { recursive: true });
|
|
96
|
+
await Promise.all(
|
|
97
|
+
entries.map(async (entry) => {
|
|
98
|
+
const srcPath = join(sourcePath, entry.name);
|
|
99
|
+
const destFilePath = join(destPath, entry.name);
|
|
100
|
+
if (entry.isDirectory()) {
|
|
101
|
+
await copyAndTrack(srcPath, destFilePath, fileMap, sourceLabel);
|
|
102
|
+
} else if (entry.isFile() && (entry.name.endsWith(".gql") || entry.name.endsWith(".graphql"))) {
|
|
103
|
+
await promises.copyFile(srcPath, destFilePath);
|
|
104
|
+
const existing = fileMap.get(entry.name);
|
|
105
|
+
fileMap.set(entry.name, existing ? `${existing},${sourceLabel}` : sourceLabel);
|
|
71
106
|
}
|
|
72
|
-
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function detectQueryConflicts(fileMap) {
|
|
113
|
+
const conflicts = [];
|
|
114
|
+
fileMap.forEach((sources, file) => {
|
|
115
|
+
const sourceList = sources.split(",");
|
|
116
|
+
if (sourceList.length > 1) {
|
|
117
|
+
conflicts.push({ file, sources: sourceList });
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return conflicts;
|
|
121
|
+
}
|
|
122
|
+
function getAddOnModuleQueriesPath(addOnModuleName, nuxt) {
|
|
123
|
+
if (!hasNuxtModule(addOnModuleName)) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
const installedModules = nuxt.options._installedModules || [];
|
|
127
|
+
for (const m of installedModules) {
|
|
128
|
+
if (m.meta.name === addOnModuleName && m.entryPath) {
|
|
129
|
+
if (m.entryPath === "../src/module") {
|
|
130
|
+
return join(nuxt.options.rootDir, "../src/runtime/queries/");
|
|
131
|
+
} else if (m.entryPath.startsWith("../")) {
|
|
132
|
+
return join(nuxt.options.rootDir, "../", m.entryPath, "./runtime/queries/");
|
|
133
|
+
} else {
|
|
134
|
+
return join("./node_modules", m.entryPath, "dist/runtime/queries/");
|
|
73
135
|
}
|
|
74
136
|
}
|
|
75
|
-
} else {
|
|
76
|
-
const moduleName = addOnModuleName.replace("@", "");
|
|
77
|
-
addTemplate({
|
|
78
|
-
write: true,
|
|
79
|
-
filename: moduleName + ".mjs",
|
|
80
|
-
getContents: () => `export { }`
|
|
81
|
-
});
|
|
82
|
-
nuxt.options.alias["#" + moduleName] = resolve(nuxt.options.buildDir, moduleName);
|
|
83
137
|
}
|
|
138
|
+
return null;
|
|
84
139
|
}
|
|
85
140
|
|
|
86
141
|
const _parseDoc = async (doc) => {
|
|
@@ -132,44 +187,59 @@ async function prepareContext(ctx) {
|
|
|
132
187
|
const fragments = q.fragments?.length ? q.fragments.map((f) => `${f}Fragment${fragmentSuffix}`).join(" | ") : "any";
|
|
133
188
|
return ` export const ${functionName}: (params?: ${q.name}QueryVariables) => AsyncData<${fragments}, FetchError | null | undefined>`;
|
|
134
189
|
};
|
|
135
|
-
ctx.generateImports = () =>
|
|
136
|
-
|
|
137
|
-
|
|
190
|
+
ctx.generateImports = () => {
|
|
191
|
+
const parts = ["import { useWPContent } from '#imports'", ""];
|
|
192
|
+
for (const fn of ctx.fns) {
|
|
193
|
+
parts.push(fnExp(fn));
|
|
194
|
+
}
|
|
195
|
+
return parts.join("\n");
|
|
196
|
+
};
|
|
138
197
|
const types = [];
|
|
139
|
-
ctx.fns
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
198
|
+
for (const fn of ctx.fns) {
|
|
199
|
+
types.push(...getQueryTypeTemplate(fn));
|
|
200
|
+
}
|
|
201
|
+
ctx.generateDeclarations = () => {
|
|
202
|
+
const declarations = [
|
|
203
|
+
`import type { ${[...new Set(types)].join(", ")} } from '#build/graphql-operations'`,
|
|
204
|
+
"import { AsyncData } from 'nuxt/app'",
|
|
205
|
+
"import { FetchError } from 'ofetch'",
|
|
206
|
+
"declare module '#wpnuxt' {"
|
|
207
|
+
];
|
|
208
|
+
for (const fn of ctx.fns) {
|
|
209
|
+
declarations.push(fnExp(fn, true));
|
|
210
|
+
}
|
|
211
|
+
declarations.push("}");
|
|
212
|
+
return declarations.join("\n");
|
|
213
|
+
};
|
|
150
214
|
ctx.fnImports = ctx.fns.map((fn) => ({ from: "#wpnuxt", name: fnName(fn.name) }));
|
|
151
|
-
logger
|
|
152
|
-
|
|
215
|
+
if (logger) {
|
|
216
|
+
logger.debug("generated WPNuxt composables: ");
|
|
217
|
+
for (const fn of ctx.fns) {
|
|
218
|
+
logger.debug(` ${fnName(fn.name)}()`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
153
221
|
}
|
|
154
222
|
function getQueryTypeTemplate(q) {
|
|
155
|
-
const types = [];
|
|
156
|
-
types.push(`${q.name}QueryVariables`);
|
|
223
|
+
const types = [`${q.name}QueryVariables`];
|
|
157
224
|
if (q.fragments && q.fragments.length > 0) {
|
|
158
|
-
q.fragments
|
|
225
|
+
for (const fragment of q.fragments) {
|
|
226
|
+
types.push(`${fragment}Fragment`);
|
|
227
|
+
}
|
|
159
228
|
}
|
|
160
229
|
return types;
|
|
161
230
|
}
|
|
162
231
|
async function prepareFunctions(ctx) {
|
|
163
232
|
if (!ctx.docs) {
|
|
164
|
-
getLogger()
|
|
233
|
+
getLogger()?.error("no GraphQL query documents were found!");
|
|
165
234
|
return;
|
|
166
235
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
})
|
|
172
|
-
|
|
236
|
+
const allOperations = await Promise.all(
|
|
237
|
+
ctx.docs.map(async (doc) => {
|
|
238
|
+
const content = await promises.readFile(doc, "utf8");
|
|
239
|
+
return parseDoc(content);
|
|
240
|
+
})
|
|
241
|
+
);
|
|
242
|
+
ctx.fns.push(...allOperations.flat());
|
|
173
243
|
}
|
|
174
244
|
|
|
175
245
|
const allowDocument = (f, resolver) => {
|
|
@@ -190,6 +260,7 @@ const defaultConfigs = {
|
|
|
190
260
|
frontendUrl: "",
|
|
191
261
|
defaultMenuName: "main",
|
|
192
262
|
enableCache: true,
|
|
263
|
+
cacheMaxAge: 300,
|
|
193
264
|
staging: false,
|
|
194
265
|
logLevel: 3,
|
|
195
266
|
composablesPrefix: "useWP",
|
|
@@ -201,7 +272,9 @@ const module = defineNuxtModule({
|
|
|
201
272
|
name,
|
|
202
273
|
version,
|
|
203
274
|
configKey: "wpNuxt",
|
|
204
|
-
|
|
275
|
+
compatibility: {
|
|
276
|
+
nuxt: ">=3.1.0"
|
|
277
|
+
}
|
|
205
278
|
},
|
|
206
279
|
// Default configuration options of the Nuxt module
|
|
207
280
|
defaults: defaultConfigs,
|
|
@@ -213,6 +286,7 @@ const module = defineNuxtModule({
|
|
|
213
286
|
frontendUrl: process.env.WPNUXT_FRONTEND_URL || options.frontendUrl,
|
|
214
287
|
defaultMenuName: process.env.WPNUXT_DEFAULT_MENU_NAME || options.defaultMenuName,
|
|
215
288
|
enableCache: process.env.WPNUXT_ENABLE_CACHE ? process.env.WPNUXT_ENABLE_CACHE === "true" : options.enableCache,
|
|
289
|
+
cacheMaxAge: process.env.WPNUXT_CACHE_MAX_AGE ? Number.parseInt(process.env.WPNUXT_CACHE_MAX_AGE) : options.cacheMaxAge,
|
|
216
290
|
staging: process.env.WPNUXT_STAGING === "true" || options.staging,
|
|
217
291
|
downloadSchema: process.env.WPNUXT_DOWNLOAD_SCHEMA === "true" || options.downloadSchema,
|
|
218
292
|
logLevel: process.env.WPNUXT_LOG_LEVEL ? Number.parseInt(process.env.WPNUXT_LOG_LEVEL) : options.logLevel,
|
|
@@ -223,9 +297,9 @@ const module = defineNuxtModule({
|
|
|
223
297
|
nuxt.options.runtimeConfig.public.wpNuxt = publicWPNuxtConfig;
|
|
224
298
|
validateConfig(publicWPNuxtConfig);
|
|
225
299
|
const logger = initLogger(publicWPNuxtConfig.logLevel);
|
|
226
|
-
logger.
|
|
227
|
-
logger.
|
|
228
|
-
logger.info("
|
|
300
|
+
logger.debug("Config:", publicWPNuxtConfig);
|
|
301
|
+
logger.debug("Connecting GraphQL to", publicWPNuxtConfig.wordpressUrl);
|
|
302
|
+
logger.info("WPNuxt frontend URL:", publicWPNuxtConfig.frontendUrl);
|
|
229
303
|
if (publicWPNuxtConfig.enableCache) logger.info("Cache enabled");
|
|
230
304
|
logger.debug("Debug mode enabled, log level:", publicWPNuxtConfig.logLevel);
|
|
231
305
|
if (publicWPNuxtConfig.staging) logger.info("Staging enabled");
|
|
@@ -242,42 +316,35 @@ const module = defineNuxtModule({
|
|
|
242
316
|
addPlugin({
|
|
243
317
|
src: resolveRuntimeModule("plugins/vue-sanitize-directive")
|
|
244
318
|
});
|
|
245
|
-
|
|
246
|
-
{ name: "isStaging", as: "isStaging", from: resolveRuntimeModule("./composables/isStaging") },
|
|
247
|
-
{ name: "useWPContent", as: "useWPContent", from: resolveRuntimeModule("./composables/useWPContent") },
|
|
248
|
-
{ name: "parseDoc", as: "parseDoc", from: resolveRuntimeModule("./composables/useParser") },
|
|
249
|
-
{ name: "usePrevNextPost", as: "usePrevNextPost", from: resolveRuntimeModule("./composables/usePrevNextPost") },
|
|
250
|
-
{ name: "loginUser", as: "loginUser", from: resolveRuntimeModule("./composables/user") },
|
|
251
|
-
{ name: "logoutUser", as: "logoutUser", from: resolveRuntimeModule("./composables/user") },
|
|
252
|
-
{ name: "getCurrentUserId", as: "getCurrentUserId", from: resolveRuntimeModule("./composables/user") },
|
|
253
|
-
{ name: "getCurrentUserName", as: "getCurrentUserName", from: resolveRuntimeModule("./composables/user") },
|
|
254
|
-
{ name: "useTokens", as: "useTokens", from: resolveRuntimeModule("./composables/useTokens") },
|
|
255
|
-
{ name: "useWPUri", as: "useWPUri", from: resolveRuntimeModule("./composables/useWPUri") },
|
|
256
|
-
{ name: "useFeaturedImage", as: "useFeaturedImage", from: resolveRuntimeModule("./composables/useFeaturedImage") }
|
|
257
|
-
]);
|
|
319
|
+
addImportsDir(resolveRuntimeModule("./composables"));
|
|
258
320
|
addComponentsDir({
|
|
259
321
|
path: resolveRuntimeModule("./components"),
|
|
260
322
|
pathPrefix: false,
|
|
261
323
|
prefix: "",
|
|
262
|
-
global:
|
|
324
|
+
global: false,
|
|
325
|
+
// Lazy load components for better performance
|
|
326
|
+
extensions: [".vue"]
|
|
263
327
|
});
|
|
264
328
|
addServerHandler({
|
|
265
|
-
route: "/api/
|
|
266
|
-
handler: resolveRuntimeModule("./server/api/
|
|
329
|
+
route: "/api/_wpnuxt/content",
|
|
330
|
+
handler: resolveRuntimeModule("./server/api/_wpnuxt/content.post")
|
|
267
331
|
});
|
|
268
332
|
addServerHandler({
|
|
269
|
-
route: "/api/config",
|
|
270
|
-
handler: resolveRuntimeModule("./server/api/config")
|
|
333
|
+
route: "/api/_wpnuxt/config",
|
|
334
|
+
handler: resolveRuntimeModule("./server/api/_wpnuxt/config")
|
|
271
335
|
});
|
|
272
|
-
await
|
|
273
|
-
|
|
336
|
+
const [_, mergedQueriesFolder] = await Promise.all([
|
|
337
|
+
installModule("@vueuse/nuxt", {}),
|
|
338
|
+
mergeQueries(nuxt)
|
|
339
|
+
]);
|
|
274
340
|
await installModule("nuxt-graphql-middleware", {
|
|
275
341
|
debug: publicWPNuxtConfig.logLevel ? publicWPNuxtConfig.logLevel > 3 : false,
|
|
276
342
|
graphqlEndpoint: `${publicWPNuxtConfig.wordpressUrl}/graphql`,
|
|
277
343
|
downloadSchema: publicWPNuxtConfig.downloadSchema,
|
|
278
344
|
codegenConfig: {
|
|
279
345
|
debugMode: publicWPNuxtConfig.logLevel ? publicWPNuxtConfig.logLevel > 3 : false,
|
|
280
|
-
useCache:
|
|
346
|
+
useCache: !publicWPNuxtConfig.downloadSchema
|
|
347
|
+
// Cache when schema is committed
|
|
281
348
|
},
|
|
282
349
|
codegenSchemaConfig: {
|
|
283
350
|
urlSchemaOptions: {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NodeWithContentEditorFragment } from '#build/graphql-operations';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
node: NodeWithContentEditorFragment;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -2,5 +2,6 @@ import type { NodeWithContentEditorFragment } from '#build/graphql-operations';
|
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
node: NodeWithContentEditorFragment;
|
|
4
4
|
};
|
|
5
|
-
declare const
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
6
7
|
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { OperationTypeNode } from "graphql";
|
|
3
|
-
import { useWPUri } from "../composables/useWPUri";
|
|
4
|
-
import { useWPContent } from "../composables";
|
|
5
3
|
import WPNuxtLogo from "./WPNuxtLogo.vue";
|
|
6
4
|
import WordPressLogo from "./WordPressLogo.vue";
|
|
7
|
-
import { useRuntimeConfig, useHead, useRoute } from "#imports";
|
|
5
|
+
import { useRuntimeConfig, useHead, useRoute, useWPContent, useWPUri } from "#imports";
|
|
8
6
|
const config = useRuntimeConfig();
|
|
9
7
|
const frontendUrl = config.public.wpNuxt.frontendUrl;
|
|
10
8
|
const wordpressUrl = config.public.wpNuxt.wordpressUrl;
|
|
@@ -38,20 +36,24 @@ if (import.meta.client) {
|
|
|
38
36
|
<div class="bar-left">
|
|
39
37
|
<WPNuxtLogo wp-color="white" />
|
|
40
38
|
<div class="bar-button-wrapper">
|
|
41
|
-
<
|
|
42
|
-
:
|
|
39
|
+
<a
|
|
40
|
+
:href="wpUri.admin"
|
|
43
41
|
class="bar-button"
|
|
42
|
+
target="_blank"
|
|
43
|
+
rel="noopener noreferrer"
|
|
44
44
|
>
|
|
45
45
|
<WordPressLogo /> Admin
|
|
46
|
-
</
|
|
46
|
+
</a>
|
|
47
47
|
</div>
|
|
48
48
|
<div
|
|
49
49
|
v-if="post"
|
|
50
50
|
class="bar-button-wrapper"
|
|
51
51
|
>
|
|
52
|
-
<
|
|
53
|
-
:
|
|
52
|
+
<a
|
|
53
|
+
:href="wpUri.postEdit('' + post.databaseId)"
|
|
54
54
|
class="bar-button primary"
|
|
55
|
+
target="_blank"
|
|
56
|
+
rel="noopener noreferrer"
|
|
55
57
|
>
|
|
56
58
|
<svg
|
|
57
59
|
class="icon"
|
|
@@ -69,16 +71,17 @@ if (import.meta.client) {
|
|
|
69
71
|
/>
|
|
70
72
|
</svg>
|
|
71
73
|
Edit <span class="hidden sm:inline-flex">{{ post.contentTypeName }}</span>
|
|
72
|
-
</
|
|
74
|
+
</a>
|
|
73
75
|
</div>
|
|
74
76
|
</div>
|
|
75
77
|
<div class="bar-right">
|
|
76
78
|
<div class="bar-button-wrapper">
|
|
77
|
-
<
|
|
79
|
+
<a
|
|
78
80
|
v-if="frontendUrl"
|
|
79
|
-
:
|
|
81
|
+
:href="frontendUrl"
|
|
80
82
|
class="bar-button"
|
|
81
83
|
target="_blank"
|
|
84
|
+
rel="noopener noreferrer"
|
|
82
85
|
>
|
|
83
86
|
Live site
|
|
84
87
|
<svg
|
|
@@ -93,7 +96,7 @@ if (import.meta.client) {
|
|
|
93
96
|
d="M18 10.82a1 1 0 0 0-1 1V19a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h7.18a1 1 0 0 0 0-2H5a3 3 0 0 0-3 3v11a3 3 0 0 0 3 3h11a3 3 0 0 0 3-3v-7.18a1 1 0 0 0-1-1m3.92-8.2a1 1 0 0 0-.54-.54A1 1 0 0 0 21 2h-6a1 1 0 0 0 0 2h3.59L8.29 14.29a1 1 0 0 0 0 1.42a1 1 0 0 0 1.42 0L20 5.41V9a1 1 0 0 0 2 0V3a1 1 0 0 0-.08-.38"
|
|
94
97
|
/>
|
|
95
98
|
</svg>
|
|
96
|
-
</
|
|
99
|
+
</a>
|
|
97
100
|
</div>
|
|
98
101
|
</div>
|
|
99
102
|
</div>
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
declare const
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
2
3
|
export default _default;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NodeWithContentEditorFragment, NodeWithEditorBlocksFragment } from '#build/graphql-operations';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
node: NodeWithContentEditorFragment | NodeWithEditorBlocksFragment;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
7
|
+
export default _default;
|
|
@@ -2,5 +2,6 @@ import type { NodeWithContentEditorFragment, NodeWithEditorBlocksFragment } from
|
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
node: NodeWithContentEditorFragment | NodeWithEditorBlocksFragment;
|
|
4
4
|
};
|
|
5
|
-
declare const
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
6
|
+
declare const _default: typeof __VLS_export;
|
|
6
7
|
export default _default;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
wpColor?: string;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
declare const _default: typeof __VLS_export;
|
|
6
|
+
export default _default;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
type __VLS_Props = {
|
|
2
2
|
wpColor?: string;
|
|
3
3
|
};
|
|
4
|
-
declare const
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
declare const _default: typeof __VLS_export;
|
|
5
6
|
export default _default;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
declare const
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
2
3
|
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OperationTypeNode } from "graphql";
|
|
2
|
-
import { useWPContent } from "
|
|
2
|
+
import { useWPContent } from "#imports";
|
|
3
3
|
const _usePrevNextPost = async (currentPostPath) => {
|
|
4
4
|
const currentPostSlug = currentPostPath.replaceAll("/", "");
|
|
5
5
|
const allPosts = await getAllPosts();
|
|
@@ -8,15 +8,15 @@ const _usePrevNextPost = async (currentPostPath) => {
|
|
|
8
8
|
const nextPost = currentIndex > 0 ? allPosts.slugs[currentIndex - 1] : null;
|
|
9
9
|
const prevPost = allPosts.slugs.length > currentIndex + 1 ? allPosts.slugs[currentIndex + 1] : null;
|
|
10
10
|
return {
|
|
11
|
-
prev: prevPost
|
|
12
|
-
next: nextPost
|
|
11
|
+
prev: prevPost ?? null,
|
|
12
|
+
next: nextPost ?? null
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
15
|
const getAllPosts = async () => {
|
|
16
16
|
const { data: allPosts } = await useWPContent(OperationTypeNode.QUERY, "Posts", ["posts", "nodes"], false);
|
|
17
|
-
if (allPosts) {
|
|
17
|
+
if (allPosts && Array.isArray(allPosts)) {
|
|
18
18
|
return {
|
|
19
|
-
slugs: allPosts
|
|
19
|
+
slugs: allPosts.map((post) => {
|
|
20
20
|
if (post) return post.slug;
|
|
21
21
|
else return null;
|
|
22
22
|
})
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { FetchError } from 'ofetch';
|
|
2
2
|
import type { OperationTypeNode } from 'graphql';
|
|
3
|
-
|
|
4
|
-
data
|
|
5
|
-
error
|
|
6
|
-
}
|
|
3
|
+
interface WPContentResponse<T> {
|
|
4
|
+
data?: T;
|
|
5
|
+
error?: FetchError | null;
|
|
6
|
+
}
|
|
7
|
+
export declare const useWPContent: <T>(operation: OperationTypeNode, queryName: string, nodes: string[], fixImagePaths: boolean, params?: T) => Promise<WPContentResponse<T>>;
|
|
8
|
+
export {};
|
|
@@ -1,22 +1,57 @@
|
|
|
1
1
|
import { getRelativeImagePath } from "../util/images.js";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
2
3
|
const _useWPContent = async (operation, queryName, nodes, fixImagePaths, params) => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
try {
|
|
5
|
+
const config = useRuntimeConfig();
|
|
6
|
+
const wordpressUrl = config.public.wpNuxt.wordpressUrl;
|
|
7
|
+
const response = await $fetch("/api/_wpnuxt/content", {
|
|
8
|
+
method: "POST",
|
|
9
|
+
body: {
|
|
10
|
+
operation,
|
|
11
|
+
queryName,
|
|
12
|
+
params
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const { data, error } = response;
|
|
16
|
+
const actualError = error && typeof error === "object" && "value" in error ? error.value : error;
|
|
17
|
+
if (actualError) {
|
|
18
|
+
console.error(`[WPNuxt] Error fetching ${queryName}:`, actualError);
|
|
19
|
+
return { data: void 0, error: actualError };
|
|
9
20
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
21
|
+
return {
|
|
22
|
+
data: data ? transformData(data, nodes, fixImagePaths, wordpressUrl) : void 0,
|
|
23
|
+
error: null
|
|
24
|
+
};
|
|
25
|
+
} catch (err) {
|
|
26
|
+
const fetchError = err;
|
|
27
|
+
console.error(`[WPNuxt] Failed to fetch ${queryName}:`, fetchError.message || err);
|
|
28
|
+
return {
|
|
29
|
+
data: void 0,
|
|
30
|
+
error: fetchError
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const fixMalformedUrls = (content, wordpressUrl) => {
|
|
35
|
+
const urlObj = new URL(wordpressUrl);
|
|
36
|
+
const port = urlObj.port;
|
|
37
|
+
if (port) {
|
|
38
|
+
const malformedPattern = new RegExp(`(href|src)=["']:${port}/`, "g");
|
|
39
|
+
content = content.replace(malformedPattern, `$1="${wordpressUrl}/`);
|
|
40
|
+
}
|
|
41
|
+
return content;
|
|
15
42
|
};
|
|
16
|
-
const transformData = (data, nodes, fixImagePaths) => {
|
|
43
|
+
const transformData = (data, nodes, fixImagePaths, wordpressUrl) => {
|
|
17
44
|
const transformedData = findData(data, nodes);
|
|
18
|
-
if (
|
|
19
|
-
transformedData
|
|
45
|
+
if (transformedData && typeof transformedData === "object") {
|
|
46
|
+
if ("content" in transformedData && typeof transformedData.content === "string") {
|
|
47
|
+
transformedData.content = fixMalformedUrls(transformedData.content, wordpressUrl);
|
|
48
|
+
}
|
|
49
|
+
if (fixImagePaths && "featuredImage" in transformedData) {
|
|
50
|
+
const typed = transformedData;
|
|
51
|
+
if (typed.featuredImage?.node?.sourceUrl) {
|
|
52
|
+
typed.featuredImage.node.relativePath = getRelativeImagePath(typed.featuredImage.node.sourceUrl);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
20
55
|
}
|
|
21
56
|
return transformedData;
|
|
22
57
|
};
|
|
@@ -24,8 +59,12 @@ const findData = (data, nodes) => {
|
|
|
24
59
|
if (nodes.length === 0) return data;
|
|
25
60
|
if (nodes.length > 0) {
|
|
26
61
|
return nodes.reduce((acc, node) => {
|
|
27
|
-
|
|
62
|
+
if (acc && typeof acc === "object" && node in acc) {
|
|
63
|
+
return acc[node];
|
|
64
|
+
}
|
|
65
|
+
return acc;
|
|
28
66
|
}, data);
|
|
29
67
|
}
|
|
68
|
+
return data;
|
|
30
69
|
};
|
|
31
70
|
export const useWPContent = _useWPContent;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
declare
|
|
2
|
-
|
|
1
|
+
declare module 'vue-sanitize-directive' {
|
|
2
|
+
import type { Plugin } from 'vue'
|
|
3
|
+
|
|
4
|
+
const VueSanitizeDirective: Plugin
|
|
5
|
+
export default VueSanitizeDirective
|
|
6
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { defineCachedEventHandler
|
|
1
|
+
import { defineCachedEventHandler } from "nitro/runtime";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
2
3
|
export default defineCachedEventHandler(async (event) => {
|
|
3
4
|
const config = useRuntimeConfig(event);
|
|
4
5
|
return {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare const _default: any;
|
|
2
|
+
export default _default;
|
|
3
|
+
/**
|
|
4
|
+
* Get the parameters for the GraphQL middleware query.
|
|
5
|
+
* Converts complex objects to a JSON string to pass as a single query parameter.
|
|
6
|
+
*
|
|
7
|
+
* @param variables - The GraphQL query variables
|
|
8
|
+
* @returns Query parameters suitable for GET requests
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildRequestParams(variables?: Record<string, unknown> | undefined | null): Record<string, string>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { readBody, createError } from "h3";
|
|
2
|
+
import { LRUCache } from "lru-cache";
|
|
3
|
+
import { defineCachedEventHandler } from "nitro/runtime";
|
|
4
|
+
import { useRuntimeConfig } from "#imports";
|
|
5
|
+
const queryCache = new LRUCache({
|
|
6
|
+
max: 500,
|
|
7
|
+
// Maximum 500 cached queries
|
|
8
|
+
ttl: 1e3 * 60 * 5,
|
|
9
|
+
// 5 minutes TTL
|
|
10
|
+
updateAgeOnGet: true,
|
|
11
|
+
// Refresh TTL on access
|
|
12
|
+
updateAgeOnHas: false
|
|
13
|
+
});
|
|
14
|
+
function fastHash(str) {
|
|
15
|
+
let hash = 2166136261;
|
|
16
|
+
for (let i = 0; i < str.length; i++) {
|
|
17
|
+
hash ^= str.charCodeAt(i);
|
|
18
|
+
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
|
19
|
+
}
|
|
20
|
+
return (hash >>> 0).toString(36);
|
|
21
|
+
}
|
|
22
|
+
async function getCachedBody(event) {
|
|
23
|
+
if (!event.context._wpContentBody) {
|
|
24
|
+
event.context._wpContentBody = await readBody(event);
|
|
25
|
+
}
|
|
26
|
+
return event.context._wpContentBody;
|
|
27
|
+
}
|
|
28
|
+
export default defineCachedEventHandler(async (event) => {
|
|
29
|
+
const config = useRuntimeConfig().public.wpNuxt;
|
|
30
|
+
const body = await getCachedBody(event);
|
|
31
|
+
if (!body || !body.queryName) {
|
|
32
|
+
throw createError({
|
|
33
|
+
statusCode: 400,
|
|
34
|
+
statusMessage: "Bad Request",
|
|
35
|
+
message: "The request must contain a queryName"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const memoryCacheKey = `${body.queryName}_${body.params ? fastHash(JSON.stringify(body.params)) : "no-params"}`;
|
|
39
|
+
const cached = queryCache.get(memoryCacheKey);
|
|
40
|
+
if (cached && config?.enableCache) {
|
|
41
|
+
return {
|
|
42
|
+
data: cached.data,
|
|
43
|
+
error: cached.error
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const operation = body.operation || "query";
|
|
48
|
+
const response = await $fetch(
|
|
49
|
+
`/api/graphql_middleware/${operation}/${body.queryName}`,
|
|
50
|
+
{
|
|
51
|
+
method: operation === "mutation" ? "POST" : "GET",
|
|
52
|
+
params: operation === "query" ? buildRequestParams(body.params) : void 0,
|
|
53
|
+
body: operation === "mutation" ? body.params : void 0,
|
|
54
|
+
headers: {
|
|
55
|
+
Authorization: `Bearer ${event.context.accessToken || ""}`
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
if (response.errors && response.errors.length > 0) {
|
|
60
|
+
console.error(`[WPNuxt] GraphQL errors for ${body.queryName}:`, response.errors);
|
|
61
|
+
}
|
|
62
|
+
const result = {
|
|
63
|
+
data: response.data,
|
|
64
|
+
error: response.errors || void 0
|
|
65
|
+
};
|
|
66
|
+
if (operation === "query" && config?.enableCache) {
|
|
67
|
+
queryCache.set(memoryCacheKey, {
|
|
68
|
+
data: result.data,
|
|
69
|
+
error: result.error,
|
|
70
|
+
timestamp: Date.now()
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error(`[WPNuxt] Failed to fetch GraphQL query ${body.queryName}:`, error);
|
|
76
|
+
throw createError({
|
|
77
|
+
statusCode: 500,
|
|
78
|
+
statusMessage: "Internal Server Error",
|
|
79
|
+
message: `Failed to fetch content: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}, {
|
|
83
|
+
group: "api",
|
|
84
|
+
name: "wpContent",
|
|
85
|
+
getKey: async (event) => {
|
|
86
|
+
const body = await getCachedBody(event);
|
|
87
|
+
const paramsHash = body.params ? fastHash(JSON.stringify(body.params)) : "";
|
|
88
|
+
return `${body.queryName}${paramsHash ? `_${paramsHash}` : ""}`;
|
|
89
|
+
},
|
|
90
|
+
swr: true,
|
|
91
|
+
maxAge: useRuntimeConfig().public.wpNuxt?.cacheMaxAge || 300
|
|
92
|
+
});
|
|
93
|
+
export function buildRequestParams(variables) {
|
|
94
|
+
if (!variables) {
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
97
|
+
for (const key in variables) {
|
|
98
|
+
if (typeof variables[key] !== "string") {
|
|
99
|
+
return {
|
|
100
|
+
__variables: JSON.stringify(variables)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return variables;
|
|
105
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Type declarations for auto-generated modules
|
|
2
|
+
declare module '#graphql-operations' {
|
|
3
|
+
export * from '#build/graphql-operations'
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
declare module '#build/graphql-operations' {
|
|
7
|
+
// These types are auto-generated by nuxt-graphql-middleware
|
|
8
|
+
export interface NodeByUriQueryVariables {
|
|
9
|
+
uri?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PostsQueryVariables {
|
|
13
|
+
first?: number
|
|
14
|
+
after?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Fragment types
|
|
18
|
+
export interface MenuItemFragment {
|
|
19
|
+
id?: string
|
|
20
|
+
label?: string
|
|
21
|
+
url?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PostFragment {
|
|
25
|
+
id?: string
|
|
26
|
+
title?: string
|
|
27
|
+
content?: string
|
|
28
|
+
slug?: string
|
|
29
|
+
uri?: string
|
|
30
|
+
date?: string
|
|
31
|
+
excerpt?: string
|
|
32
|
+
contentTypeName?: string
|
|
33
|
+
categories?: {
|
|
34
|
+
nodes?: Array<{ name?: string }>
|
|
35
|
+
}
|
|
36
|
+
featuredImage?: {
|
|
37
|
+
node?: {
|
|
38
|
+
sourceUrl?: string
|
|
39
|
+
altText?: string
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface PageFragment {
|
|
45
|
+
id?: string
|
|
46
|
+
title?: string
|
|
47
|
+
content?: string
|
|
48
|
+
slug?: string
|
|
49
|
+
uri?: string
|
|
50
|
+
date?: string
|
|
51
|
+
contentTypeName?: string
|
|
52
|
+
featuredImage?: {
|
|
53
|
+
node?: {
|
|
54
|
+
sourceUrl?: string
|
|
55
|
+
altText?: string
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface NodeWithContentEditorFragment {
|
|
61
|
+
id?: string
|
|
62
|
+
content?: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface NodeWithEditorBlocksFragment {
|
|
66
|
+
id?: string
|
|
67
|
+
editorBlocks?: unknown[]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface NodeWithFeaturedImage {
|
|
71
|
+
id?: string
|
|
72
|
+
featuredImage?: {
|
|
73
|
+
node?: {
|
|
74
|
+
sourceUrl?: string
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Add more as needed by the actual GraphQL schema
|
|
80
|
+
export type Maybe<T> = T | null
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare module '#wpnuxt/blocks' {
|
|
84
|
+
// Placeholder for blocks module types
|
|
85
|
+
export const CoreButton: unknown
|
|
86
|
+
export const BlockRenderer: unknown
|
|
87
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wpnuxt/core",
|
|
3
|
-
"version": "1.0.0-edge.
|
|
3
|
+
"version": "1.0.0-edge.31",
|
|
4
4
|
"description": "WPNuxt",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -51,45 +51,44 @@
|
|
|
51
51
|
"start": "pnpm run wp-env:create && pnpm run dev"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@nuxt/kit": "
|
|
55
|
-
"@vueuse/nuxt": "^
|
|
54
|
+
"@nuxt/kit": "4.2.2",
|
|
55
|
+
"@vueuse/nuxt": "^14.1.0",
|
|
56
|
+
"consola": "^3.4.2",
|
|
56
57
|
"defu": "^6.1.4",
|
|
57
|
-
"graphql": "^16.
|
|
58
|
-
"
|
|
58
|
+
"graphql": "^16.12.0",
|
|
59
|
+
"knitwork": "^1.3.0",
|
|
60
|
+
"lru-cache": "^11.2.4",
|
|
61
|
+
"nuxt-graphql-middleware": "5.2.3",
|
|
62
|
+
"pathe": "^2.0.3",
|
|
63
|
+
"scule": "^1.3.0",
|
|
59
64
|
"vue-sanitize-directive": "^0.2.1"
|
|
60
65
|
},
|
|
61
66
|
"devDependencies": {
|
|
62
|
-
"@nuxt/devtools": "^
|
|
63
|
-
"@nuxt/eslint-config": "^1.
|
|
64
|
-
"@nuxt/module-builder": "^1.0.
|
|
65
|
-
"@nuxt/schema": "
|
|
66
|
-
"@nuxt/test-utils": "^3.
|
|
67
|
-
"@rollup/rollup-linux-arm64-gnu": "^4.
|
|
68
|
-
"@rollup/rollup-linux-arm64-musl": "^4.
|
|
69
|
-
"@types/node": "
|
|
70
|
-
"@vitest/coverage-v8": "^
|
|
67
|
+
"@nuxt/devtools": "^3.1.1",
|
|
68
|
+
"@nuxt/eslint-config": "^1.12.1",
|
|
69
|
+
"@nuxt/module-builder": "^1.0.2",
|
|
70
|
+
"@nuxt/schema": "4.2.2",
|
|
71
|
+
"@nuxt/test-utils": "^3.21.0",
|
|
72
|
+
"@rollup/rollup-linux-arm64-gnu": "^4.53.5",
|
|
73
|
+
"@rollup/rollup-linux-arm64-musl": "^4.53.5",
|
|
74
|
+
"@types/node": "25.0.3",
|
|
75
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
71
76
|
"@vue/test-utils": "^2.4.6",
|
|
72
|
-
"@wordpress/env": "^10.
|
|
73
|
-
"changelogen": "^0.6.
|
|
74
|
-
"markdownlint-cli": "^0.
|
|
75
|
-
"nuxt": "^
|
|
77
|
+
"@wordpress/env": "^10.36.0",
|
|
78
|
+
"changelogen": "^0.6.2",
|
|
79
|
+
"markdownlint-cli": "^0.47.0",
|
|
80
|
+
"nuxt": "^4.2.2",
|
|
76
81
|
"nuxt-content-twoslash": "^0.1.2",
|
|
77
|
-
"release-it": "^19.0
|
|
78
|
-
"typescript": "^5.
|
|
82
|
+
"release-it": "^19.1.0",
|
|
83
|
+
"typescript": "^5.9.3",
|
|
79
84
|
"untyped": "2.0.0",
|
|
80
|
-
"vite": "^
|
|
81
|
-
"vitest": "^
|
|
85
|
+
"vite": "^7.3.0",
|
|
86
|
+
"vitest": "^4.0.16",
|
|
82
87
|
"vue-docgen-web-types": "^0.1.8",
|
|
83
|
-
"vue-tsc": "
|
|
84
|
-
},
|
|
85
|
-
"peerDependencies": {
|
|
86
|
-
"consola": "^3.3.3",
|
|
87
|
-
"graphql": "^16.10.0",
|
|
88
|
-
"knitwork": "^1.2.0",
|
|
89
|
-
"pathe": "^2.0.1",
|
|
90
|
-
"scule": "^1.3.0"
|
|
88
|
+
"vue-tsc": "3.1.8"
|
|
91
89
|
},
|
|
92
90
|
"engines": {
|
|
93
91
|
"node": ">=20"
|
|
94
|
-
}
|
|
92
|
+
},
|
|
93
|
+
"packageManager": "pnpm@10.18.0+sha512.e804f889f1cecc40d572db084eec3e4881739f8dec69c0ff10d2d1beff9a4e309383ba27b5b750059d7f4c149535b6cd0d2cb1ed3aeb739239a4284a68f40cfa"
|
|
95
94
|
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { readBody } from "h3";
|
|
2
|
-
import { defineCachedEventHandler } from "#imports";
|
|
3
|
-
export default defineCachedEventHandler(async (event) => {
|
|
4
|
-
const body = await readBody(event);
|
|
5
|
-
if (!body || !body.queryName) {
|
|
6
|
-
throw new Error(
|
|
7
|
-
"The request must contain a queryName"
|
|
8
|
-
);
|
|
9
|
-
}
|
|
10
|
-
return $fetch("/api/graphql_middleware/" + (body.operation || "query") + "/" + body.queryName, {
|
|
11
|
-
method: body.operation === "mutation" ? "POST" : "GET",
|
|
12
|
-
params: body.operation === "query" ? buildRequestParams(body.params) : void 0,
|
|
13
|
-
body: body.operation === "mutation" ? body.params : void 0,
|
|
14
|
-
headers: {
|
|
15
|
-
Authorization: `Bearer ${event.context.accessToken}`
|
|
16
|
-
}
|
|
17
|
-
}).then((v) => {
|
|
18
|
-
return {
|
|
19
|
-
data: v.data,
|
|
20
|
-
error: v.errors || void 0
|
|
21
|
-
};
|
|
22
|
-
});
|
|
23
|
-
}, {
|
|
24
|
-
group: "api",
|
|
25
|
-
name: "wpContent",
|
|
26
|
-
getKey: async (event) => {
|
|
27
|
-
const body = await readBody(event);
|
|
28
|
-
return `${body.queryName}${body.params ? "_" + JSON.stringify(body.params).replaceAll('"', "").replaceAll(":", "_") : ""}`;
|
|
29
|
-
},
|
|
30
|
-
swr: true,
|
|
31
|
-
maxAge: 60 * 5
|
|
32
|
-
// 5 minutes
|
|
33
|
-
});
|
|
34
|
-
export function buildRequestParams(variables) {
|
|
35
|
-
if (!variables) {
|
|
36
|
-
return {};
|
|
37
|
-
}
|
|
38
|
-
for (const key in variables) {
|
|
39
|
-
if (typeof variables[key] !== "string") {
|
|
40
|
-
return {
|
|
41
|
-
__variables: JSON.stringify(variables)
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return variables;
|
|
46
|
-
}
|
|
File without changes
|