druxt 0.15.0 → 0.18.0
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/dist/components/DruxtDebug.stories.mjs +48 -0
- package/dist/components/DruxtDebug.vue +7 -2
- package/dist/components/DruxtModule.stories.mdx +126 -0
- package/dist/components/DruxtModule.vue +66 -10
- package/dist/druxt.esm.js +110 -41
- package/dist/druxt.ssr.js +110 -41
- package/package.json +7 -2
- package/stories/README.stories.mdx +74 -0
- package/templates/plugin.js +10 -1
- package/CHANGELOG.md +0 -368
package/dist/druxt.ssr.js
CHANGED
|
@@ -22,7 +22,7 @@ const md5__default = /*#__PURE__*/_interopDefaultLegacy(md5);
|
|
|
22
22
|
const Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue);
|
|
23
23
|
|
|
24
24
|
var name = "druxt";
|
|
25
|
-
var version = "0.
|
|
25
|
+
var version = "0.18.0";
|
|
26
26
|
var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
|
|
27
27
|
var keywords = [
|
|
28
28
|
"cms",
|
|
@@ -56,11 +56,12 @@ var main = "dist/druxt.ssr.js";
|
|
|
56
56
|
var module$1 = "dist/druxt.esm.js";
|
|
57
57
|
var files = [
|
|
58
58
|
"dist",
|
|
59
|
+
"stories",
|
|
59
60
|
"templates"
|
|
60
61
|
];
|
|
61
62
|
var dependencies = {
|
|
63
|
+
"@nuxtjs/axios": "^5.13.6",
|
|
62
64
|
"@nuxtjs/proxy": "^2.1.0",
|
|
63
|
-
axios: "^0.21.1",
|
|
64
65
|
chalk: "^4.1.2",
|
|
65
66
|
deepmerge: "^4.2.2",
|
|
66
67
|
"drupal-jsonapi-params": "^1.2.1",
|
|
@@ -68,7 +69,11 @@ var dependencies = {
|
|
|
68
69
|
querystring: "^0.2.0",
|
|
69
70
|
scule: "^0.2.0"
|
|
70
71
|
};
|
|
72
|
+
var devDependencies = {
|
|
73
|
+
"@storybook/addon-docs": "^6.4.13"
|
|
74
|
+
};
|
|
71
75
|
var peerDependencies = {
|
|
76
|
+
axios: "*",
|
|
72
77
|
consola: "*"
|
|
73
78
|
};
|
|
74
79
|
var optionalDependencies = {
|
|
@@ -93,6 +98,7 @@ const meta = {
|
|
|
93
98
|
module: module$1,
|
|
94
99
|
files: files,
|
|
95
100
|
dependencies: dependencies,
|
|
101
|
+
devDependencies: devDependencies,
|
|
96
102
|
peerDependencies: peerDependencies,
|
|
97
103
|
optionalDependencies: optionalDependencies,
|
|
98
104
|
publishConfig: publishConfig
|
|
@@ -132,6 +138,14 @@ const DruxtNuxtModule = function(moduleOptions = {}) {
|
|
|
132
138
|
}
|
|
133
139
|
this.addModule("@nuxtjs/proxy");
|
|
134
140
|
}
|
|
141
|
+
if (!options.axios) {
|
|
142
|
+
this.options.axios = {
|
|
143
|
+
baseURL: options.baseUrl,
|
|
144
|
+
proxy: !!this.options.proxy,
|
|
145
|
+
...this.options.axios
|
|
146
|
+
};
|
|
147
|
+
this.addModule("@nuxtjs/axios");
|
|
148
|
+
}
|
|
135
149
|
this.nuxt.hook("components:dirs", (dirs) => {
|
|
136
150
|
dirs.push({ path: path.join(__dirname, "components") });
|
|
137
151
|
});
|
|
@@ -140,6 +154,18 @@ const DruxtNuxtModule = function(moduleOptions = {}) {
|
|
|
140
154
|
fileName: "druxt.js",
|
|
141
155
|
options
|
|
142
156
|
});
|
|
157
|
+
const extendPlugins = this.options.extendPlugins;
|
|
158
|
+
this.options.extendPlugins = (plugins) => {
|
|
159
|
+
plugins = typeof extendPlugins === "function" ? extendPlugins(plugins) : plugins;
|
|
160
|
+
const axiosIndex = plugins.findIndex(({ src }) => src === `${this.options.buildDir}/axios.js`);
|
|
161
|
+
const axiosPlugin = plugins[axiosIndex];
|
|
162
|
+
plugins.splice(axiosIndex, 1);
|
|
163
|
+
const druxtIndex = plugins.findIndex(({ src }) => src === `${this.options.buildDir}/druxt.js`);
|
|
164
|
+
const druxtPlugin = plugins[druxtIndex];
|
|
165
|
+
plugins.splice(druxtIndex, 1);
|
|
166
|
+
plugins = [axiosPlugin, druxtPlugin, ...plugins];
|
|
167
|
+
return plugins;
|
|
168
|
+
};
|
|
143
169
|
this.addPlugin({
|
|
144
170
|
src: path.resolve(__dirname, "../templates/store.js"),
|
|
145
171
|
fileName: "store/druxt.js",
|
|
@@ -149,8 +175,12 @@ const DruxtNuxtModule = function(moduleOptions = {}) {
|
|
|
149
175
|
this.options.components = (_a = this.options.components) != null ? _a : true;
|
|
150
176
|
this.options.cli.badgeMessages.push(`${chalk__default['default'].blue.bold("Druxt")} @ v${meta.version}`);
|
|
151
177
|
this.options.cli.badgeMessages.push(`${chalk__default['default'].bold("API:")} ${chalk__default['default'].blue.underline(options.baseUrl + options.endpoint)}`);
|
|
178
|
+
this.nuxt.hook("storybook:config", async ({ stories }) => {
|
|
179
|
+
stories.push("druxt/stories/*.stories.mdx");
|
|
180
|
+
stories.push("druxt/dist/components/*.stories.mdx");
|
|
181
|
+
stories.push("druxt/dist/components/*.stories.mjs");
|
|
182
|
+
});
|
|
152
183
|
};
|
|
153
|
-
DruxtNuxtModule.meta = meta;
|
|
154
184
|
|
|
155
185
|
class DruxtClient {
|
|
156
186
|
constructor(baseUrl, options = {}) {
|
|
@@ -160,14 +190,15 @@ class DruxtClient {
|
|
|
160
190
|
if (!baseUrl) {
|
|
161
191
|
throw new Error("The 'baseUrl' parameter is required.");
|
|
162
192
|
}
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
193
|
+
this.axios = {};
|
|
194
|
+
if (typeof options.axios === "function") {
|
|
195
|
+
this.axios = options.axios;
|
|
196
|
+
} else {
|
|
197
|
+
this.axios = axios__default['default'].create({
|
|
198
|
+
...options.axios || {},
|
|
199
|
+
baseURL: baseUrl
|
|
200
|
+
});
|
|
169
201
|
}
|
|
170
|
-
this.axios = axios__default['default'].create(axiosSettings);
|
|
171
202
|
if (options.debug) {
|
|
172
203
|
const log = this.log;
|
|
173
204
|
this.axios.interceptors.request.use((config) => {
|
|
@@ -219,9 +250,16 @@ class DruxtClient {
|
|
|
219
250
|
}
|
|
220
251
|
}
|
|
221
252
|
if (Object.keys(permissions).length) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
253
|
+
const err = {
|
|
254
|
+
response: {
|
|
255
|
+
statusText: res.data.meta.omitted.detail,
|
|
256
|
+
data: {
|
|
257
|
+
errors: [{ detail: `Required permissions:
|
|
258
|
+
- ${Object.keys(permissions).join("\n - ")}` }]
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
throw err;
|
|
225
263
|
}
|
|
226
264
|
}
|
|
227
265
|
}
|
|
@@ -241,19 +279,49 @@ class DruxtClient {
|
|
|
241
279
|
}
|
|
242
280
|
});
|
|
243
281
|
} catch (err) {
|
|
244
|
-
|
|
282
|
+
this.error(err, { url: href });
|
|
245
283
|
}
|
|
246
284
|
return response;
|
|
247
285
|
}
|
|
286
|
+
error(err, context = {}) {
|
|
287
|
+
let { url } = context;
|
|
288
|
+
if (!url && ((err.response || {}).config || {}).url) {
|
|
289
|
+
url = err.response.config.url;
|
|
290
|
+
}
|
|
291
|
+
const title = [
|
|
292
|
+
(err.response || {}).status,
|
|
293
|
+
(err.response || {}).statusText || err.message
|
|
294
|
+
].filter((s) => s).join(": ");
|
|
295
|
+
const meta = { url: url && [this.options.baseUrl, url].join("") };
|
|
296
|
+
let message = [title];
|
|
297
|
+
if (Object.values(meta).filter((o) => o).length) {
|
|
298
|
+
message.push(Object.entries(meta).filter(([, v]) => v).map(([key, value]) => `${key.toUpperCase()}: ${value}`).join("\n"));
|
|
299
|
+
}
|
|
300
|
+
if (((((err.response || {}).data || {}).errors || [])[0] || {}).detail) {
|
|
301
|
+
message.push(err.response.data.errors[0].detail);
|
|
302
|
+
}
|
|
303
|
+
const error = Error(message.join("\n\n"));
|
|
304
|
+
error.response = err.response;
|
|
305
|
+
error.druxt = context;
|
|
306
|
+
throw error;
|
|
307
|
+
}
|
|
308
|
+
async get(url, options) {
|
|
309
|
+
try {
|
|
310
|
+
const res = await this.axios.get(url, options);
|
|
311
|
+
this.checkPermissions(res);
|
|
312
|
+
return res;
|
|
313
|
+
} catch (err) {
|
|
314
|
+
this.error(err, { url });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
248
317
|
async getCollection(type, query) {
|
|
249
318
|
const { href } = await this.getIndex(type);
|
|
250
319
|
if (!href) {
|
|
251
320
|
return false;
|
|
252
321
|
}
|
|
253
322
|
const url = this.buildQueryUrl(href, query);
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
return res.data;
|
|
323
|
+
const { data } = await this.get(url);
|
|
324
|
+
return data;
|
|
257
325
|
}
|
|
258
326
|
async getCollectionAll(type, query) {
|
|
259
327
|
const collections = [];
|
|
@@ -273,16 +341,27 @@ class DruxtClient {
|
|
|
273
341
|
if (this.index && resource) {
|
|
274
342
|
return this.index[resource] ? this.index[resource] : false;
|
|
275
343
|
}
|
|
276
|
-
|
|
344
|
+
const url = this.options.endpoint;
|
|
345
|
+
const { data } = await this.get(url);
|
|
346
|
+
let index = data.links;
|
|
347
|
+
if (typeof index !== "object") {
|
|
348
|
+
const err = { response: { statusText: "Invalid JSON:API endpoint" } };
|
|
349
|
+
this.error(err, { url });
|
|
350
|
+
}
|
|
277
351
|
const baseUrl = this.options.baseUrl;
|
|
278
352
|
index = Object.fromEntries(Object.entries(index).map(([key, value]) => {
|
|
279
353
|
value.href = value.href.replace(baseUrl, "");
|
|
280
354
|
return [key, value];
|
|
281
355
|
}));
|
|
282
356
|
if (index[this.options.jsonapiResourceConfig]) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
357
|
+
let resources = [];
|
|
358
|
+
try {
|
|
359
|
+
resources = (await this.get(index[this.options.jsonapiResourceConfig].href)).data.data;
|
|
360
|
+
} catch (err) {
|
|
361
|
+
this.log.warn(err.message);
|
|
362
|
+
}
|
|
363
|
+
for (const resourceType in resources) {
|
|
364
|
+
const resource2 = resources[resourceType];
|
|
286
365
|
const internal = resource2.attributes.drupal_internal__id.split("--");
|
|
287
366
|
const item = {
|
|
288
367
|
resourceType: resource2.attributes.resourceType,
|
|
@@ -298,11 +377,7 @@ class DruxtClient {
|
|
|
298
377
|
}
|
|
299
378
|
}
|
|
300
379
|
this.index = index;
|
|
301
|
-
|
|
302
|
-
const response = this.index[resource] ? this.index[resource] : false;
|
|
303
|
-
return response;
|
|
304
|
-
}
|
|
305
|
-
return this.index;
|
|
380
|
+
return resource ? this.index[resource] || false : this.index;
|
|
306
381
|
}
|
|
307
382
|
async getRelated(type, id, related, query) {
|
|
308
383
|
if (!id || !type || !related) {
|
|
@@ -313,12 +388,8 @@ class DruxtClient {
|
|
|
313
388
|
href = this.options.endpoint + "/" + type.replace("--", "/");
|
|
314
389
|
}
|
|
315
390
|
const url = this.buildQueryUrl(`${href}/${id}/${related}`, query);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
return related2.data;
|
|
319
|
-
} catch (e) {
|
|
320
|
-
return false;
|
|
321
|
-
}
|
|
391
|
+
const { data } = await this.get(url);
|
|
392
|
+
return data;
|
|
322
393
|
}
|
|
323
394
|
async getResource(type, id, query) {
|
|
324
395
|
if (!id || !type) {
|
|
@@ -328,13 +399,9 @@ class DruxtClient {
|
|
|
328
399
|
if (!href) {
|
|
329
400
|
href = this.options.endpoint + "/" + type.replace("--", "/");
|
|
330
401
|
}
|
|
331
|
-
const url = this.buildQueryUrl(
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return resource.data;
|
|
335
|
-
} catch (e) {
|
|
336
|
-
return false;
|
|
337
|
-
}
|
|
402
|
+
const url = this.buildQueryUrl([href, id].join("/"), query);
|
|
403
|
+
const { data } = await this.get(url);
|
|
404
|
+
return data;
|
|
338
405
|
}
|
|
339
406
|
async updateResource(resource) {
|
|
340
407
|
const { href } = await this.getIndex(resource.type);
|
|
@@ -350,7 +417,7 @@ class DruxtClient {
|
|
|
350
417
|
}
|
|
351
418
|
});
|
|
352
419
|
} catch (err) {
|
|
353
|
-
|
|
420
|
+
this.error(err);
|
|
354
421
|
}
|
|
355
422
|
return response;
|
|
356
423
|
}
|
|
@@ -361,7 +428,7 @@ const getDrupalJsonApiParams = (query) => {
|
|
|
361
428
|
};
|
|
362
429
|
|
|
363
430
|
const dehydrateResources = ({ commit, queryObject, resources }) => {
|
|
364
|
-
return resources.map((data) => {
|
|
431
|
+
return (resources || []).map((data) => {
|
|
365
432
|
const link = decodeURI(((data.links || {}).self || {}).href || "");
|
|
366
433
|
const href = typeof (queryObject.fields || {})[data.type] === "string" ? [link.split("?")[0], `fields[${data.type}]=${queryObject.fields[data.type]}`].join("?") : link;
|
|
367
434
|
commit("druxt/addResource", {
|
|
@@ -552,6 +619,8 @@ class DruxtClass {
|
|
|
552
619
|
}
|
|
553
620
|
}
|
|
554
621
|
|
|
622
|
+
DruxtNuxtModule.meta = require("../package.json");
|
|
623
|
+
|
|
555
624
|
exports.DruxtClass = DruxtClass;
|
|
556
625
|
exports.DruxtClient = DruxtClient;
|
|
557
626
|
exports.DruxtStore = DruxtStore;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "druxt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "The Fully Decoupled Drupal Framework for Nuxt.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
@@ -34,11 +34,12 @@
|
|
|
34
34
|
"module": "dist/druxt.esm.js",
|
|
35
35
|
"files": [
|
|
36
36
|
"dist",
|
|
37
|
+
"stories",
|
|
37
38
|
"templates"
|
|
38
39
|
],
|
|
39
40
|
"dependencies": {
|
|
41
|
+
"@nuxtjs/axios": "^5.13.6",
|
|
40
42
|
"@nuxtjs/proxy": "^2.1.0",
|
|
41
|
-
"axios": "^0.21.1",
|
|
42
43
|
"chalk": "^4.1.2",
|
|
43
44
|
"deepmerge": "^4.2.2",
|
|
44
45
|
"drupal-jsonapi-params": "^1.2.1",
|
|
@@ -46,7 +47,11 @@
|
|
|
46
47
|
"querystring": "^0.2.0",
|
|
47
48
|
"scule": "^0.2.0"
|
|
48
49
|
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@storybook/addon-docs": "^6.4.13"
|
|
52
|
+
},
|
|
49
53
|
"peerDependencies": {
|
|
54
|
+
"axios": "*",
|
|
50
55
|
"consola": "*"
|
|
51
56
|
},
|
|
52
57
|
"optionalDependencies": {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Meta } from '@storybook/addon-docs'
|
|
2
|
+
|
|
3
|
+
<Meta title="Druxt/README" />
|
|
4
|
+
|
|
5
|
+
# Druxt Storybook
|
|
6
|
+
|
|
7
|
+
> Druxt + @nuxtjs/Storybook
|
|
8
|
+
|
|
9
|
+
The following documentation and stories are provided by
|
|
10
|
+
[DruxtJS](https://druxtjs.org) and the installed Druxt modules.
|
|
11
|
+
|
|
12
|
+
The stories are connected to your Drupal JSON:API via the DruxtClient; this
|
|
13
|
+
allows you to test your Druxt Wrapper components using live data.
|
|
14
|
+
|
|
15
|
+
- For more information, refer to the
|
|
16
|
+
[Druxt Storybook guide](https://druxtjs.org/guide/storybook).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Introduction
|
|
21
|
+
|
|
22
|
+
This is a live Druxt Storybook, with autogenerated stories based on the
|
|
23
|
+
configuration of your Drupal backend.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
### Autogenerated stories
|
|
28
|
+
|
|
29
|
+
Each Druxt module is able to use configuration from your Drupal backend to craft
|
|
30
|
+
site specific stories.
|
|
31
|
+
|
|
32
|
+
For instance, the DruxtEntity module will create a story for each Entity type,
|
|
33
|
+
Bundle and Display mode, while the Block module will create a story for each
|
|
34
|
+
backend Theme, Region and Block.
|
|
35
|
+
|
|
36
|
+
Search or navigate through the Druxt components and stories in the Storybook
|
|
37
|
+
sidebar.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### What is Druxt?
|
|
42
|
+
|
|
43
|
+
> Drupal + Nuxt = Druxt
|
|
44
|
+
|
|
45
|
+
Druxt is a framework for building Fully Decoupled Drupal and Nuxt.js
|
|
46
|
+
applications and sites. It allows you to leverage the content modelling and
|
|
47
|
+
management power of Drupal, and build elegant user experiences with Nuxt.js.
|
|
48
|
+
|
|
49
|
+
- Find out more @ [DruxtJS.org](https://druxtjs.org)
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### Druxt components
|
|
54
|
+
|
|
55
|
+
Druxt components are provided by Druxt modules to provide targetted decoupled
|
|
56
|
+
Drupal functionality; A **DruxtEntity** component to render Drupal Content
|
|
57
|
+
entities, or a **DruxtMenu** component to render a Drupal menu, etc.
|
|
58
|
+
|
|
59
|
+
- See the core Druxt components @
|
|
60
|
+
[https://druxtjs.org/api/components](https://druxtjs.org/api/components)
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### Druxt Wrapper theme system
|
|
65
|
+
|
|
66
|
+
Druxt components that extend the **DruxtModule** use slot based wrapper system,
|
|
67
|
+
providing the frontend developer the ability to create theme templates per
|
|
68
|
+
Content type, or Display mode, and many more component options depending on the
|
|
69
|
+
module.
|
|
70
|
+
|
|
71
|
+
The available component options are provided via the `component.options` data
|
|
72
|
+
on the relevant Druxt module component.
|
|
73
|
+
|
|
74
|
+
- For more information, see the [Themeing guide](https://druxtjs.org/guide/theming)
|
package/templates/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DruxtClient } from 'druxt'
|
|
2
2
|
|
|
3
|
-
export default (
|
|
3
|
+
export default ({ app }, inject) => {
|
|
4
4
|
const options = <%= JSON.stringify(options) %>
|
|
5
5
|
|
|
6
6
|
// Disable the proxy for server side requests.
|
|
@@ -8,6 +8,15 @@ export default (context, inject) => {
|
|
|
8
8
|
options.proxy.api = false
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
<% if (typeof options.axios === 'object') { %>
|
|
12
|
+
// Axios settings.
|
|
13
|
+
console.warn('[druxt] Axios instance settings are deprecated, use @nuxtjs/axios module configuration instead.')
|
|
14
|
+
options.axios = <%= JSON.stringify(options.axios) %>
|
|
15
|
+
<% } else { %>
|
|
16
|
+
// Use the @nuxtjs/axios module Axios instance.
|
|
17
|
+
options.axios = app.$axios
|
|
18
|
+
<% } %>
|
|
19
|
+
|
|
11
20
|
const druxt = new DruxtClient(options.baseUrl, options)
|
|
12
21
|
druxt.settings = options
|
|
13
22
|
inject('druxt', druxt)
|