druxt 0.24.0 → 0.24.1-dev.20260920063819
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 +132 -24
- package/banner.svg +1 -0
- package/dist/components/Druxt.vue +7 -5
- package/dist/components/DruxtDebug.vue +7 -2
- package/dist/components/DruxtModule.vue +98 -56
- package/dist/components/DruxtWrapper.vue +1 -1
- package/dist/druxt.esm.js +62 -28
- package/dist/druxt.ssr.js +62 -28
- package/dist/server-middleware/template.mjs +3 -3
- package/icon.svg +4 -0
- package/package.json +15 -10
package/README.md
CHANGED
|
@@ -1,36 +1,131 @@
|
|
|
1
|
-
|
|
1
|
+
<img src="./banner.svg" alt="Druxt: the core client, store and DruxtModule base">
|
|
2
|
+
|
|
3
|
+
# Druxt
|
|
2
4
|
|
|
3
5
|
[](https://www.npmjs.com/package/druxt)
|
|
4
|
-
[](https://github.com/druxt/druxt.js/actions/workflows/ci.yml)
|
|
5
7
|
[](https://snyk.io/test/github/druxt/druxt.js?targetFile=package.json)
|
|
6
8
|
[](https://codecov.io/gh/druxt/druxt.js)
|
|
7
9
|
|
|
10
|
+
> The core module, DruxtClient, DruxtStore and the DruxtModule base component.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
The core `druxt` package is the foundation every other Druxt module builds
|
|
13
|
+
on. It provides the three pieces the whole framework shares:
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
- **[DruxtClient](#druxtclient)**: the Drupal JSON:API communication layer.
|
|
16
|
+
- **[DruxtStore](#druxtstore)**: the Vuex module caching resources and
|
|
17
|
+
collections for all modules.
|
|
18
|
+
- **[DruxtModule](#druxtmodule)**: the base component behind the
|
|
19
|
+
theme-component suggestion system.
|
|
12
20
|
|
|
13
|
-
##
|
|
21
|
+
## Installation
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
1. Install the package:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npm i druxt
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
2. Add the module and your backend URL to `nuxt.config.js`:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
export default {
|
|
33
|
+
modules: [['druxt', { baseUrl: 'https://api.umami.demo.druxtjs.org' }]],
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
\* _Replace `https://api.umami.demo.druxtjs.org` with your own
|
|
38
|
+
Drupal backend._
|
|
39
|
+
|
|
40
|
+
3. On the Drupal side, install and enable the
|
|
41
|
+
[Druxt module](https://www.drupal.org/project/druxt) and grant the
|
|
42
|
+
**access druxt resources** permission to the relevant roles. Missing this
|
|
43
|
+
is the most common cause of site-wide JSON:API failures. See
|
|
44
|
+
[Troubleshooting](https://druxtjs.org/how-to/troubleshooting)
|
|
45
|
+
if requests are failing after install.
|
|
46
|
+
|
|
47
|
+
## Compatibility
|
|
48
|
+
|
|
49
|
+
As of September 2026. See the [releases](https://github.com/druxt/druxt.js/releases) for the current version.
|
|
50
|
+
|
|
51
|
+
| | Supported |
|
|
52
|
+
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
53
|
+
| Nuxt | 2.15 or later (Nuxt 2 line). Nuxt 3 is not supported. |
|
|
54
|
+
| Vue | 2.7 |
|
|
55
|
+
| Node | 16, the tested version. Node 16 is past upstream end of life. The 1.x line targets it deliberately. 17 and later need `NODE_OPTIONS=--openssl-legacy-provider` to build. |
|
|
56
|
+
| Drupal core | 10 or 11. `drupal/druxt` 1.2.2 declares `^10 \|\| ^11 \|\| ^12` and ended 8 and 9 support. 12 is declared but waits on Decoupled Router and JSON:API Menu Items. Tested against 10 and 11. |
|
|
57
|
+
| Drupal module | `drupal/druxt` ^1.2.2, which brings `decoupled_router`, `jsonapi_menu_items` and `jsonapi_views`. Earlier 1.2.x releases are incompatible with Decoupled Router 2.0.7 ([#3618675](https://www.drupal.org/i/3618675)). |
|
|
58
|
+
| Known pins | `@nuxtjs/storybook` 4.2.0 (later majors need Nuxt 3). Axios 0.x, or add it to `build.transpile` |
|
|
59
|
+
|
|
60
|
+
What these bounds promise over time is stated in the
|
|
61
|
+
[support and versioning policy](https://druxtjs.org/explanation/support-and-versioning).
|
|
62
|
+
|
|
63
|
+
Translated routes also need a `decoupled_router` patch; see the
|
|
64
|
+
[multilingual guide](https://druxtjs.org/how-to/multilingual).
|
|
65
|
+
|
|
66
|
+
## Settings
|
|
67
|
+
|
|
68
|
+
| Option | Type | Default | Description |
|
|
69
|
+
| ------------- | ----------------- | ------------ | ------------------------------------------------------------------------ |
|
|
70
|
+
| `baseUrl` | `string` | | The Drupal backend URL. **Required.** |
|
|
71
|
+
| `endpoint` | `string` | `'/jsonapi'` | The JSON:API endpoint path. |
|
|
72
|
+
| `proxy.api` | `boolean` | `false` | Proxy API requests via Nuxt ([guide](https://druxtjs.org/how-to/proxy)). |
|
|
73
|
+
| `proxy.files` | `boolean\|string` | `false` | Proxy Drupal files. A string sets the site. |
|
|
74
|
+
|
|
75
|
+
See the [Nuxt module API](https://druxtjs.org/api/packages/druxt/nuxt) for the full
|
|
76
|
+
options list.
|
|
77
|
+
|
|
78
|
+
## DruxtClient
|
|
21
79
|
|
|
22
|
-
|
|
80
|
+
The client is the communication layer between your application and Drupal's
|
|
81
|
+
JSON:API: resources, collections, indexing and authentication all flow
|
|
82
|
+
through it.
|
|
23
83
|
|
|
24
|
-
|
|
84
|
+
```js
|
|
85
|
+
import { DruxtClient } from 'druxt';
|
|
25
86
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- Slot and Wrapper theming system.
|
|
87
|
+
const client = new DruxtClient('https://api.umami.demo.druxtjs.org');
|
|
88
|
+
const collection = await client.getCollection('node--article');
|
|
89
|
+
```
|
|
30
90
|
|
|
31
|
-
|
|
91
|
+
- [Use the Druxt client directly](https://druxtjs.org/how-to/use-the-druxt-client): practical
|
|
92
|
+
guide, including non-Nuxt usage.
|
|
93
|
+
- [DruxtClient API](https://druxtjs.org/api/packages/druxt/client): full method reference.
|
|
32
94
|
|
|
33
|
-
|
|
95
|
+
## DruxtStore
|
|
96
|
+
|
|
97
|
+
The Vuex module that all Druxt modules share: request deduplication, the
|
|
98
|
+
resource/collection cache, and include handling.
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
const resource = await this.$store.dispatch('druxt/getResource', {
|
|
102
|
+
type: 'node--article',
|
|
103
|
+
id: 'd8dfd355-7f2f-4fc3-a149-288e4e293bdd',
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- [The DruxtStore concept page](https://druxtjs.org/explanation/druxt-store): how it works
|
|
108
|
+
and why it exists.
|
|
109
|
+
- [DruxtStore API](https://druxtjs.org/api/packages/druxt/stores/druxt): mutations and
|
|
110
|
+
actions.
|
|
111
|
+
- [Deprecations](https://druxtjs.org/modules/druxt/deprecations): retired signatures.
|
|
112
|
+
|
|
113
|
+
## DruxtModule
|
|
114
|
+
|
|
115
|
+
The base component for all Druxt components: it turns a `druxt()` options
|
|
116
|
+
object (component suggestions, props, slots) into themeable rendering.
|
|
117
|
+
Building on it is covered by the
|
|
118
|
+
[custom module tutorial](https://druxtjs.org/tutorials/first-custom-module), and the mechanism
|
|
119
|
+
by [Component resolution](https://druxtjs.org/explanation/component-resolution).
|
|
120
|
+
|
|
121
|
+
- [DruxtModule API](https://druxtjs.org/api/packages/druxt/components/DruxtModule).
|
|
122
|
+
|
|
123
|
+
## Where to go next
|
|
124
|
+
|
|
125
|
+
- New to Druxt? Start with the [Getting started tutorial](https://druxtjs.org/tutorials/getting-started).
|
|
126
|
+
- Ready for the full site experience? See the [Site module](https://druxtjs.org/modules/site).
|
|
127
|
+
|
|
128
|
+
---
|
|
34
129
|
|
|
35
130
|
## Modules
|
|
36
131
|
|
|
@@ -43,23 +138,36 @@ Learn more at https://druxtjs.org
|
|
|
43
138
|
- [druxt-site](https://druxtjs.org/modules/site) - Out-of-the-box decoupled Drupal Site
|
|
44
139
|
- [druxt-views](https://druxtjs.org/modules/views) - Decoupled Views
|
|
45
140
|
|
|
46
|
-
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Links
|
|
144
|
+
|
|
145
|
+
- Documentation: https://druxtjs.org
|
|
146
|
+
- Community Discord server: https://discord.druxtjs.org
|
|
147
|
+
- Demo - Umami Food Magazine:
|
|
148
|
+
- https://demo.druxtjs.org
|
|
149
|
+
- https://storybook.umami.demo.druxtjs.org
|
|
150
|
+
|
|
151
|
+
---
|
|
47
152
|
|
|
48
153
|
## Support
|
|
49
154
|
|
|
50
|
-
Druxt is an open
|
|
155
|
+
Druxt is an open-source project, built by the community for the community.
|
|
51
156
|
|
|
52
157
|
Find support or get involved in building Druxt via the community channels:
|
|
158
|
+
|
|
53
159
|
- [DruxtJS Discord server](https://discord.druxtjs.org)
|
|
54
160
|
- **#druxt** Slack channel on [Drupal.org slack](https://drupal.org/slack)
|
|
55
161
|
|
|
56
|
-
|
|
162
|
+
---
|
|
57
163
|
|
|
58
164
|
## Contributing
|
|
59
165
|
|
|
60
|
-
[](https://devpod.sh/open#https://github.com/druxt/druxt.js)
|
|
167
|
+
|
|
168
|
+
See the [Contributing guide](https://github.com/druxt/druxt.js/blob/develop/CONTRIBUTING.md).
|
|
61
169
|
|
|
62
|
-
|
|
170
|
+
---
|
|
63
171
|
|
|
64
172
|
## License
|
|
65
173
|
|
package/banner.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 320" width="1280" height="320" role="img" aria-label="druxt: The core client, store and DruxtModule base."><defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#1f2937"/><stop offset="0.7" stop-color="#2f495e"/><stop offset="1" stop-color="#36566e"/></linearGradient></defs><rect width="1280" height="320" rx="16" fill="url(#g)"/><rect x="250" y="85" width="150" height="150" rx="32" fill="rgba(229,236,241,0.07)"/><g transform="translate(277,112) scale(4)" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.5 19.25h-19L9.4 5.5l3.4 6.45" stroke="#7cc5f1"/><path d="M12.8 11.95l2.6-5.4 6.1 12.7" stroke="#68cb9f"/></g><text x="440" y="150" style="font-family:ui-sans-serif,system-ui,sans-serif" font-size="64" font-weight="700" letter-spacing="-1" fill="#eef2f6">Druxt</text><text x="651" y="150" style="font-family:ui-monospace,Menlo,Consolas,monospace" font-size="26" fill="#7cc5f1">druxt</text><text x="440" y="196" style="font-family:ui-sans-serif,system-ui,sans-serif" font-size="25" fill="rgba(229,236,241,0.75)">The core client, store and DruxtModule base.</text><g transform="translate(440,236) scale(0.0994)"><path d="M139 330l-1-2c-2-4-2-8-1-13H29L189 31l67 121 22-16-67-121c-1-2-9-14-22-14-6 0-15 2-22 15L5 303c-1 3-8 16-2 27 4 6 10 12 24 12h136c-14 0-21-6-24-12z" fill="#3498DB"/><path d="M447 304L317 70c-2-2-9-15-22-15-6 0-15 3-22 15l-17 28v54l39-67 129 230h-49a23 23 0 0 1-2 14l-1 1c-6 11-21 12-23 12h76c3 0 17-1 24-12 3-5 5-14-2-26z" fill="#108775"/><path d="M376 330v-1l1-2c1-4 2-8 1-12l-4-12-102-178-15-27h-1l-15 27-102 178-4 12a24 24 0 0 0 2 15c4 6 10 12 24 12h190c3 0 18-1 25-12zM256 152l93 163H163l93-163z" fill="#E5ECF1"/></g><text x="492" y="260" style="font-family:ui-sans-serif,system-ui,sans-serif" font-size="17" font-weight="600" fill="rgba(229,236,241,0.85)">druxtjs.org</text></svg>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Renders the specified Druxt module component, with support for wrapper and inner elements.
|
|
5
5
|
*
|
|
6
6
|
* @example @lang vue
|
|
7
7
|
* <Druxt
|
|
@@ -39,7 +39,7 @@ export default {
|
|
|
39
39
|
*
|
|
40
40
|
* @type {string}
|
|
41
41
|
*
|
|
42
|
-
* @example @lang vue <caption>Using the [DruxtJS Site module](https://
|
|
42
|
+
* @example @lang vue <caption>Using the [DruxtJS Site module](https://druxtjs.org/modules/site).</caption>
|
|
43
43
|
* <Druxt module="site" />
|
|
44
44
|
*/
|
|
45
45
|
module: {
|
|
@@ -52,7 +52,7 @@ export default {
|
|
|
52
52
|
*
|
|
53
53
|
* @type {object}
|
|
54
54
|
*
|
|
55
|
-
* @example @lang vue <caption>Using the [DruxtJS Entity module](https://
|
|
55
|
+
* @example @lang vue <caption>Using the [DruxtJS Entity module](https://druxtjs.org/modules/entity) to render a 'node--article' resource.</caption>
|
|
56
56
|
* <Druxt
|
|
57
57
|
* module="entity"
|
|
58
58
|
* :props-data="{
|
|
@@ -96,8 +96,10 @@ export default {
|
|
|
96
96
|
/**
|
|
97
97
|
* Vue.js Data object.
|
|
98
98
|
*
|
|
99
|
-
* @
|
|
100
|
-
* @
|
|
99
|
+
* @param {object} vm - The component ViewModel.
|
|
100
|
+
* @param {*} vm.value - The module component model value.
|
|
101
|
+
* @property {object} component - The module component and its propsData.
|
|
102
|
+
* @property {*} model - The module component model value.
|
|
101
103
|
*/
|
|
102
104
|
data: ({ value }) => ({
|
|
103
105
|
component: {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
* The DruxtDebug component can be used to render debug information that is
|
|
22
22
|
* visible only when Nuxt is run in development mode.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* Use the default slot to render your debug information, or the **json**
|
|
25
|
+
* prop to format your data. You can also combine the two.
|
|
26
26
|
*
|
|
27
27
|
* @example @lang vue
|
|
28
28
|
* <DruxtDebug :json="entity">Debug information</DruxtDebug>
|
|
@@ -60,6 +60,8 @@ export default {
|
|
|
60
60
|
/**
|
|
61
61
|
* The invoking Druxt module component.
|
|
62
62
|
*
|
|
63
|
+
* @param {object} vm - The component ViewModel.
|
|
64
|
+
* @param {object} vm.$parent - The parent component instance.
|
|
63
65
|
* @return {object}
|
|
64
66
|
*/
|
|
65
67
|
module: ({ $parent }) =>
|
|
@@ -70,6 +72,9 @@ export default {
|
|
|
70
72
|
/**
|
|
71
73
|
* The computed summary title.
|
|
72
74
|
*
|
|
75
|
+
* @param {object} vm - The component ViewModel.
|
|
76
|
+
* @param {object} vm.module - The invoking Druxt module component.
|
|
77
|
+
* @param {string} vm.summary - Text to use for debug summary.
|
|
73
78
|
* @return {string}
|
|
74
79
|
*/
|
|
75
80
|
title: ({ module, summary }) => module.$options._componentTag
|
|
@@ -6,28 +6,27 @@ import Vue from 'vue'
|
|
|
6
6
|
import DruxtWrapper from './DruxtWrapper.vue'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* The DruxtModule component
|
|
10
|
-
*
|
|
9
|
+
* The DruxtModule component renders a Druxt module; import and extend the
|
|
10
|
+
* component to build your own module.
|
|
11
11
|
*
|
|
12
12
|
* The component provides access to the Druxt Wrapper theming and fetch system
|
|
13
13
|
* via the druxt settings object.
|
|
14
14
|
*
|
|
15
|
+
* @see {@link https://druxtjs.org/explanation/component-resolution|Component resolution}
|
|
16
|
+
*
|
|
15
17
|
* @example @lang js
|
|
16
|
-
* import DruxtModule from 'druxt/
|
|
18
|
+
* import DruxtModule from 'druxt/components/DruxtModule.vue'
|
|
17
19
|
* export default {
|
|
18
|
-
* name: '
|
|
20
|
+
* name: 'DruxtCustomModule',
|
|
19
21
|
* extends: DruxtModule,
|
|
20
22
|
* druxt: {
|
|
21
23
|
* async fetchConfig() {},
|
|
22
24
|
* async fetchData(settings) {},
|
|
23
|
-
* componentOptions: (
|
|
24
|
-
* propsData: (
|
|
25
|
-
* foo: context.foo,
|
|
26
|
-
* bar: context.bar,
|
|
27
|
-
* }),
|
|
25
|
+
* componentOptions: () => ([['Default']]),
|
|
26
|
+
* propsData: ({ model }) => ({ value: model }),
|
|
28
27
|
* slots(h) {
|
|
29
28
|
* return {
|
|
30
|
-
* default: (attrs) => h('
|
|
29
|
+
* default: (attrs) => h('div', { attrs }, [this.model])
|
|
31
30
|
* }
|
|
32
31
|
* }
|
|
33
32
|
* }
|
|
@@ -41,7 +40,7 @@ export default {
|
|
|
41
40
|
/**
|
|
42
41
|
* The resource langcode.
|
|
43
42
|
*
|
|
44
|
-
* @example
|
|
43
|
+
* @example @lang vue
|
|
45
44
|
* <DruxtModule langcode="en" />
|
|
46
45
|
*
|
|
47
46
|
* @type {string}
|
|
@@ -52,13 +51,20 @@ export default {
|
|
|
52
51
|
},
|
|
53
52
|
|
|
54
53
|
/**
|
|
55
|
-
* The
|
|
54
|
+
* The Vue.js v-model binding for the module.
|
|
56
55
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
* Setting a value provides the module data directly, so the Drupal
|
|
57
|
+
* JSON:API fetch is skipped.
|
|
59
58
|
*
|
|
60
|
-
* @example
|
|
61
|
-
* <
|
|
59
|
+
* @example @lang vue
|
|
60
|
+
* <template>
|
|
61
|
+
* <DruxtModule v-model="model" />
|
|
62
|
+
* </template>
|
|
63
|
+
*
|
|
64
|
+
* <script>
|
|
65
|
+
* export default {
|
|
66
|
+
* data: () => ({ model: { foo: 'bar' } })
|
|
67
|
+
* }
|
|
62
68
|
*
|
|
63
69
|
* @type {*}
|
|
64
70
|
* @model
|
|
@@ -76,9 +82,9 @@ export default {
|
|
|
76
82
|
* @example
|
|
77
83
|
* <DruxtModule
|
|
78
84
|
* :wrapper="{
|
|
79
|
-
* component: '
|
|
80
|
-
* class: '
|
|
81
|
-
* propsData: {
|
|
85
|
+
* component: 'BCard',
|
|
86
|
+
* class: 'article-card',
|
|
87
|
+
* propsData: { noBody: true }
|
|
82
88
|
* }"
|
|
83
89
|
* />
|
|
84
90
|
*
|
|
@@ -91,8 +97,10 @@ export default {
|
|
|
91
97
|
},
|
|
92
98
|
|
|
93
99
|
/**
|
|
100
|
+
* @param {object} vm - The component ViewModel.
|
|
101
|
+
* @param {*} vm.value - The module component model value.
|
|
94
102
|
* @property {ComponentData} component - The wrapper component and propsData to be rendered.
|
|
95
|
-
* @property {
|
|
103
|
+
* @property {*} model - The module component model value.
|
|
96
104
|
*/
|
|
97
105
|
data: ({ value }) => ({
|
|
98
106
|
component: {
|
|
@@ -110,23 +118,20 @@ export default {
|
|
|
110
118
|
/**
|
|
111
119
|
* Loads the Druxt module data and applies a wrapper component as required.
|
|
112
120
|
*
|
|
113
|
-
*
|
|
121
|
+
* If your component has an existing `fetch` method, you must manually invoke
|
|
114
122
|
* the `DruxtModule.fetch()` hook.
|
|
115
123
|
*
|
|
116
124
|
* @example @lang js <caption>Manually invoking DruxtModule.fetch().</caption>
|
|
117
|
-
* import DruxtModule from 'druxt/
|
|
125
|
+
* import DruxtModule from 'druxt/components/DruxtModule.vue'
|
|
118
126
|
* export default {
|
|
119
|
-
* name: '
|
|
127
|
+
* name: 'DruxtCustomModule',
|
|
120
128
|
* extends: DruxtModule,
|
|
121
129
|
* async fetch() {
|
|
122
130
|
* await DruxtModule.fetch.call(this)
|
|
123
|
-
* }
|
|
131
|
+
* },
|
|
124
132
|
* druxt: {
|
|
125
|
-
* componentOptions: () => ([['
|
|
126
|
-
* propsData: (
|
|
127
|
-
* bar: ctx.bar,
|
|
128
|
-
* foo: ctx.foo,
|
|
129
|
-
* }),
|
|
133
|
+
* componentOptions: () => ([['Default']]),
|
|
134
|
+
* propsData: ({ model }) => ({ value: model }),
|
|
130
135
|
* }
|
|
131
136
|
* }
|
|
132
137
|
*/
|
|
@@ -151,7 +156,7 @@ export default {
|
|
|
151
156
|
if (
|
|
152
157
|
// No default template and wrapper isn't false OR
|
|
153
158
|
(!hasDefaultTemplate && this.wrapper !== false) ||
|
|
154
|
-
// Default
|
|
159
|
+
// Default template and wrapper is set
|
|
155
160
|
(hasDefaultTemplate && this.wrapper)
|
|
156
161
|
) {
|
|
157
162
|
options = this.getModuleComponents()
|
|
@@ -190,6 +195,17 @@ export default {
|
|
|
190
195
|
},
|
|
191
196
|
|
|
192
197
|
computed: {
|
|
198
|
+
/**
|
|
199
|
+
* The current language code is the `langcode` prop if set, otherwise the
|
|
200
|
+
* route's langcode metadata.
|
|
201
|
+
*
|
|
202
|
+
* Used by Druxt modules to fetch the correct resource translation.
|
|
203
|
+
*
|
|
204
|
+
* @param {object} vm - The component ViewModel.
|
|
205
|
+
* @param {string} vm.langcode - The `langcode` prop.
|
|
206
|
+
* @param {object} vm.$route - The current route.
|
|
207
|
+
* @return {string} The current language code.
|
|
208
|
+
*/
|
|
193
209
|
lang: ({ langcode, $route }) => langcode || ($route.meta || {}).langcode
|
|
194
210
|
},
|
|
195
211
|
|
|
@@ -222,6 +238,9 @@ export default {
|
|
|
222
238
|
methods: {
|
|
223
239
|
/**
|
|
224
240
|
* Sets the component to render a DruxtDebug error message.
|
|
241
|
+
*
|
|
242
|
+
* @param {object} err - The error object.
|
|
243
|
+
* @param {object} [context] - Error context; carries the wrapper component data where the failure knows it.
|
|
225
244
|
*/
|
|
226
245
|
error(err, context = {}) {
|
|
227
246
|
// Build error details.
|
|
@@ -279,8 +298,14 @@ export default {
|
|
|
279
298
|
// Convert parts into a pascalCase component name.
|
|
280
299
|
const name = pascalCase([this.$options.name, ...parts])
|
|
281
300
|
|
|
282
|
-
// Store set variant data to be used in next set item.
|
|
283
|
-
variants
|
|
301
|
+
// Store set variant data to be used in next set item. (Only
|
|
302
|
+
// `.parts` is read back from `variants` - no `global` key is
|
|
303
|
+
// needed here; it was previously a bare `global` object-shorthand
|
|
304
|
+
// property, which happened to reference Node's global object in
|
|
305
|
+
// SSR/webpack contexts and silently did nothing, but throws
|
|
306
|
+
// `ReferenceError: global is not defined` in an actual browser -
|
|
307
|
+
// e.g. Vite, which doesn't polyfill it.)
|
|
308
|
+
variants.unshift({ name, parts })
|
|
284
309
|
|
|
285
310
|
// Add langcode suffixed component option.
|
|
286
311
|
if (this.lang) {
|
|
@@ -315,10 +340,12 @@ export default {
|
|
|
315
340
|
*
|
|
316
341
|
* @example @lang js
|
|
317
342
|
* {
|
|
318
|
-
*
|
|
319
|
-
*
|
|
343
|
+
* $attrs: { entity: {}, fields: {}, langcode: 'en', schema: {} },
|
|
344
|
+
* props: { value: {} },
|
|
345
|
+
* propsData: { entity: {}, fields: {}, langcode: 'en', schema: {}, value: {} },
|
|
320
346
|
* }
|
|
321
347
|
*
|
|
348
|
+
* @param {object} wrapperProps - Props registered by the wrapper component.
|
|
322
349
|
* @return {object}
|
|
323
350
|
*/
|
|
324
351
|
getModulePropsData(wrapperProps = {}) {
|
|
@@ -406,7 +433,7 @@ export default {
|
|
|
406
433
|
/**
|
|
407
434
|
* Get wrapper component data.
|
|
408
435
|
*
|
|
409
|
-
* @param {string} component - The
|
|
436
|
+
* @param {string} component - The wrapper component name.
|
|
410
437
|
*
|
|
411
438
|
* @return {WrapperData}
|
|
412
439
|
*/
|
|
@@ -443,9 +470,9 @@ export default {
|
|
|
443
470
|
props: (this.wrapper || {}).propsData || undefined,
|
|
444
471
|
}
|
|
445
472
|
|
|
446
|
-
// Return only wrapper if fetch state is still pending and
|
|
447
|
-
//
|
|
448
|
-
if (this.$fetchState.pending && !this.component.options.length) {
|
|
473
|
+
// Return only wrapper if fetch state is still pending and no earlier fetch
|
|
474
|
+
// has resolved component options or slots.
|
|
475
|
+
if (this.$fetchState.pending && !(this.component.options || []).length && !(this.component.slots || []).length) {
|
|
449
476
|
return h((this.wrapper || {}).component || 'div', wrapperData)
|
|
450
477
|
}
|
|
451
478
|
|
|
@@ -477,6 +504,11 @@ export default {
|
|
|
477
504
|
}
|
|
478
505
|
|
|
479
506
|
/**
|
|
507
|
+
* The list of candidate Wrapper components, with naming parts and global
|
|
508
|
+
* registration state.
|
|
509
|
+
*
|
|
510
|
+
* @see {@link https://druxtjs.org/explanation/component-resolution|Component resolution}
|
|
511
|
+
*
|
|
480
512
|
* @typedef {object[]} Components
|
|
481
513
|
* @property {boolean} global - Component global registration state.
|
|
482
514
|
* @property {string} name - The component name.
|
|
@@ -485,48 +517,58 @@ export default {
|
|
|
485
517
|
* @example @lang js
|
|
486
518
|
* [{
|
|
487
519
|
* global: true,
|
|
488
|
-
*
|
|
489
|
-
* parts: ['
|
|
520
|
+
* name: 'DruxtEntityNodeArticleDefault',
|
|
521
|
+
* parts: ['NodeArticle', 'Default'],
|
|
490
522
|
* }]
|
|
491
523
|
*/
|
|
492
524
|
|
|
525
|
+
/* eslint-disable jsdoc/valid-types --
|
|
526
|
+
the property is Vue's `is`; the namepath parser rejects that word in any spelling */
|
|
493
527
|
/**
|
|
528
|
+
* The wrapper component and propsData to be rendered.
|
|
529
|
+
*
|
|
494
530
|
* @typedef {object} ComponentData
|
|
495
|
-
* @property {object} $attrs - propsData not registered by the
|
|
496
|
-
* @property {string} is=DruxtWrapper - The
|
|
497
|
-
* @property {string[]} options - The
|
|
498
|
-
* @property {object} props - propsData registered by the
|
|
531
|
+
* @property {object} $attrs - propsData not registered by the wrapper component.
|
|
532
|
+
* @property {string} is=DruxtWrapper - The wrapper component name.
|
|
533
|
+
* @property {string[]} options - The wrapper component options.
|
|
534
|
+
* @property {object} props - propsData registered by the wrapper component.
|
|
499
535
|
* @property {object} propsData - The component propsData object.
|
|
500
|
-
* @property {object} settings - Druxt settings object provided by the
|
|
536
|
+
* @property {object} settings - Druxt settings object provided by the wrapper component.
|
|
501
537
|
*
|
|
502
538
|
* @example @lang js
|
|
503
539
|
* {
|
|
504
|
-
* $attrs: {
|
|
505
|
-
* is: '
|
|
540
|
+
* $attrs: { entity: {}, fields: {}, schema: {} },
|
|
541
|
+
* is: 'DruxtEntityNodeArticleDefault',
|
|
506
542
|
* options: [
|
|
507
|
-
* '
|
|
543
|
+
* 'DruxtEntityNodeArticleDefault',
|
|
544
|
+
* 'DruxtEntityDefault',
|
|
508
545
|
* ],
|
|
509
|
-
* props: {
|
|
546
|
+
* props: { value: {} },
|
|
510
547
|
* propsData: {
|
|
511
|
-
*
|
|
512
|
-
*
|
|
548
|
+
* entity: {},
|
|
549
|
+
* fields: {},
|
|
550
|
+
* schema: {},
|
|
551
|
+
* value: {},
|
|
513
552
|
* },
|
|
514
|
-
* settings: {
|
|
553
|
+
* settings: { query: {} },
|
|
515
554
|
* }
|
|
516
555
|
*/
|
|
556
|
+
/* eslint-enable jsdoc/valid-types */
|
|
517
557
|
|
|
518
558
|
/**
|
|
559
|
+
* Druxt settings and registered props retrieved from the wrapper component.
|
|
560
|
+
*
|
|
519
561
|
* @typedef {object} WrapperData
|
|
520
562
|
* @property {object} druxt - Druxt settings object for use by Druxt module.
|
|
521
563
|
* @property {object} props - Registered props oject.
|
|
522
564
|
*
|
|
523
565
|
* @example @lang js
|
|
524
566
|
* {
|
|
525
|
-
* druxt: {
|
|
567
|
+
* druxt: { query: { fields: ['path', 'title'] } },
|
|
526
568
|
* props: {
|
|
527
|
-
*
|
|
528
|
-
* type:
|
|
529
|
-
* default:
|
|
569
|
+
* value: {
|
|
570
|
+
* type: Object,
|
|
571
|
+
* default: () => ({}),
|
|
530
572
|
* }
|
|
531
573
|
* }
|
|
532
574
|
* }
|
package/dist/druxt.esm.js
CHANGED
|
@@ -8,6 +8,7 @@ import merge from 'deepmerge';
|
|
|
8
8
|
import md5 from 'md5';
|
|
9
9
|
import Vue from 'vue';
|
|
10
10
|
|
|
11
|
+
const indexCache = new WeakMap();
|
|
11
12
|
class DruxtClient {
|
|
12
13
|
constructor(baseUrl, options = {}) {
|
|
13
14
|
this.log = consola.create({ defaults: {
|
|
@@ -40,7 +41,13 @@ class DruxtClient {
|
|
|
40
41
|
jsonapiResourceConfig: "jsonapi_resource_config--jsonapi_resource_config",
|
|
41
42
|
...options
|
|
42
43
|
};
|
|
43
|
-
this.
|
|
44
|
+
const indexKey = JSON.stringify([baseUrl, this.options.endpoint, this.options.jsonapiResourceConfig]);
|
|
45
|
+
this.indexKey = indexKey;
|
|
46
|
+
if (!indexCache.has(this.axios))
|
|
47
|
+
indexCache.set(this.axios, { index: {}, requests: {} });
|
|
48
|
+
const cache = indexCache.get(this.axios);
|
|
49
|
+
this.indexRequests = cache.requests;
|
|
50
|
+
this.index = cache.index[indexKey] || (cache.index[indexKey] = {});
|
|
44
51
|
}
|
|
45
52
|
addHeaders(headers) {
|
|
46
53
|
if (typeof headers === "undefined") {
|
|
@@ -161,12 +168,19 @@ class DruxtClient {
|
|
|
161
168
|
return collections;
|
|
162
169
|
}
|
|
163
170
|
async getIndex(resource, prefix) {
|
|
164
|
-
if ((this.index || {})[prefix]
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
171
|
+
if (!(this.index || {})[prefix]) {
|
|
172
|
+
const key = [this.indexKey, prefix || ""].join(":");
|
|
173
|
+
const request = this.indexRequests[key] || (this.indexRequests[key] = this.fetchIndex(prefix));
|
|
174
|
+
try {
|
|
175
|
+
await request;
|
|
176
|
+
} finally {
|
|
177
|
+
if (this.indexRequests[key] === request)
|
|
178
|
+
delete this.indexRequests[key];
|
|
179
|
+
}
|
|
169
180
|
}
|
|
181
|
+
return resource ? this.index[prefix][resource] || false : this.index[prefix];
|
|
182
|
+
}
|
|
183
|
+
async fetchIndex(prefix) {
|
|
170
184
|
const url = [prefix, this.options.endpoint].join("");
|
|
171
185
|
const { data } = await this.get(url);
|
|
172
186
|
let index = data.links;
|
|
@@ -187,13 +201,13 @@ class DruxtClient {
|
|
|
187
201
|
this.log.warn(err.message);
|
|
188
202
|
}
|
|
189
203
|
for (const resourceType in resources) {
|
|
190
|
-
const
|
|
191
|
-
const internal =
|
|
204
|
+
const resource = resources[resourceType];
|
|
205
|
+
const internal = resource.attributes.drupal_internal__id.split("--");
|
|
192
206
|
const item = {
|
|
193
|
-
resourceType:
|
|
207
|
+
resourceType: resource.attributes.resourceType,
|
|
194
208
|
entityType: internal[0],
|
|
195
209
|
bundle: internal[1],
|
|
196
|
-
resourceFields:
|
|
210
|
+
resourceFields: resource.attributes.resourceFields
|
|
197
211
|
};
|
|
198
212
|
const id = [item.entityType, item.bundle].join("--");
|
|
199
213
|
index[id] = {
|
|
@@ -203,7 +217,6 @@ class DruxtClient {
|
|
|
203
217
|
}
|
|
204
218
|
}
|
|
205
219
|
this.index[prefix] = index;
|
|
206
|
-
return resource ? this.index[prefix][resource] || false : this.index[prefix];
|
|
207
220
|
}
|
|
208
221
|
async getRelated(type, id, related, query, prefix = "") {
|
|
209
222
|
if (!id || !type || !related) {
|
|
@@ -250,7 +263,7 @@ class DruxtClient {
|
|
|
250
263
|
}
|
|
251
264
|
|
|
252
265
|
var name = "druxt";
|
|
253
|
-
var version = "0.24.
|
|
266
|
+
var version = "0.24.1-dev.20260920063819";
|
|
254
267
|
var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
|
|
255
268
|
var keywords = [
|
|
256
269
|
"cms",
|
|
@@ -273,12 +286,14 @@ var repository = {
|
|
|
273
286
|
url: "git+https://github.com/druxt/druxt.js"
|
|
274
287
|
};
|
|
275
288
|
var license = "MIT";
|
|
289
|
+
var author = "Stuart Clark <stuart@druxtjs.org>";
|
|
276
290
|
var exports = {
|
|
277
291
|
".": {
|
|
278
292
|
require: "./dist/druxt.ssr.js",
|
|
279
293
|
"import": "./dist/druxt.esm.js"
|
|
280
294
|
},
|
|
281
295
|
"./components/*": "./dist/components/*",
|
|
296
|
+
"./dist/components/*": "./dist/components/*",
|
|
282
297
|
"./plugins/*": "./dist/plugins/*",
|
|
283
298
|
"./server-middleware/*": "./dist/server-middleware/*",
|
|
284
299
|
"./dist/server-middleware/template.mjs": "./dist/server-middleware/template.mjs"
|
|
@@ -287,31 +302,34 @@ var main = "dist/druxt.ssr.js";
|
|
|
287
302
|
var module = "dist/druxt.esm.js";
|
|
288
303
|
var files = [
|
|
289
304
|
"dist",
|
|
290
|
-
"templates"
|
|
305
|
+
"templates",
|
|
306
|
+
"icon.svg",
|
|
307
|
+
"banner.svg"
|
|
291
308
|
];
|
|
292
309
|
var dependencies = {
|
|
293
310
|
"@nuxtjs/axios": "^5.13.6",
|
|
294
311
|
"@nuxtjs/proxy": "^2.1.0",
|
|
295
|
-
"@vue/devtools-api": "^6.
|
|
312
|
+
"@vue/devtools-api": "^6.6.4",
|
|
296
313
|
chalk: "^4.1.2",
|
|
297
314
|
deepmerge: "^4.3.1",
|
|
298
|
-
"drupal-jsonapi-params": "^2.2
|
|
299
|
-
"express-rate-limit": "^
|
|
300
|
-
"launch-editor": "^2.
|
|
315
|
+
"drupal-jsonapi-params": "^2.3.2",
|
|
316
|
+
"express-rate-limit": "^7.5.1",
|
|
317
|
+
"launch-editor": "^2.14.1",
|
|
301
318
|
md5: "^2.3.0",
|
|
302
319
|
querystring: "^0.2.1",
|
|
303
320
|
scule: "^0.3.2"
|
|
304
321
|
};
|
|
305
322
|
var devDependencies = {
|
|
306
|
-
"@storybook/addon-docs": "^6.5.16"
|
|
323
|
+
"@storybook/addon-docs": "^6.5.16",
|
|
324
|
+
"druxt-test-utils": "^0.2.15"
|
|
307
325
|
};
|
|
308
326
|
var peerDependencies = {
|
|
309
|
-
axios: "
|
|
327
|
+
axios: "0.28.0",
|
|
310
328
|
consola: "*"
|
|
311
329
|
};
|
|
312
330
|
var optionalDependencies = {
|
|
313
|
-
"core-js": "^3.
|
|
314
|
-
vue: "^2.7.
|
|
331
|
+
"core-js": "^3.50.0",
|
|
332
|
+
vue: "^2.7.16",
|
|
315
333
|
vuex: "^3.6.2"
|
|
316
334
|
};
|
|
317
335
|
var publishConfig = {
|
|
@@ -326,6 +344,7 @@ var meta = {
|
|
|
326
344
|
bugs: bugs,
|
|
327
345
|
repository: repository,
|
|
328
346
|
license: license,
|
|
347
|
+
author: author,
|
|
329
348
|
exports: exports,
|
|
330
349
|
main: main,
|
|
331
350
|
module: module,
|
|
@@ -337,6 +356,7 @@ var meta = {
|
|
|
337
356
|
publishConfig: publishConfig
|
|
338
357
|
};
|
|
339
358
|
|
|
359
|
+
const extendComponent = (component) => ({ ...component, isAsync: false });
|
|
340
360
|
const DruxtNuxtModule = async function(moduleOptions = {}) {
|
|
341
361
|
var _a;
|
|
342
362
|
const options = {
|
|
@@ -393,8 +413,13 @@ const DruxtNuxtModule = async function(moduleOptions = {}) {
|
|
|
393
413
|
};
|
|
394
414
|
this.addModule("@nuxtjs/axios");
|
|
395
415
|
}
|
|
416
|
+
this.options.build = this.options.build || {};
|
|
417
|
+
this.options.build.transpile = this.options.build.transpile || [];
|
|
418
|
+
if (!this.options.build.transpile.includes("axios")) {
|
|
419
|
+
this.options.build.transpile.push("axios");
|
|
420
|
+
}
|
|
396
421
|
this.nuxt.hook("components:dirs", (dirs) => {
|
|
397
|
-
dirs.push({ path: join(__dirname, "components") });
|
|
422
|
+
dirs.push({ path: join(__dirname, "components"), extendComponent });
|
|
398
423
|
});
|
|
399
424
|
this.addPlugin({
|
|
400
425
|
src: resolve(__dirname, "../templates/plugin.js"),
|
|
@@ -493,14 +518,16 @@ const DruxtStore = ({ store }) => {
|
|
|
493
518
|
collection.data = dehydrateResources({ commit: this.commit, prefix, queryObject, resources: collection.data });
|
|
494
519
|
if (collection.included) {
|
|
495
520
|
collection.included = dehydrateResources({ commit: this.commit, prefix, queryObject, resources: collection.included });
|
|
496
|
-
delete collection.included;
|
|
497
521
|
}
|
|
522
|
+
const hadIncluded = !!collection.included;
|
|
498
523
|
collection = merge(state.collections[type][hash][prefix] || {}, collection, { arrayMerge: (dst, src) => src });
|
|
524
|
+
if (!hadIncluded)
|
|
525
|
+
delete collection.included;
|
|
499
526
|
Vue.set(state.collections[type][hash], prefix, collection);
|
|
500
527
|
},
|
|
501
528
|
addResource(state, { prefix, resource, hash }) {
|
|
502
529
|
if (hash) {
|
|
503
|
-
console.warn("[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/
|
|
530
|
+
console.warn("[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/modules/druxt/deprecations#druxtstore-addresource-hash");
|
|
504
531
|
}
|
|
505
532
|
const { id, type } = (resource || {}).data || {};
|
|
506
533
|
if (!id || !type) {
|
|
@@ -548,10 +575,17 @@ const DruxtStore = ({ store }) => {
|
|
|
548
575
|
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
|
|
549
576
|
const hash = query ? md5(JSON.stringify({ ...queryObject, fields: {}, include: [] })) : "_default";
|
|
550
577
|
if (!bypassCache && ((state.collections[type] || {})[hash] || {})[prefix]) {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
578
|
+
const cached = state.collections[type][hash][prefix];
|
|
579
|
+
const hydrate = (o) => (((state.resources[o.type] || {})[o.id] || {})[prefix] || {}).data;
|
|
580
|
+
const data = cached.data.map(hydrate);
|
|
581
|
+
const included = cached.included ? cached.included.map(hydrate) : void 0;
|
|
582
|
+
if (data.every((o) => o) && (included || []).every((o) => o)) {
|
|
583
|
+
return {
|
|
584
|
+
...cached,
|
|
585
|
+
data,
|
|
586
|
+
...included ? { included } : {}
|
|
587
|
+
};
|
|
588
|
+
}
|
|
555
589
|
}
|
|
556
590
|
const collection = await this.$druxt.getCollection(type, query, prefix);
|
|
557
591
|
commit("addCollection", { collection: { ...collection }, type, hash, prefix });
|
package/dist/druxt.ssr.js
CHANGED
|
@@ -21,6 +21,7 @@ const merge__default = /*#__PURE__*/_interopDefaultLegacy(merge);
|
|
|
21
21
|
const md5__default = /*#__PURE__*/_interopDefaultLegacy(md5);
|
|
22
22
|
const Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue);
|
|
23
23
|
|
|
24
|
+
const indexCache = new WeakMap();
|
|
24
25
|
class DruxtClient {
|
|
25
26
|
constructor(baseUrl, options = {}) {
|
|
26
27
|
this.log = consola__default["default"].create({ defaults: {
|
|
@@ -53,7 +54,13 @@ class DruxtClient {
|
|
|
53
54
|
jsonapiResourceConfig: "jsonapi_resource_config--jsonapi_resource_config",
|
|
54
55
|
...options
|
|
55
56
|
};
|
|
56
|
-
this.
|
|
57
|
+
const indexKey = JSON.stringify([baseUrl, this.options.endpoint, this.options.jsonapiResourceConfig]);
|
|
58
|
+
this.indexKey = indexKey;
|
|
59
|
+
if (!indexCache.has(this.axios))
|
|
60
|
+
indexCache.set(this.axios, { index: {}, requests: {} });
|
|
61
|
+
const cache = indexCache.get(this.axios);
|
|
62
|
+
this.indexRequests = cache.requests;
|
|
63
|
+
this.index = cache.index[indexKey] || (cache.index[indexKey] = {});
|
|
57
64
|
}
|
|
58
65
|
addHeaders(headers) {
|
|
59
66
|
if (typeof headers === "undefined") {
|
|
@@ -174,12 +181,19 @@ class DruxtClient {
|
|
|
174
181
|
return collections;
|
|
175
182
|
}
|
|
176
183
|
async getIndex(resource, prefix) {
|
|
177
|
-
if ((this.index || {})[prefix]
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
184
|
+
if (!(this.index || {})[prefix]) {
|
|
185
|
+
const key = [this.indexKey, prefix || ""].join(":");
|
|
186
|
+
const request = this.indexRequests[key] || (this.indexRequests[key] = this.fetchIndex(prefix));
|
|
187
|
+
try {
|
|
188
|
+
await request;
|
|
189
|
+
} finally {
|
|
190
|
+
if (this.indexRequests[key] === request)
|
|
191
|
+
delete this.indexRequests[key];
|
|
192
|
+
}
|
|
182
193
|
}
|
|
194
|
+
return resource ? this.index[prefix][resource] || false : this.index[prefix];
|
|
195
|
+
}
|
|
196
|
+
async fetchIndex(prefix) {
|
|
183
197
|
const url = [prefix, this.options.endpoint].join("");
|
|
184
198
|
const { data } = await this.get(url);
|
|
185
199
|
let index = data.links;
|
|
@@ -200,13 +214,13 @@ class DruxtClient {
|
|
|
200
214
|
this.log.warn(err.message);
|
|
201
215
|
}
|
|
202
216
|
for (const resourceType in resources) {
|
|
203
|
-
const
|
|
204
|
-
const internal =
|
|
217
|
+
const resource = resources[resourceType];
|
|
218
|
+
const internal = resource.attributes.drupal_internal__id.split("--");
|
|
205
219
|
const item = {
|
|
206
|
-
resourceType:
|
|
220
|
+
resourceType: resource.attributes.resourceType,
|
|
207
221
|
entityType: internal[0],
|
|
208
222
|
bundle: internal[1],
|
|
209
|
-
resourceFields:
|
|
223
|
+
resourceFields: resource.attributes.resourceFields
|
|
210
224
|
};
|
|
211
225
|
const id = [item.entityType, item.bundle].join("--");
|
|
212
226
|
index[id] = {
|
|
@@ -216,7 +230,6 @@ class DruxtClient {
|
|
|
216
230
|
}
|
|
217
231
|
}
|
|
218
232
|
this.index[prefix] = index;
|
|
219
|
-
return resource ? this.index[prefix][resource] || false : this.index[prefix];
|
|
220
233
|
}
|
|
221
234
|
async getRelated(type, id, related, query, prefix = "") {
|
|
222
235
|
if (!id || !type || !related) {
|
|
@@ -263,7 +276,7 @@ class DruxtClient {
|
|
|
263
276
|
}
|
|
264
277
|
|
|
265
278
|
var name = "druxt";
|
|
266
|
-
var version = "0.24.
|
|
279
|
+
var version = "0.24.1-dev.20260920063819";
|
|
267
280
|
var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
|
|
268
281
|
var keywords = [
|
|
269
282
|
"cms",
|
|
@@ -286,12 +299,14 @@ var repository = {
|
|
|
286
299
|
url: "git+https://github.com/druxt/druxt.js"
|
|
287
300
|
};
|
|
288
301
|
var license = "MIT";
|
|
302
|
+
var author = "Stuart Clark <stuart@druxtjs.org>";
|
|
289
303
|
var exports$1 = {
|
|
290
304
|
".": {
|
|
291
305
|
require: "./dist/druxt.ssr.js",
|
|
292
306
|
"import": "./dist/druxt.esm.js"
|
|
293
307
|
},
|
|
294
308
|
"./components/*": "./dist/components/*",
|
|
309
|
+
"./dist/components/*": "./dist/components/*",
|
|
295
310
|
"./plugins/*": "./dist/plugins/*",
|
|
296
311
|
"./server-middleware/*": "./dist/server-middleware/*",
|
|
297
312
|
"./dist/server-middleware/template.mjs": "./dist/server-middleware/template.mjs"
|
|
@@ -300,31 +315,34 @@ var main = "dist/druxt.ssr.js";
|
|
|
300
315
|
var module$1 = "dist/druxt.esm.js";
|
|
301
316
|
var files = [
|
|
302
317
|
"dist",
|
|
303
|
-
"templates"
|
|
318
|
+
"templates",
|
|
319
|
+
"icon.svg",
|
|
320
|
+
"banner.svg"
|
|
304
321
|
];
|
|
305
322
|
var dependencies = {
|
|
306
323
|
"@nuxtjs/axios": "^5.13.6",
|
|
307
324
|
"@nuxtjs/proxy": "^2.1.0",
|
|
308
|
-
"@vue/devtools-api": "^6.
|
|
325
|
+
"@vue/devtools-api": "^6.6.4",
|
|
309
326
|
chalk: "^4.1.2",
|
|
310
327
|
deepmerge: "^4.3.1",
|
|
311
|
-
"drupal-jsonapi-params": "^2.2
|
|
312
|
-
"express-rate-limit": "^
|
|
313
|
-
"launch-editor": "^2.
|
|
328
|
+
"drupal-jsonapi-params": "^2.3.2",
|
|
329
|
+
"express-rate-limit": "^7.5.1",
|
|
330
|
+
"launch-editor": "^2.14.1",
|
|
314
331
|
md5: "^2.3.0",
|
|
315
332
|
querystring: "^0.2.1",
|
|
316
333
|
scule: "^0.3.2"
|
|
317
334
|
};
|
|
318
335
|
var devDependencies = {
|
|
319
|
-
"@storybook/addon-docs": "^6.5.16"
|
|
336
|
+
"@storybook/addon-docs": "^6.5.16",
|
|
337
|
+
"druxt-test-utils": "^0.2.15"
|
|
320
338
|
};
|
|
321
339
|
var peerDependencies = {
|
|
322
|
-
axios: "
|
|
340
|
+
axios: "0.28.0",
|
|
323
341
|
consola: "*"
|
|
324
342
|
};
|
|
325
343
|
var optionalDependencies = {
|
|
326
|
-
"core-js": "^3.
|
|
327
|
-
vue: "^2.7.
|
|
344
|
+
"core-js": "^3.50.0",
|
|
345
|
+
vue: "^2.7.16",
|
|
328
346
|
vuex: "^3.6.2"
|
|
329
347
|
};
|
|
330
348
|
var publishConfig = {
|
|
@@ -339,6 +357,7 @@ const meta = {
|
|
|
339
357
|
bugs: bugs,
|
|
340
358
|
repository: repository,
|
|
341
359
|
license: license,
|
|
360
|
+
author: author,
|
|
342
361
|
exports: exports$1,
|
|
343
362
|
main: main,
|
|
344
363
|
module: module$1,
|
|
@@ -350,6 +369,7 @@ const meta = {
|
|
|
350
369
|
publishConfig: publishConfig
|
|
351
370
|
};
|
|
352
371
|
|
|
372
|
+
const extendComponent = (component) => ({ ...component, isAsync: false });
|
|
353
373
|
const DruxtNuxtModule = async function(moduleOptions = {}) {
|
|
354
374
|
var _a;
|
|
355
375
|
const options = {
|
|
@@ -406,8 +426,13 @@ const DruxtNuxtModule = async function(moduleOptions = {}) {
|
|
|
406
426
|
};
|
|
407
427
|
this.addModule("@nuxtjs/axios");
|
|
408
428
|
}
|
|
429
|
+
this.options.build = this.options.build || {};
|
|
430
|
+
this.options.build.transpile = this.options.build.transpile || [];
|
|
431
|
+
if (!this.options.build.transpile.includes("axios")) {
|
|
432
|
+
this.options.build.transpile.push("axios");
|
|
433
|
+
}
|
|
409
434
|
this.nuxt.hook("components:dirs", (dirs) => {
|
|
410
|
-
dirs.push({ path: path.join(__dirname, "components") });
|
|
435
|
+
dirs.push({ path: path.join(__dirname, "components"), extendComponent });
|
|
411
436
|
});
|
|
412
437
|
this.addPlugin({
|
|
413
438
|
src: path.resolve(__dirname, "../templates/plugin.js"),
|
|
@@ -506,14 +531,16 @@ const DruxtStore = ({ store }) => {
|
|
|
506
531
|
collection.data = dehydrateResources({ commit: this.commit, prefix, queryObject, resources: collection.data });
|
|
507
532
|
if (collection.included) {
|
|
508
533
|
collection.included = dehydrateResources({ commit: this.commit, prefix, queryObject, resources: collection.included });
|
|
509
|
-
delete collection.included;
|
|
510
534
|
}
|
|
535
|
+
const hadIncluded = !!collection.included;
|
|
511
536
|
collection = merge__default["default"](state.collections[type][hash][prefix] || {}, collection, { arrayMerge: (dst, src) => src });
|
|
537
|
+
if (!hadIncluded)
|
|
538
|
+
delete collection.included;
|
|
512
539
|
Vue__default["default"].set(state.collections[type][hash], prefix, collection);
|
|
513
540
|
},
|
|
514
541
|
addResource(state, { prefix, resource, hash }) {
|
|
515
542
|
if (hash) {
|
|
516
|
-
console.warn("[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/
|
|
543
|
+
console.warn("[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/modules/druxt/deprecations#druxtstore-addresource-hash");
|
|
517
544
|
}
|
|
518
545
|
const { id, type } = (resource || {}).data || {};
|
|
519
546
|
if (!id || !type) {
|
|
@@ -561,10 +588,17 @@ const DruxtStore = ({ store }) => {
|
|
|
561
588
|
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
|
|
562
589
|
const hash = query ? md5__default["default"](JSON.stringify({ ...queryObject, fields: {}, include: [] })) : "_default";
|
|
563
590
|
if (!bypassCache && ((state.collections[type] || {})[hash] || {})[prefix]) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
591
|
+
const cached = state.collections[type][hash][prefix];
|
|
592
|
+
const hydrate = (o) => (((state.resources[o.type] || {})[o.id] || {})[prefix] || {}).data;
|
|
593
|
+
const data = cached.data.map(hydrate);
|
|
594
|
+
const included = cached.included ? cached.included.map(hydrate) : void 0;
|
|
595
|
+
if (data.every((o) => o) && (included || []).every((o) => o)) {
|
|
596
|
+
return {
|
|
597
|
+
...cached,
|
|
598
|
+
data,
|
|
599
|
+
...included ? { included } : {}
|
|
600
|
+
};
|
|
601
|
+
}
|
|
568
602
|
}
|
|
569
603
|
const collection = await this.$druxt.getCollection(type, query, prefix);
|
|
570
604
|
commit("addCollection", { collection: { ...collection }, type, hash, prefix });
|
|
@@ -63,11 +63,11 @@ app.post("/add", async (req, res) => {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
const
|
|
66
|
+
const formatRecursive = (item, depth = 2) => {
|
|
67
67
|
for (const [key, value] of Object.entries(item)) {
|
|
68
68
|
if (typeof value === "object") {
|
|
69
69
|
exports.push(`${" ".repeat(depth * 2)}${key}: {`);
|
|
70
|
-
|
|
70
|
+
formatRecursive(value, depth + 1);
|
|
71
71
|
exports.push(`${" ".repeat(depth * 2)}},`);
|
|
72
72
|
} else if (typeof value === "string") {
|
|
73
73
|
exports.push(`${" ".repeat(depth * 2)}${value},`);
|
|
@@ -75,7 +75,7 @@ app.post("/add", async (req, res) => {
|
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
exports.push("\r\n druxt: {");
|
|
78
|
-
|
|
78
|
+
formatRecursive(druxt);
|
|
79
79
|
exports.push(" },");
|
|
80
80
|
}
|
|
81
81
|
const template = `<!-- Generated by the Druxt devel template server middleware. -->
|
package/icon.svg
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "druxt",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.1-dev.20260920063819",
|
|
4
4
|
"description": "The Fully Decoupled Drupal Framework for Nuxt.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
@@ -23,12 +23,14 @@
|
|
|
23
23
|
"url": "git+https://github.com/druxt/druxt.js"
|
|
24
24
|
},
|
|
25
25
|
"license": "MIT",
|
|
26
|
+
"author": "Stuart Clark <stuart@druxtjs.org>",
|
|
26
27
|
"exports": {
|
|
27
28
|
".": {
|
|
28
29
|
"require": "./dist/druxt.ssr.js",
|
|
29
30
|
"import": "./dist/druxt.esm.js"
|
|
30
31
|
},
|
|
31
32
|
"./components/*": "./dist/components/*",
|
|
33
|
+
"./dist/components/*": "./dist/components/*",
|
|
32
34
|
"./plugins/*": "./dist/plugins/*",
|
|
33
35
|
"./server-middleware/*": "./dist/server-middleware/*",
|
|
34
36
|
"./dist/server-middleware/template.mjs": "./dist/server-middleware/template.mjs"
|
|
@@ -37,31 +39,34 @@
|
|
|
37
39
|
"module": "dist/druxt.esm.js",
|
|
38
40
|
"files": [
|
|
39
41
|
"dist",
|
|
40
|
-
"templates"
|
|
42
|
+
"templates",
|
|
43
|
+
"icon.svg",
|
|
44
|
+
"banner.svg"
|
|
41
45
|
],
|
|
42
46
|
"dependencies": {
|
|
43
47
|
"@nuxtjs/axios": "^5.13.6",
|
|
44
48
|
"@nuxtjs/proxy": "^2.1.0",
|
|
45
|
-
"@vue/devtools-api": "^6.
|
|
49
|
+
"@vue/devtools-api": "^6.6.4",
|
|
46
50
|
"chalk": "^4.1.2",
|
|
47
51
|
"deepmerge": "^4.3.1",
|
|
48
|
-
"drupal-jsonapi-params": "^2.2
|
|
49
|
-
"express-rate-limit": "^
|
|
50
|
-
"launch-editor": "^2.
|
|
52
|
+
"drupal-jsonapi-params": "^2.3.2",
|
|
53
|
+
"express-rate-limit": "^7.5.1",
|
|
54
|
+
"launch-editor": "^2.14.1",
|
|
51
55
|
"md5": "^2.3.0",
|
|
52
56
|
"querystring": "^0.2.1",
|
|
53
57
|
"scule": "^0.3.2"
|
|
54
58
|
},
|
|
55
59
|
"devDependencies": {
|
|
56
|
-
"@storybook/addon-docs": "^6.5.16"
|
|
60
|
+
"@storybook/addon-docs": "^6.5.16",
|
|
61
|
+
"druxt-test-utils": "^0.2.15"
|
|
57
62
|
},
|
|
58
63
|
"peerDependencies": {
|
|
59
|
-
"axios": "
|
|
64
|
+
"axios": "0.28.0",
|
|
60
65
|
"consola": "*"
|
|
61
66
|
},
|
|
62
67
|
"optionalDependencies": {
|
|
63
|
-
"core-js": "^3.
|
|
64
|
-
"vue": "^2.7.
|
|
68
|
+
"core-js": "^3.50.0",
|
|
69
|
+
"vue": "^2.7.16",
|
|
65
70
|
"vuex": "^3.6.2"
|
|
66
71
|
},
|
|
67
72
|
"publishConfig": {
|