druxt-router 0.21.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/dist/components/DruxtRouter.stories.mjs +16 -0
- package/dist/components/DruxtRouter.vue +195 -19
- package/dist/druxt-router.esm.js +13 -9
- package/dist/druxt-router.ssr.js +13 -9
- package/nuxt/index.js +3 -0
- package/package.json +2 -2
- package/templates/plugin.js +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
# druxt-router
|
|
2
2
|
|
|
3
|
+
## 0.24.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [45bc0b9]
|
|
8
|
+
- druxt@0.14.0
|
|
9
|
+
|
|
10
|
+
## 0.24.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- 9161b38: Added Storybook integration for the DruxtRouter component.
|
|
15
|
+
- 9161b38: Added ability to render a specific route using the Path property.
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
<DruxtRouter path="/node/1" />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- 9161b38: Added fetch hook to DruxtRouter component.
|
|
22
|
+
- 9161b38: Added option to disable the DruxtRouter page middleware.
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
export default {
|
|
26
|
+
druxt: {
|
|
27
|
+
router: {
|
|
28
|
+
middleware: false
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Note: This is experimental and your results may vary.
|
|
35
|
+
|
|
36
|
+
## 0.23.0
|
|
37
|
+
|
|
38
|
+
### Minor Changes
|
|
39
|
+
|
|
40
|
+
- 77ab204: Added support for API Proxy
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- Updated dependencies [77ab204]
|
|
45
|
+
- druxt@0.13.0
|
|
46
|
+
|
|
47
|
+
## 0.22.0
|
|
48
|
+
|
|
49
|
+
### Minor Changes
|
|
50
|
+
|
|
51
|
+
- c7b267a: Throw Error on router errors
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- Updated dependencies [4504a2f]
|
|
56
|
+
- druxt@0.12.0
|
|
57
|
+
|
|
3
58
|
## 0.21.0
|
|
4
59
|
|
|
5
60
|
### Minor Changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import DruxtRouter from './DruxtRouter.vue'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'Druxt/Router/DruxtRouter',
|
|
5
|
+
component: DruxtRouter
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const Template = (args, { argTypes }) => ({
|
|
9
|
+
components: { DruxtRouter },
|
|
10
|
+
props: Object.keys(argTypes),
|
|
11
|
+
template: `<DruxtRouter v-bind="$props" />`
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export const Default = Template.bind({})
|
|
15
|
+
Default.storyName = 'DruxtRouter'
|
|
16
|
+
Default.args = { path: '/' }
|
|
@@ -1,21 +1,61 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
|
|
3
3
|
import DruxtModule from 'druxt/dist/components/DruxtModule.vue'
|
|
4
|
-
import { mapState } from 'vuex'
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* The DruxtRouter component renders a Drupal decoupled route, or path, using
|
|
7
|
+
* the appropriate Druxt component.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
9
|
+
* `<DruxtRouter path="/" />`
|
|
10
|
+
*
|
|
11
|
+
* If no Path is specified, the Vue router path will be used by default.
|
|
12
|
+
*
|
|
13
|
+
* For instance, using the `/node/1` route would result in a DruxtRouter
|
|
14
|
+
* component for the content in Drupal with the Node ID of 1.
|
|
15
|
+
*
|
|
16
|
+
* @example <caption>Render using the Vue router path</caption> @lang vue
|
|
11
17
|
* <DruxtRouter />
|
|
18
|
+
*
|
|
19
|
+
* @example <caption>Render a specified path</caption> @lang vue
|
|
20
|
+
* <DruxtRouter path="/node/1" />
|
|
21
|
+
*
|
|
22
|
+
* @example <caption>Render the result of the model, bypasses Drupal backend</caption> @lang vue
|
|
23
|
+
* <DruxtRouter v-model="route" />
|
|
24
|
+
*
|
|
25
|
+
* @example <caption>Render via a template</caption> @lang vue
|
|
26
|
+
* <DruxtRouter>
|
|
27
|
+
* <template #default="{ route }">
|
|
28
|
+
* <DruxtRouter v-bind="route.props" />
|
|
29
|
+
* </template>
|
|
30
|
+
* </DruxtRouter>
|
|
12
31
|
*/
|
|
13
32
|
export default {
|
|
14
33
|
name: 'DruxtRouter',
|
|
15
34
|
|
|
16
35
|
extends: DruxtModule,
|
|
17
36
|
|
|
18
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Nuxt middleware; gets and sets the current route, and processes redirects.
|
|
39
|
+
*
|
|
40
|
+
* This can be disabled by setting the `druxt.router.middleware` option to
|
|
41
|
+
* `false` in `nuxt.config.js`
|
|
42
|
+
*
|
|
43
|
+
* @example @lang js
|
|
44
|
+
* export default {
|
|
45
|
+
* druxt: {
|
|
46
|
+
* router: {
|
|
47
|
+
* middleware: false
|
|
48
|
+
* }
|
|
49
|
+
* }
|
|
50
|
+
* }
|
|
51
|
+
*/
|
|
52
|
+
async middleware ({ $druxt, redirect, route, store }) {
|
|
53
|
+
// Ensure Router middleware is enabled.
|
|
54
|
+
if (typeof ($druxt.settings.router || {}).middleware !== 'undefined' && !$druxt.settings.router.middleware) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Get and set the current route and redirect information.
|
|
19
59
|
const result = await store.dispatch('druxtRouter/get', route.fullPath)
|
|
20
60
|
|
|
21
61
|
// Process redirect.
|
|
@@ -24,6 +64,44 @@ export default {
|
|
|
24
64
|
}
|
|
25
65
|
},
|
|
26
66
|
|
|
67
|
+
/** */
|
|
68
|
+
props: {
|
|
69
|
+
/**
|
|
70
|
+
* The Decoupled router path.
|
|
71
|
+
*
|
|
72
|
+
* If not set, the Vue router value will be used instead.
|
|
73
|
+
*
|
|
74
|
+
* @type {string}
|
|
75
|
+
*
|
|
76
|
+
* @example @lang vue
|
|
77
|
+
* <DruxtRouter path="/node/1" />
|
|
78
|
+
*/
|
|
79
|
+
path: {
|
|
80
|
+
type: String,
|
|
81
|
+
default: undefined,
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The Router object, used to determine the resolved route component.
|
|
86
|
+
*
|
|
87
|
+
* Setting this value will bypass the JSON:API.
|
|
88
|
+
*
|
|
89
|
+
* @type {object}
|
|
90
|
+
* @model
|
|
91
|
+
*/
|
|
92
|
+
value: {
|
|
93
|
+
type: Object,
|
|
94
|
+
default: () => undefined
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @property {object} model - The model object.
|
|
100
|
+
*/
|
|
101
|
+
data: ({ value }) => ({
|
|
102
|
+
model: value,
|
|
103
|
+
}),
|
|
104
|
+
|
|
27
105
|
/**
|
|
28
106
|
* Nuxt head method.
|
|
29
107
|
*
|
|
@@ -39,7 +117,7 @@ export default {
|
|
|
39
117
|
{
|
|
40
118
|
hid: 'canonical',
|
|
41
119
|
rel: 'canonical',
|
|
42
|
-
href: this.canonical || this.route.canonical
|
|
120
|
+
href: this.canonical || (this.route || {}).canonical
|
|
43
121
|
}
|
|
44
122
|
]
|
|
45
123
|
}
|
|
@@ -51,44 +129,142 @@ export default {
|
|
|
51
129
|
return head
|
|
52
130
|
},
|
|
53
131
|
|
|
54
|
-
/**
|
|
55
|
-
* Vue.js Computed properties.
|
|
56
|
-
*
|
|
57
|
-
* @vue-computed {object} redirect The current Redirect, if applicable.
|
|
58
|
-
* @vue-computed {object} route The current Route.
|
|
59
|
-
*/
|
|
132
|
+
/** */
|
|
60
133
|
computed: {
|
|
134
|
+
/**
|
|
135
|
+
* The route module.
|
|
136
|
+
*
|
|
137
|
+
* @type {string}
|
|
138
|
+
*/
|
|
61
139
|
module: ({ route }) =>
|
|
62
140
|
(route || {}).component && route.component.startsWith('druxt-') ? route.component.substring(6) : false,
|
|
63
141
|
|
|
142
|
+
/**
|
|
143
|
+
* The route object.
|
|
144
|
+
*
|
|
145
|
+
* @type {object}
|
|
146
|
+
*/
|
|
147
|
+
route: ({ model }) => model,
|
|
148
|
+
|
|
64
149
|
/**
|
|
65
150
|
* Route title.
|
|
66
151
|
* @type {boolean|string}
|
|
67
152
|
* @default false
|
|
68
153
|
*/
|
|
69
|
-
title: ({ route }) => route.label || false,
|
|
154
|
+
title: ({ route }) => (route || {}).label || false,
|
|
70
155
|
|
|
71
156
|
/**
|
|
72
157
|
* Route component property data.
|
|
73
158
|
* @type {object|string}
|
|
74
159
|
* @default false
|
|
75
160
|
*/
|
|
76
|
-
props: ({ route }) => route.props || false,
|
|
161
|
+
props: ({ route }) => (route || {}).props || false,
|
|
162
|
+
},
|
|
77
163
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
164
|
+
/** */
|
|
165
|
+
watch: {
|
|
166
|
+
/**
|
|
167
|
+
* Re-fetch on update to Path prop.
|
|
168
|
+
*/
|
|
169
|
+
async path() {
|
|
170
|
+
await this.$fetch()
|
|
171
|
+
}
|
|
82
172
|
},
|
|
83
173
|
|
|
174
|
+
/** DruxtModule settings */
|
|
84
175
|
druxt: {
|
|
176
|
+
/**
|
|
177
|
+
* Provides the available component naming options for the Druxt Wrapper.
|
|
178
|
+
*
|
|
179
|
+
* @param {object} context - The module component ViewModel.
|
|
180
|
+
* @returns {ComponentOptions}
|
|
181
|
+
*/
|
|
85
182
|
componentOptions: ({ module, route }) => [
|
|
86
183
|
// @TODO - Add Path options.
|
|
87
184
|
[module || 'error', route.isHomePath ? 'front' : 'not-front'],
|
|
88
185
|
['default']
|
|
89
186
|
],
|
|
90
187
|
|
|
91
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Fetch the decoupled route.
|
|
190
|
+
*/
|
|
191
|
+
async fetchConfig() {
|
|
192
|
+
// Use the v-model value if provided.
|
|
193
|
+
if (this.value) {
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Get the route from the Drupal decoupled router module via the
|
|
198
|
+
// druxtRouter store.
|
|
199
|
+
// Use the Path prop or the Vue Router as the route to lookup.
|
|
200
|
+
const path = this.path || this.$route.fullPath
|
|
201
|
+
const route = await this.$store.dispatch('druxtRouter/getRoute', path)
|
|
202
|
+
this.model = route
|
|
203
|
+
|
|
204
|
+
// If this the path is the active Vue route, set the active route in the
|
|
205
|
+
// druxtRouter store for other modules to use.
|
|
206
|
+
// This is also done when via the middleware if in use.
|
|
207
|
+
const setActiveRoute = path === this.$route.fullPath
|
|
208
|
+
if (setActiveRoute) {
|
|
209
|
+
this.$store.commit('druxtRouter/setRoute', path)
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Provides propsData for the DruxtWrapper.
|
|
215
|
+
*
|
|
216
|
+
* @param {object} context - The module component ViewModel.
|
|
217
|
+
* @returns {PropsData}
|
|
218
|
+
*/
|
|
219
|
+
propsData: ({ $route, path, model }) => ({
|
|
220
|
+
path: path || $route.fullPath,
|
|
221
|
+
route: model
|
|
222
|
+
})
|
|
92
223
|
}
|
|
93
224
|
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Provides the available naming options for the Wrapper component.
|
|
228
|
+
*
|
|
229
|
+
* @typedef {array[]} ComponentOptions
|
|
230
|
+
*
|
|
231
|
+
* @example @lang js
|
|
232
|
+
* [
|
|
233
|
+
* 'DruxtRouter[Module][IsFront?]',
|
|
234
|
+
* 'DruxtRouterDefault',
|
|
235
|
+
* ]
|
|
236
|
+
*
|
|
237
|
+
* @example <caption>Entity route</caption> @lang js
|
|
238
|
+
* [
|
|
239
|
+
* 'DruxtRouterEntityFront',
|
|
240
|
+
* 'DruxtRouterEntity',
|
|
241
|
+
* 'DruxtRouterDefault',
|
|
242
|
+
* '',
|
|
243
|
+
* ]
|
|
244
|
+
*/
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Provides property data for use in the Wrapper component.
|
|
248
|
+
*
|
|
249
|
+
* @typedef {object} PropsData
|
|
250
|
+
* @param {string} path - The route path.
|
|
251
|
+
* @param {object} route - The Decoupled Router object.
|
|
252
|
+
*
|
|
253
|
+
* @example @lang js
|
|
254
|
+
* {
|
|
255
|
+
* path: '/',
|
|
256
|
+
* route: {
|
|
257
|
+
* canonical: 'https://demo-api.druxtjs.org/en/node',
|
|
258
|
+
* component: 'druxt-view',
|
|
259
|
+
* error: false,
|
|
260
|
+
* isHomePath: true,
|
|
261
|
+
* jsonapi: {},
|
|
262
|
+
* label: 'Home',
|
|
263
|
+
* props: {},
|
|
264
|
+
* redirect: false,
|
|
265
|
+
* resolvedPath: '/en/node',
|
|
266
|
+
* type: 'views',
|
|
267
|
+
* }
|
|
268
|
+
* }
|
|
269
|
+
*/
|
|
94
270
|
</script>
|
package/dist/druxt-router.esm.js
CHANGED
|
@@ -51,9 +51,6 @@ class DruxtRouter {
|
|
|
51
51
|
}
|
|
52
52
|
async get(path) {
|
|
53
53
|
const route = await this.getRoute(path);
|
|
54
|
-
if (route.error) {
|
|
55
|
-
return { route };
|
|
56
|
-
}
|
|
57
54
|
const redirect = this.getRedirect(path, route);
|
|
58
55
|
return { redirect, route };
|
|
59
56
|
}
|
|
@@ -150,11 +147,9 @@ class DruxtRouter {
|
|
|
150
147
|
break;
|
|
151
148
|
}
|
|
152
149
|
if (!(response.status >= 200 && response.status < 300)) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
};
|
|
157
|
-
route.component = "error";
|
|
150
|
+
const error = new Error();
|
|
151
|
+
error.response = response;
|
|
152
|
+
throw error;
|
|
158
153
|
}
|
|
159
154
|
return route;
|
|
160
155
|
}
|
|
@@ -226,7 +221,12 @@ const DruxtRouterStore = ({ store }) => {
|
|
|
226
221
|
if (typeof state.routes[path] !== "undefined") {
|
|
227
222
|
return state.routes[path];
|
|
228
223
|
}
|
|
229
|
-
|
|
224
|
+
let route;
|
|
225
|
+
try {
|
|
226
|
+
route = await this.$druxtRouter().getRoute(path);
|
|
227
|
+
} catch (err) {
|
|
228
|
+
route = { error: { statusCode: err.response.status, message: err.response.data.message } };
|
|
229
|
+
}
|
|
230
230
|
commit("addRoute", { path, route });
|
|
231
231
|
return route;
|
|
232
232
|
}
|
|
@@ -282,6 +282,10 @@ const DruxtRouterEntityMixin = {
|
|
|
282
282
|
|
|
283
283
|
const DruxtRouterMixin = {
|
|
284
284
|
props: {
|
|
285
|
+
path: {
|
|
286
|
+
type: String,
|
|
287
|
+
default: void 0
|
|
288
|
+
},
|
|
285
289
|
route: {
|
|
286
290
|
type: Object,
|
|
287
291
|
required: true
|
package/dist/druxt-router.ssr.js
CHANGED
|
@@ -59,9 +59,6 @@ class DruxtRouter {
|
|
|
59
59
|
}
|
|
60
60
|
async get(path) {
|
|
61
61
|
const route = await this.getRoute(path);
|
|
62
|
-
if (route.error) {
|
|
63
|
-
return { route };
|
|
64
|
-
}
|
|
65
62
|
const redirect = this.getRedirect(path, route);
|
|
66
63
|
return { redirect, route };
|
|
67
64
|
}
|
|
@@ -158,11 +155,9 @@ class DruxtRouter {
|
|
|
158
155
|
break;
|
|
159
156
|
}
|
|
160
157
|
if (!(response.status >= 200 && response.status < 300)) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
};
|
|
165
|
-
route.component = "error";
|
|
158
|
+
const error = new Error();
|
|
159
|
+
error.response = response;
|
|
160
|
+
throw error;
|
|
166
161
|
}
|
|
167
162
|
return route;
|
|
168
163
|
}
|
|
@@ -234,7 +229,12 @@ const DruxtRouterStore = ({ store }) => {
|
|
|
234
229
|
if (typeof state.routes[path] !== "undefined") {
|
|
235
230
|
return state.routes[path];
|
|
236
231
|
}
|
|
237
|
-
|
|
232
|
+
let route;
|
|
233
|
+
try {
|
|
234
|
+
route = await this.$druxtRouter().getRoute(path);
|
|
235
|
+
} catch (err) {
|
|
236
|
+
route = { error: { statusCode: err.response.status, message: err.response.data.message } };
|
|
237
|
+
}
|
|
238
238
|
commit("addRoute", { path, route });
|
|
239
239
|
return route;
|
|
240
240
|
}
|
|
@@ -290,6 +290,10 @@ const DruxtRouterEntityMixin = {
|
|
|
290
290
|
|
|
291
291
|
const DruxtRouterMixin = {
|
|
292
292
|
props: {
|
|
293
|
+
path: {
|
|
294
|
+
type: String,
|
|
295
|
+
default: void 0
|
|
296
|
+
},
|
|
293
297
|
route: {
|
|
294
298
|
type: Object,
|
|
295
299
|
required: true
|
package/nuxt/index.js
CHANGED
|
@@ -48,6 +48,9 @@ const DruxtRouterNuxtModule = async function(moduleOptions = {}) {
|
|
|
48
48
|
fileName: "store/druxt-router.js",
|
|
49
49
|
options
|
|
50
50
|
});
|
|
51
|
+
this.nuxt.hook("storybook:config", async ({ stories }) => {
|
|
52
|
+
stories.push("druxt-router/dist/components/*.stories.mjs");
|
|
53
|
+
});
|
|
51
54
|
};
|
|
52
55
|
DruxtRouterNuxtModule.meta = require("../package.json");
|
|
53
56
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "druxt-router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "Drupal router for Nuxt, powered by the Drupal Decoupled Router module.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"templates"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"druxt": "^0.
|
|
45
|
+
"druxt": "^0.14.0",
|
|
46
46
|
"url-parse": "^1.4.7"
|
|
47
47
|
},
|
|
48
48
|
"optionalDependencies": {
|
package/templates/plugin.js
CHANGED
|
@@ -8,6 +8,14 @@ export default (context, inject) => {
|
|
|
8
8
|
options.endpoint = '<%= options.endpoint %>'
|
|
9
9
|
<% } %>
|
|
10
10
|
|
|
11
|
+
<% if ((options.proxy || {}).api) { %>
|
|
12
|
+
if (process.client) {
|
|
13
|
+
options.proxy = {
|
|
14
|
+
api: <%= options.proxy.api %>
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
<% } %>
|
|
18
|
+
|
|
11
19
|
<% if (options.router && options.router.render) { %>
|
|
12
20
|
// Render component.
|
|
13
21
|
options.render = '<%= options.router.render %>'
|