@wpnuxt/core 1.0.0-edge.4
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 +89 -0
- package/dist/module.cjs +5 -0
- package/dist/module.d.mts +116 -0
- package/dist/module.d.ts +116 -0
- package/dist/module.json +10 -0
- package/dist/module.mjs +357 -0
- package/dist/runtime/app/graphqlMiddleware.serverOptions.d.ts +2 -0
- package/dist/runtime/app/graphqlMiddleware.serverOptions.js +11 -0
- package/dist/runtime/components/StagingBanner.vue +107 -0
- package/dist/runtime/components/WPNuxtLogo.vue +17 -0
- package/dist/runtime/components/WordPressLogo.vue +15 -0
- package/dist/runtime/composables/index.d.ts +3 -0
- package/dist/runtime/composables/index.js +3 -0
- package/dist/runtime/composables/isStaging.d.ts +1 -0
- package/dist/runtime/composables/isStaging.js +6 -0
- package/dist/runtime/composables/useFeaturedImage.d.ts +2 -0
- package/dist/runtime/composables/useFeaturedImage.js +7 -0
- package/dist/runtime/composables/usePrevNextPost.d.ts +4 -0
- package/dist/runtime/composables/usePrevNextPost.js +25 -0
- package/dist/runtime/composables/useWPContent.d.ts +3 -0
- package/dist/runtime/composables/useWPContent.js +35 -0
- package/dist/runtime/composables/useWPUri.d.ts +8 -0
- package/dist/runtime/composables/useWPUri.js +23 -0
- package/dist/runtime/plugins/vue-sanitize-directive.d.ts +2 -0
- package/dist/runtime/plugins/vue-sanitize-directive.js +5 -0
- package/dist/runtime/queries/GeneralSettings.gql +7 -0
- package/dist/runtime/queries/Menu.gql +11 -0
- package/dist/runtime/queries/Node.gql +9 -0
- package/dist/runtime/queries/Pages.gql +19 -0
- package/dist/runtime/queries/Posts.gql +19 -0
- package/dist/runtime/queries/Revisions.gql +9 -0
- package/dist/runtime/queries/Viewer.gql +14 -0
- package/dist/runtime/queries/fragments/ContentNode.fragment.gql +28 -0
- package/dist/runtime/queries/fragments/GeneralSettings.fragment.gql +11 -0
- package/dist/runtime/queries/fragments/MediaItem.fragment.gql +52 -0
- package/dist/runtime/queries/fragments/MenuItem.fragment.gql +4 -0
- package/dist/runtime/queries/fragments/NodeWithExcerpt.fragment.gql +3 -0
- package/dist/runtime/queries/fragments/NodeWithFeaturedImage.fragment.gql +10 -0
- package/dist/runtime/queries/fragments/NodeWithFeaturedImageToMediaItemConnectionEdge.fragment.gql +8 -0
- package/dist/runtime/queries/fragments/Page.fragment.gql +15 -0
- package/dist/runtime/queries/fragments/Post.fragment.gql +11 -0
- package/dist/runtime/server/api/purgeCache.get.d.ts +5 -0
- package/dist/runtime/server/api/purgeCache.get.js +9 -0
- package/dist/runtime/server/api/wpContent.post.d.ts +9 -0
- package/dist/runtime/server/api/wpContent.post.js +50 -0
- package/dist/runtime/server/index.d.ts +1 -0
- package/dist/runtime/server/index.js +8 -0
- package/dist/runtime/server/storage.d.ts +3 -0
- package/dist/runtime/server/storage.js +11 -0
- package/dist/runtime/util/images.d.ts +2 -0
- package/dist/runtime/util/images.js +8 -0
- package/dist/runtime/util/logger.d.ts +3 -0
- package/dist/runtime/util/logger.js +25 -0
- package/dist/types.d.mts +7 -0
- package/dist/types.d.ts +7 -0
- package/package.json +100 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
|
|
2
|
+
This module is still being developed and not ready for production usage yet.
|
|
3
|
+
There will be many smaller alpha releases the coming weeks, often with breaking changes.
|
|
4
|
+
|
|
5
|
+
I am working towards a stable release. And will inform about it here
|
|
6
|
+
|
|
7
|
+
# WPNuxt
|
|
8
|
+
|
|
9
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
10
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
11
|
+
[![License][license-src]][license-href]
|
|
12
|
+
[![Nuxt][nuxt-src]][nuxt-href]
|
|
13
|
+
|
|
14
|
+
Nuxt module for using WordPress as a headless CMS with a Nuxt 3 frontend
|
|
15
|
+
|
|
16
|
+
- [✨ Release Notes](/CHANGELOG.md)
|
|
17
|
+
<!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
|
|
18
|
+
<!-- - [📖 Documentation](https://example.com) -->
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Content is fetched from WordPress using server-side GraphQL api calls
|
|
23
|
+
- Support for (Gutenberg Blocks), using WPEngine's wp-graphql-content-blocks https://faustjs.org/tutorial/get-started-with-wp-graphql-content-blocks
|
|
24
|
+
|
|
25
|
+
## Quick Setup
|
|
26
|
+
|
|
27
|
+
1. Add `@vernaillen/wpnuxt` dependency to your project
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Using pnpm
|
|
31
|
+
pnpm add -D @vernaillen/wpnuxt
|
|
32
|
+
|
|
33
|
+
# Using yarn
|
|
34
|
+
yarn add --dev @vernaillen/wpnuxt
|
|
35
|
+
|
|
36
|
+
# Using npm
|
|
37
|
+
npm install --save-dev @vernaillen/wpnuxt
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. Add '@vernaillen/wpnuxt' to the `modules` section of `nuxt.config.ts`
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
export default defineNuxtConfig({
|
|
44
|
+
modules: [
|
|
45
|
+
'@vernaillen/wpnuxt'
|
|
46
|
+
]
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That's it! You can now use the WPNuxt module in your Nuxt app ✨
|
|
51
|
+
|
|
52
|
+
## Development
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Install dependencies
|
|
56
|
+
npm install
|
|
57
|
+
|
|
58
|
+
# Generate type stubs
|
|
59
|
+
npm run dev:prepare
|
|
60
|
+
|
|
61
|
+
# Develop with the playground
|
|
62
|
+
npm run dev
|
|
63
|
+
|
|
64
|
+
# Build the playground
|
|
65
|
+
npm run dev:build
|
|
66
|
+
|
|
67
|
+
# Run ESLint
|
|
68
|
+
npm run lint
|
|
69
|
+
|
|
70
|
+
# Run Vitest
|
|
71
|
+
npm run test
|
|
72
|
+
npm run test:watch
|
|
73
|
+
|
|
74
|
+
# Release new version
|
|
75
|
+
npm run release
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
<!-- Badges -->
|
|
79
|
+
[npm-version-src]: https://img.shields.io/npm/v/@vernaillen/wpnuxt/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
80
|
+
[npm-version-href]: https://www.npmjs.com/package/@vernaillen/wpnuxt
|
|
81
|
+
|
|
82
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/@vernaillen/wpnuxt.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
83
|
+
[npm-downloads-href]: https://www.npmjs.com/package/@vernaillen/wpnuxt
|
|
84
|
+
|
|
85
|
+
[license-src]: https://img.shields.io/npm/l/@vernaillen/wpnuxt?style=flat&colorA=18181B&colorB=28CF8D
|
|
86
|
+
[license-href]: https://www.npmjs.com/package/@vernaillen/wpnuxt
|
|
87
|
+
|
|
88
|
+
[nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
|
|
89
|
+
[nuxt-href]: https://nuxt.com
|
package/dist/module.cjs
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface WPNuxtConfig {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Log level for the WPNuxt module
|
|
7
|
+
* @default 3
|
|
8
|
+
* @example 0 = silent, 1 = error, 2 = warn, 3 = info, 4 = debug, 5 = trace
|
|
9
|
+
*/
|
|
10
|
+
logLevel?: number
|
|
11
|
+
/**
|
|
12
|
+
* URL of the WordPress site
|
|
13
|
+
*
|
|
14
|
+
* There is no default value for this option, so it's required.
|
|
15
|
+
*
|
|
16
|
+
* @example 'https://wordpress.wpnuxt.com'
|
|
17
|
+
*/
|
|
18
|
+
wordpressUrl: string
|
|
19
|
+
frontendUrl: string
|
|
20
|
+
|
|
21
|
+
faustSecretKey?: string
|
|
22
|
+
defaultMenuName?: string
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Enable custom components for Gutenberg blocks
|
|
26
|
+
* When disabled the module will use the renderedHtml of each block returned by WordPress
|
|
27
|
+
*
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
blocks?: boolean
|
|
31
|
+
|
|
32
|
+
replaceSchema?: boolean
|
|
33
|
+
enableCache?: boolean
|
|
34
|
+
|
|
35
|
+
staging?: boolean
|
|
36
|
+
/**
|
|
37
|
+
* Generate composables based on the GraphQL queries, provided by both the WPNuxt module as the queries added by the user.
|
|
38
|
+
*
|
|
39
|
+
* @default { enabled: true, prefix: 'useWP' }
|
|
40
|
+
*/
|
|
41
|
+
generateComposables?: WPNuxtConfigComposables
|
|
42
|
+
|
|
43
|
+
queries?: WPNuxtConfigQueries
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Download the GraphQL schema and store it on disk.
|
|
47
|
+
*
|
|
48
|
+
* When setting this to false, the module will expect a graphql.schema file to be available.
|
|
49
|
+
* You could first enable this, commit the schema file and then set downloadSchema to false to avoid have to query the graphql introspection on each start of the application
|
|
50
|
+
*
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
downloadSchema?: boolean
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface WPNuxtConfigComposables {
|
|
57
|
+
enabled?: boolean
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Prefix to use for generated composables
|
|
61
|
+
*
|
|
62
|
+
* @example 'useWP' => 'useWPPages', 'useWPPosts', 'useWPMenu'
|
|
63
|
+
* @default 'useWP'
|
|
64
|
+
*/
|
|
65
|
+
prefix?: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface WPNuxtConfigQueries {
|
|
69
|
+
/**
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
usePredefinedQueries?: boolean
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Folder for user defined queries
|
|
76
|
+
*
|
|
77
|
+
* relative to the src dir of your nuxt app
|
|
78
|
+
*
|
|
79
|
+
* @default extend/queries
|
|
80
|
+
*/
|
|
81
|
+
extendDir?: string
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The predefined queries & the user defined queries will be merged and placed in the queries output folder
|
|
85
|
+
*
|
|
86
|
+
* relative to the src dir of your nuxt app
|
|
87
|
+
*
|
|
88
|
+
* @default queries
|
|
89
|
+
*/
|
|
90
|
+
outputDir?: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
declare const _default: _nuxt_schema.NuxtModule<WPNuxtConfig>;
|
|
94
|
+
|
|
95
|
+
declare module '@nuxt/schema' {
|
|
96
|
+
interface RuntimeConfig {
|
|
97
|
+
wpNuxt: {
|
|
98
|
+
faustSecretKey: string;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
interface PublicRuntimeConfig {
|
|
102
|
+
wpNuxt: WPNuxtConfig;
|
|
103
|
+
}
|
|
104
|
+
interface ConfigSchema {
|
|
105
|
+
wpNuxt: {
|
|
106
|
+
faustSecretKey: string;
|
|
107
|
+
};
|
|
108
|
+
runtimeConfig: {
|
|
109
|
+
public?: {
|
|
110
|
+
wpNuxt: WPNuxtConfig;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export { _default as default };
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface WPNuxtConfig {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Log level for the WPNuxt module
|
|
7
|
+
* @default 3
|
|
8
|
+
* @example 0 = silent, 1 = error, 2 = warn, 3 = info, 4 = debug, 5 = trace
|
|
9
|
+
*/
|
|
10
|
+
logLevel?: number
|
|
11
|
+
/**
|
|
12
|
+
* URL of the WordPress site
|
|
13
|
+
*
|
|
14
|
+
* There is no default value for this option, so it's required.
|
|
15
|
+
*
|
|
16
|
+
* @example 'https://wordpress.wpnuxt.com'
|
|
17
|
+
*/
|
|
18
|
+
wordpressUrl: string
|
|
19
|
+
frontendUrl: string
|
|
20
|
+
|
|
21
|
+
faustSecretKey?: string
|
|
22
|
+
defaultMenuName?: string
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Enable custom components for Gutenberg blocks
|
|
26
|
+
* When disabled the module will use the renderedHtml of each block returned by WordPress
|
|
27
|
+
*
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
blocks?: boolean
|
|
31
|
+
|
|
32
|
+
replaceSchema?: boolean
|
|
33
|
+
enableCache?: boolean
|
|
34
|
+
|
|
35
|
+
staging?: boolean
|
|
36
|
+
/**
|
|
37
|
+
* Generate composables based on the GraphQL queries, provided by both the WPNuxt module as the queries added by the user.
|
|
38
|
+
*
|
|
39
|
+
* @default { enabled: true, prefix: 'useWP' }
|
|
40
|
+
*/
|
|
41
|
+
generateComposables?: WPNuxtConfigComposables
|
|
42
|
+
|
|
43
|
+
queries?: WPNuxtConfigQueries
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Download the GraphQL schema and store it on disk.
|
|
47
|
+
*
|
|
48
|
+
* When setting this to false, the module will expect a graphql.schema file to be available.
|
|
49
|
+
* You could first enable this, commit the schema file and then set downloadSchema to false to avoid have to query the graphql introspection on each start of the application
|
|
50
|
+
*
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
downloadSchema?: boolean
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface WPNuxtConfigComposables {
|
|
57
|
+
enabled?: boolean
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Prefix to use for generated composables
|
|
61
|
+
*
|
|
62
|
+
* @example 'useWP' => 'useWPPages', 'useWPPosts', 'useWPMenu'
|
|
63
|
+
* @default 'useWP'
|
|
64
|
+
*/
|
|
65
|
+
prefix?: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface WPNuxtConfigQueries {
|
|
69
|
+
/**
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
usePredefinedQueries?: boolean
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Folder for user defined queries
|
|
76
|
+
*
|
|
77
|
+
* relative to the src dir of your nuxt app
|
|
78
|
+
*
|
|
79
|
+
* @default extend/queries
|
|
80
|
+
*/
|
|
81
|
+
extendDir?: string
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The predefined queries & the user defined queries will be merged and placed in the queries output folder
|
|
85
|
+
*
|
|
86
|
+
* relative to the src dir of your nuxt app
|
|
87
|
+
*
|
|
88
|
+
* @default queries
|
|
89
|
+
*/
|
|
90
|
+
outputDir?: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
declare const _default: _nuxt_schema.NuxtModule<WPNuxtConfig>;
|
|
94
|
+
|
|
95
|
+
declare module '@nuxt/schema' {
|
|
96
|
+
interface RuntimeConfig {
|
|
97
|
+
wpNuxt: {
|
|
98
|
+
faustSecretKey: string;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
interface PublicRuntimeConfig {
|
|
102
|
+
wpNuxt: WPNuxtConfig;
|
|
103
|
+
}
|
|
104
|
+
interface ConfigSchema {
|
|
105
|
+
wpNuxt: {
|
|
106
|
+
faustSecretKey: string;
|
|
107
|
+
};
|
|
108
|
+
runtimeConfig: {
|
|
109
|
+
public?: {
|
|
110
|
+
wpNuxt: WPNuxtConfig;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export { _default as default };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { promises, statSync, existsSync, cpSync } from 'node:fs';
|
|
2
|
+
import { resolveFiles, defineNuxtModule, createResolver, addPlugin, addImports, addComponent, addServerHandler, installModule, hasNuxtModule, addTemplate } from '@nuxt/kit';
|
|
3
|
+
import defu from 'defu';
|
|
4
|
+
import { join } from 'pathe';
|
|
5
|
+
import consola, { createConsola } from 'consola';
|
|
6
|
+
import { ref } from 'vue';
|
|
7
|
+
import { upperFirst } from 'scule';
|
|
8
|
+
import { parse } from 'graphql';
|
|
9
|
+
|
|
10
|
+
const name = "@wpnuxt/core";
|
|
11
|
+
const version = "1.0.0-edge.4";
|
|
12
|
+
|
|
13
|
+
const loggerRef = ref();
|
|
14
|
+
const initLogger = (logLevel) => {
|
|
15
|
+
loggerRef.value = createConsola({
|
|
16
|
+
level: logLevel ? logLevel : 3,
|
|
17
|
+
formatOptions: {
|
|
18
|
+
colors: true,
|
|
19
|
+
compact: true,
|
|
20
|
+
date: true,
|
|
21
|
+
fancy: true
|
|
22
|
+
}
|
|
23
|
+
}).withTag("wpnuxt");
|
|
24
|
+
return loggerRef.value;
|
|
25
|
+
};
|
|
26
|
+
const getLogger = () => {
|
|
27
|
+
if (loggerRef.value) {
|
|
28
|
+
return loggerRef.value;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function validateConfig(options) {
|
|
32
|
+
if (!options.wordpressUrl || options.wordpressUrl.length === 0) {
|
|
33
|
+
throw new Error("WPNuxt error: WordPress url is missing");
|
|
34
|
+
} else if (options.wordpressUrl.substring(options.wordpressUrl.length - 1) === "/") {
|
|
35
|
+
throw new Error("WPNuxt error: WordPress url should not have a trailing slash: " + options.wordpressUrl);
|
|
36
|
+
}
|
|
37
|
+
if (options.frontendUrl && options.frontendUrl.substring(options.frontendUrl.length - 1) === "/") {
|
|
38
|
+
throw new Error("WPNuxt error: frontend url should not have a trailing slash: " + options.frontendUrl);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const _parseDoc = async (doc) => {
|
|
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(`Operation name missing in: ${doc}`);
|
|
48
|
+
}
|
|
49
|
+
const query = {
|
|
50
|
+
name: operationDefinition.name.value.trim(),
|
|
51
|
+
nodes: [],
|
|
52
|
+
fragments: [],
|
|
53
|
+
params: {}
|
|
54
|
+
};
|
|
55
|
+
processSelections(operationDefinition.selectionSet.selections, 0, query);
|
|
56
|
+
return query;
|
|
57
|
+
});
|
|
58
|
+
return operations;
|
|
59
|
+
};
|
|
60
|
+
function processSelections(selections, level, query) {
|
|
61
|
+
if (!selections || selections.length === 0)
|
|
62
|
+
return;
|
|
63
|
+
if (selections.length === 1 && selections[0].kind === "Field") {
|
|
64
|
+
query.nodes.push(selections[0].name.value.trim());
|
|
65
|
+
}
|
|
66
|
+
selections.forEach((s) => {
|
|
67
|
+
if (s.kind === "FragmentSpread") {
|
|
68
|
+
query.fragments.push(s.name.value.trim());
|
|
69
|
+
} else if (s.selectionSet?.selections) {
|
|
70
|
+
processSelections(s.selectionSet.selections, level + 1, query);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const parseDoc = _parseDoc;
|
|
75
|
+
|
|
76
|
+
async function prepareContext(ctx) {
|
|
77
|
+
const logger = getLogger();
|
|
78
|
+
if (ctx.docs) {
|
|
79
|
+
await prepareFunctions(ctx);
|
|
80
|
+
}
|
|
81
|
+
const fnName = (fn) => ctx.composables.prefix + upperFirst(fn);
|
|
82
|
+
const fnExp = (q, typed = false) => {
|
|
83
|
+
const functionName = fnName(q.name);
|
|
84
|
+
if (!typed) {
|
|
85
|
+
const nodesArray = q.nodes?.map((n) => `'${n}'`);
|
|
86
|
+
return `export const ${functionName} = (params) => useWPContent('${q.name}', [${nodesArray?.join(",")}], false, params)`;
|
|
87
|
+
}
|
|
88
|
+
let fragmentSuffix = "";
|
|
89
|
+
if (q.fragments && q.fragments.length > 0 && q.nodes && q.nodes.length > 0 && q.nodes.includes("nodes")) {
|
|
90
|
+
fragmentSuffix = "[]";
|
|
91
|
+
}
|
|
92
|
+
const fragments = q.fragments && q.fragments.length > 0 ? q.fragments.map((f) => `${f}Fragment${fragmentSuffix}`).join(" | ") : "any";
|
|
93
|
+
return ` export const ${functionName}: (params?: ${q.name}QueryVariables) => AsyncData<${fragments}, FetchError | null | undefined>`;
|
|
94
|
+
};
|
|
95
|
+
ctx.generateImports = () => [
|
|
96
|
+
...ctx.fns.map((f) => fnExp(f))
|
|
97
|
+
].join("\n");
|
|
98
|
+
const types = [];
|
|
99
|
+
ctx.fns.forEach((o) => types.push(...getQueryTypeTemplate(o)));
|
|
100
|
+
ctx.generateDeclarations = () => [
|
|
101
|
+
`import type { ${[...new Set(types)].join(", ")} } from '#build/graphql-operations'`,
|
|
102
|
+
"import { AsyncData } from 'nuxt/app'",
|
|
103
|
+
"import { FetchError } from 'ofetch'",
|
|
104
|
+
"declare module '#wpnuxt' {",
|
|
105
|
+
...[
|
|
106
|
+
...ctx.fns.map((f) => fnExp(f, true))
|
|
107
|
+
],
|
|
108
|
+
"}"
|
|
109
|
+
].join("\n");
|
|
110
|
+
ctx.fnImports = ctx.fns.map((fn) => ({ from: "#wpnuxt", name: fnName(fn.name) }));
|
|
111
|
+
logger.debug("generated WPNuxt composables: ");
|
|
112
|
+
ctx.fns.forEach((f) => logger.debug(` ${fnName(f.name)}()`));
|
|
113
|
+
}
|
|
114
|
+
function getQueryTypeTemplate(q) {
|
|
115
|
+
const types = [];
|
|
116
|
+
types.push(`${q.name}QueryVariables`);
|
|
117
|
+
if (q.fragments && q.fragments.length > 0) {
|
|
118
|
+
q.fragments.forEach((f) => types.push(`${f}Fragment`));
|
|
119
|
+
}
|
|
120
|
+
return types;
|
|
121
|
+
}
|
|
122
|
+
async function prepareFunctions(ctx) {
|
|
123
|
+
if (!ctx.docs) {
|
|
124
|
+
getLogger().error("no GraphQL query documents were found!");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
for await (const doc of ctx.docs) {
|
|
128
|
+
const operations = await parseDoc(await promises.readFile(doc, "utf8"));
|
|
129
|
+
operations.forEach((query) => {
|
|
130
|
+
ctx.fns.push(query);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const allowDocument = (f, resolver) => {
|
|
136
|
+
const isSchema = f.match(/([^/]+)\.(gql|graphql)$/)?.[0]?.toLowerCase().includes("schema");
|
|
137
|
+
return !isSchema && !!statSync(resolver.resolve(f)).size;
|
|
138
|
+
};
|
|
139
|
+
async function generateWPNuxtComposables(ctx, queryOutputPath, resolver) {
|
|
140
|
+
const gqlMatch = "**/*.{gql,graphql}";
|
|
141
|
+
const documents = [];
|
|
142
|
+
const files = (await resolveFiles(queryOutputPath, [gqlMatch, "!**/schemas"], { followSymbolicLinks: false })).filter((doc) => allowDocument(doc, resolver));
|
|
143
|
+
documents.push(...files);
|
|
144
|
+
ctx.docs = documents;
|
|
145
|
+
await prepareContext(ctx);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const defaultComposablesConfig = {
|
|
149
|
+
enabled: true,
|
|
150
|
+
prefix: "useWP"
|
|
151
|
+
};
|
|
152
|
+
const defaultConfigs = {
|
|
153
|
+
wordpressUrl: "",
|
|
154
|
+
frontendUrl: "",
|
|
155
|
+
faustSecretKey: "",
|
|
156
|
+
defaultMenuName: "main",
|
|
157
|
+
blocks: true,
|
|
158
|
+
replaceSchema: false,
|
|
159
|
+
enableCache: true,
|
|
160
|
+
staging: false,
|
|
161
|
+
logLevel: 3,
|
|
162
|
+
generateComposables: defaultComposablesConfig
|
|
163
|
+
};
|
|
164
|
+
const module = defineNuxtModule({
|
|
165
|
+
meta: {
|
|
166
|
+
name,
|
|
167
|
+
version,
|
|
168
|
+
configKey: "wpNuxt",
|
|
169
|
+
nuxt: ">=3.1.0"
|
|
170
|
+
},
|
|
171
|
+
// Default configuration options of the Nuxt module
|
|
172
|
+
defaults: defaultConfigs,
|
|
173
|
+
async setup(options, nuxt) {
|
|
174
|
+
const startTime = (/* @__PURE__ */ new Date()).getTime();
|
|
175
|
+
consola.log("::: Starting WPNuxt setup ::: ");
|
|
176
|
+
const publicWPNuxtConfig = {
|
|
177
|
+
wordpressUrl: process.env.WPNUXT_WORDPRESS_URL || options.wordpressUrl,
|
|
178
|
+
frontendUrl: process.env.WPNUXT_FRONTEND_URL || options.frontendUrl,
|
|
179
|
+
defaultMenuName: process.env.WPNUXT_DEFAULT_MENU_NAME || options.defaultMenuName,
|
|
180
|
+
blocks: process.env.WPNUXT_BLOCKS ? process.env.WPNUXT_BLOCKS === "true" : options.blocks,
|
|
181
|
+
replaceSchema: process.env.WPNUXT_REPLACE_SCHEMA === "true" || options.replaceSchema,
|
|
182
|
+
enableCache: process.env.WPNUXT_ENABLE_CACHE ? process.env.WPNUXT_ENABLE_CACHE === "true" : options.enableCache,
|
|
183
|
+
staging: process.env.WPNUXT_STAGING === "true" || options.staging,
|
|
184
|
+
downloadSchema: process.env.WPNUXT_DOWNLOAD_SCHEMA === "true" || options.downloadSchema,
|
|
185
|
+
// TODO also allow below options as env vars?
|
|
186
|
+
logLevel: process.env.WPNUXT_LOG_LEVEL ? Number.parseInt(process.env.WPNUXT_LOG_LEVEL) : options.logLevel,
|
|
187
|
+
generateComposables: options.generateComposables
|
|
188
|
+
};
|
|
189
|
+
nuxt.options.runtimeConfig.wpNuxt = defu(nuxt.options.runtimeConfig.wpNuxt, {
|
|
190
|
+
faustSecretKey: process.env.WPNUXT_FAUST_SECRET_KEY ? process.env.WPNUXT_FAUST_SECRET_KEY : options.faustSecretKey
|
|
191
|
+
});
|
|
192
|
+
nuxt.options.runtimeConfig.public.wpNuxt = publicWPNuxtConfig;
|
|
193
|
+
validateConfig(publicWPNuxtConfig);
|
|
194
|
+
const logger = initLogger(publicWPNuxtConfig.logLevel);
|
|
195
|
+
logger.info("Connecting GraphQL to", publicWPNuxtConfig.wordpressUrl);
|
|
196
|
+
logger.info("frontendUrl:", publicWPNuxtConfig.frontendUrl);
|
|
197
|
+
if (publicWPNuxtConfig.enableCache)
|
|
198
|
+
logger.info("Cache enabled");
|
|
199
|
+
logger.debug("Debug mode enabled, log level:", publicWPNuxtConfig.logLevel);
|
|
200
|
+
if (publicWPNuxtConfig.staging)
|
|
201
|
+
logger.info("Staging enabled");
|
|
202
|
+
if (publicWPNuxtConfig.blocks)
|
|
203
|
+
logger.info("Blocks enabled");
|
|
204
|
+
const { resolve } = createResolver(import.meta.url);
|
|
205
|
+
const resolveRuntimeModule = (path) => resolve("./runtime", path);
|
|
206
|
+
const srcResolver = createResolver(nuxt.options.srcDir);
|
|
207
|
+
nuxt.options.alias["#wpnuxt"] = resolve(nuxt.options.buildDir, "wpnuxt");
|
|
208
|
+
nuxt.options.alias["#wpnuxt/*"] = resolve(nuxt.options.buildDir, "wpnuxt", "*");
|
|
209
|
+
nuxt.options.alias["#wpnuxt/types"] = resolve("./types");
|
|
210
|
+
nuxt.options.nitro.alias = nuxt.options.nitro.alias || {};
|
|
211
|
+
nuxt.options.nitro.alias["#wpnuxt/types"] = resolve("./types");
|
|
212
|
+
nuxt.options.nitro.externals = nuxt.options.nitro.externals || {};
|
|
213
|
+
nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [];
|
|
214
|
+
addPlugin({
|
|
215
|
+
src: resolveRuntimeModule("plugins/vue-sanitize-directive")
|
|
216
|
+
});
|
|
217
|
+
addImports([
|
|
218
|
+
{ name: "isStaging", as: "isStaging", from: resolveRuntimeModule("./composables/isStaging") },
|
|
219
|
+
{ name: "useWPContent", as: "useWPContent", from: resolveRuntimeModule("./composables/useWPContent") },
|
|
220
|
+
{ name: "parseDoc", as: "parseDoc", from: resolveRuntimeModule("./composables/useParser") },
|
|
221
|
+
{ name: "usePrevNextPost", as: "usePrevNextPost", from: resolveRuntimeModule("./composables/usePrevNextPost") },
|
|
222
|
+
{ name: "loginUser", as: "loginUser", from: resolveRuntimeModule("./composables/user") },
|
|
223
|
+
{ name: "logoutUser", as: "logoutUser", from: resolveRuntimeModule("./composables/user") },
|
|
224
|
+
{ name: "getCurrentUserId", as: "getCurrentUserId", from: resolveRuntimeModule("./composables/user") },
|
|
225
|
+
{ name: "getCurrentUserName", as: "getCurrentUserName", from: resolveRuntimeModule("./composables/user") },
|
|
226
|
+
{ name: "useTokens", as: "useTokens", from: resolveRuntimeModule("./composables/useTokens") },
|
|
227
|
+
{ name: "useWPUri", as: "useWPUri", from: resolveRuntimeModule("./composables/useWPUri") },
|
|
228
|
+
{ name: "useFeaturedImage", as: "useFeaturedImage", from: resolveRuntimeModule("./composables/useFeaturedImage") }
|
|
229
|
+
]);
|
|
230
|
+
addComponent({ name: "StagingBanner", filePath: resolveRuntimeModule("./components/StagingBanner") });
|
|
231
|
+
addComponent({ name: "WPNuxtLogo", filePath: resolveRuntimeModule("./components/WPNuxtLogo") });
|
|
232
|
+
addComponent({ name: "WordPressLogo", filePath: resolveRuntimeModule("./components/WordPressLogo") });
|
|
233
|
+
addServerHandler({
|
|
234
|
+
route: "/api/wpContent",
|
|
235
|
+
handler: resolveRuntimeModule("./server/api/wpContent.post")
|
|
236
|
+
});
|
|
237
|
+
addServerHandler({
|
|
238
|
+
route: "/api/purgeCache",
|
|
239
|
+
handler: resolveRuntimeModule("./server/api/purgeCache.get")
|
|
240
|
+
});
|
|
241
|
+
await installModule("@vueuse/nuxt", {});
|
|
242
|
+
const queryOutputPath = resolve((nuxt.options.srcDir || nuxt.options.rootDir) + "/.queries/");
|
|
243
|
+
await promises.rm(queryOutputPath, { recursive: true, force: true });
|
|
244
|
+
const userQueryPath = "~/extend/queries/".replace(/^(~~|@@)/, nuxt.options.rootDir).replace(/^(~|@)/, nuxt.options.srcDir);
|
|
245
|
+
const userQueryPathExists = existsSync(userQueryPath);
|
|
246
|
+
cpSync(resolveRuntimeModule("./queries/"), queryOutputPath, { recursive: true });
|
|
247
|
+
if (hasNuxtModule("@wpnuxt/blocks")) {
|
|
248
|
+
for (const m of nuxt.options._installedModules) {
|
|
249
|
+
if (m.meta.name === "@wpnuxt/blocks" && m.entryPath) {
|
|
250
|
+
let blocksQueriesPath;
|
|
251
|
+
if (m.entryPath.startsWith("../src/module")) {
|
|
252
|
+
blocksQueriesPath = join(nuxt.options.rootDir, "../src/runtime/queries/");
|
|
253
|
+
} else {
|
|
254
|
+
blocksQueriesPath = join("./node_modules", m.entryPath, "dist/runtime/queries/");
|
|
255
|
+
}
|
|
256
|
+
cpSync(blocksQueriesPath, queryOutputPath, { recursive: true });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
logger.debug("!!! If you want to render Gutenberg blocks with separate vue components, please install the @wpnuxt/blocks module");
|
|
261
|
+
}
|
|
262
|
+
if (userQueryPathExists) {
|
|
263
|
+
logger.debug("Extending queries:", userQueryPath);
|
|
264
|
+
cpSync(resolve(userQueryPath), queryOutputPath, { recursive: true });
|
|
265
|
+
}
|
|
266
|
+
logger.debug("Copied merged queries in folder:", queryOutputPath);
|
|
267
|
+
await installModule("nuxt-graphql-middleware", {
|
|
268
|
+
debug: publicWPNuxtConfig.logLevel ? publicWPNuxtConfig.logLevel > 3 : false,
|
|
269
|
+
graphqlEndpoint: `${publicWPNuxtConfig.wordpressUrl}/graphql`,
|
|
270
|
+
downloadSchema: publicWPNuxtConfig.downloadSchema,
|
|
271
|
+
codegenConfig: {
|
|
272
|
+
silent: false,
|
|
273
|
+
skipTypename: true,
|
|
274
|
+
useTypeImports: true,
|
|
275
|
+
// inlineFragmentTypes: 'combine',
|
|
276
|
+
dedupeFragments: true,
|
|
277
|
+
onlyOperationTypes: true,
|
|
278
|
+
avoidOptionals: false,
|
|
279
|
+
disableOnBuild: false,
|
|
280
|
+
gqlImport: "graphql-request#wpnuxt",
|
|
281
|
+
namingConvention: {
|
|
282
|
+
enumValues: "change-case-all#upperCaseFirst"
|
|
283
|
+
},
|
|
284
|
+
documents: [
|
|
285
|
+
resolve("!./graphql/**/*")
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
codegenSchemaConfig: {
|
|
289
|
+
urlSchemaOptions: {
|
|
290
|
+
headers: {
|
|
291
|
+
Authorization: "server-token"
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
outputDocuments: true,
|
|
296
|
+
autoImportPatterns: queryOutputPath,
|
|
297
|
+
includeComposables: true,
|
|
298
|
+
devtools: true
|
|
299
|
+
});
|
|
300
|
+
const resolvedPath = resolveRuntimeModule("./app/graphqlMiddleware.serverOptions");
|
|
301
|
+
const template = addTemplate({
|
|
302
|
+
filename: "graphqlMiddleware.serverOptions.ts",
|
|
303
|
+
write: true,
|
|
304
|
+
getContents: () => `
|
|
305
|
+
import type { GraphqlMiddlewareServerOptions } from '#graphql-middleware/types'
|
|
306
|
+
import serverOptions from '${resolvedPath}'
|
|
307
|
+
import type { GraphqlServerResponse } from '#graphql-middleware/types'
|
|
308
|
+
import type { GraphqlMiddlewareResponseUnion } from '#build/nuxt-graphql-middleware'
|
|
309
|
+
|
|
310
|
+
type GraphqlResponseAdditions =
|
|
311
|
+
typeof serverOptions extends GraphqlMiddlewareServerOptions<infer R> ? R : {}
|
|
312
|
+
|
|
313
|
+
export type GraphqlResponse<T> = GraphqlServerResponse<T> & GraphqlResponseAdditions
|
|
314
|
+
|
|
315
|
+
export type GraphqlResponseTyped = GraphqlResponse<GraphqlMiddlewareResponseUnion>
|
|
316
|
+
|
|
317
|
+
export { serverOptions }
|
|
318
|
+
`
|
|
319
|
+
});
|
|
320
|
+
nuxt.options.nitro.externals.inline.push(template.dst);
|
|
321
|
+
nuxt.options.alias["#graphql-middleware-server-options-build"] = template.dst;
|
|
322
|
+
if (publicWPNuxtConfig.generateComposables && publicWPNuxtConfig.generateComposables.enabled) {
|
|
323
|
+
logger.trace("Generating composables");
|
|
324
|
+
const composablesConfig = typeof publicWPNuxtConfig.generateComposables === "object" ? publicWPNuxtConfig.generateComposables : defaultComposablesConfig;
|
|
325
|
+
const ctx = await {
|
|
326
|
+
fns: [],
|
|
327
|
+
fnImports: [],
|
|
328
|
+
composables: composablesConfig
|
|
329
|
+
};
|
|
330
|
+
await generateWPNuxtComposables(ctx, queryOutputPath, srcResolver);
|
|
331
|
+
addTemplate({
|
|
332
|
+
write: true,
|
|
333
|
+
filename: "wpnuxt.mjs",
|
|
334
|
+
getContents: () => ctx.generateImports?.() || ""
|
|
335
|
+
});
|
|
336
|
+
addTemplate({
|
|
337
|
+
write: true,
|
|
338
|
+
filename: "wpnuxt/index.d.ts",
|
|
339
|
+
getContents: () => ctx.generateDeclarations?.() || ""
|
|
340
|
+
});
|
|
341
|
+
nuxt.hook("imports:extend", (autoimports) => {
|
|
342
|
+
autoimports.push(...ctx.fnImports || []);
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
nuxt.hook("nitro:init", async (nitro) => {
|
|
346
|
+
const keys = await nitro.storage.getKeys("cache:content");
|
|
347
|
+
keys.forEach(async (key) => {
|
|
348
|
+
if (key.startsWith("cache:content"))
|
|
349
|
+
await nitro.storage.removeItem(key);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
const endTime = (/* @__PURE__ */ new Date()).getTime();
|
|
353
|
+
logger.success("::: Finished WPNuxt setup in " + (endTime - startTime) + "ms ::: ");
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
export { module as default };
|