druxt 0.13.0 → 0.17.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 +31 -4
- package/dist/components/DruxtModule.stories.mdx +126 -0
- package/dist/components/DruxtModule.vue +67 -11
- package/dist/druxt.esm.js +181 -33
- package/dist/druxt.ssr.js +182 -33
- package/package.json +8 -1
- package/stories/README.stories.mdx +74 -0
- package/CHANGELOG.md +0 -338
package/dist/druxt.ssr.js
CHANGED
|
@@ -6,6 +6,7 @@ const chalk = require('chalk');
|
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const axios = require('axios');
|
|
8
8
|
const querystring = require('querystring');
|
|
9
|
+
const consola = require('consola');
|
|
9
10
|
const merge = require('deepmerge');
|
|
10
11
|
const md5 = require('md5');
|
|
11
12
|
const Vue = require('vue');
|
|
@@ -15,10 +16,93 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
15
16
|
|
|
16
17
|
const chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
|
|
17
18
|
const axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
19
|
+
const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola);
|
|
18
20
|
const merge__default = /*#__PURE__*/_interopDefaultLegacy(merge);
|
|
19
21
|
const md5__default = /*#__PURE__*/_interopDefaultLegacy(md5);
|
|
20
22
|
const Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue);
|
|
21
23
|
|
|
24
|
+
var name = "druxt";
|
|
25
|
+
var version = "0.17.0";
|
|
26
|
+
var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
|
|
27
|
+
var keywords = [
|
|
28
|
+
"cms",
|
|
29
|
+
"decoupled",
|
|
30
|
+
"drupal",
|
|
31
|
+
"druxt",
|
|
32
|
+
"headless",
|
|
33
|
+
"jsonapi",
|
|
34
|
+
"json:api",
|
|
35
|
+
"nuxt",
|
|
36
|
+
"module",
|
|
37
|
+
"vue"
|
|
38
|
+
];
|
|
39
|
+
var homepage = "https://druxtjs.org";
|
|
40
|
+
var bugs = {
|
|
41
|
+
url: "https://github.com/druxt/druxt.js/issues"
|
|
42
|
+
};
|
|
43
|
+
var repository = {
|
|
44
|
+
type: "git",
|
|
45
|
+
url: "git+https://github.com/druxt/druxt.js"
|
|
46
|
+
};
|
|
47
|
+
var license = "MIT";
|
|
48
|
+
var exports$1 = {
|
|
49
|
+
".": {
|
|
50
|
+
require: "./dist/druxt.ssr.js",
|
|
51
|
+
"import": "./dist/druxt.esm.js"
|
|
52
|
+
},
|
|
53
|
+
"./components/*": "./dist/components/*"
|
|
54
|
+
};
|
|
55
|
+
var main = "dist/druxt.ssr.js";
|
|
56
|
+
var module$1 = "dist/druxt.esm.js";
|
|
57
|
+
var files = [
|
|
58
|
+
"dist",
|
|
59
|
+
"stories",
|
|
60
|
+
"templates"
|
|
61
|
+
];
|
|
62
|
+
var dependencies = {
|
|
63
|
+
"@nuxtjs/proxy": "^2.1.0",
|
|
64
|
+
axios: "^0.21.1",
|
|
65
|
+
chalk: "^4.1.2",
|
|
66
|
+
deepmerge: "^4.2.2",
|
|
67
|
+
"drupal-jsonapi-params": "^1.2.1",
|
|
68
|
+
md5: "^2.3.0",
|
|
69
|
+
querystring: "^0.2.0",
|
|
70
|
+
scule: "^0.2.0"
|
|
71
|
+
};
|
|
72
|
+
var devDependencies = {
|
|
73
|
+
"@storybook/addon-docs": "^6.4.13"
|
|
74
|
+
};
|
|
75
|
+
var peerDependencies = {
|
|
76
|
+
consola: "*"
|
|
77
|
+
};
|
|
78
|
+
var optionalDependencies = {
|
|
79
|
+
"core-js": "^3.16.1",
|
|
80
|
+
vue: "^2.6.14",
|
|
81
|
+
vuex: "^3.6.2"
|
|
82
|
+
};
|
|
83
|
+
var publishConfig = {
|
|
84
|
+
access: "public"
|
|
85
|
+
};
|
|
86
|
+
const meta = {
|
|
87
|
+
name: name,
|
|
88
|
+
version: version,
|
|
89
|
+
description: description,
|
|
90
|
+
keywords: keywords,
|
|
91
|
+
homepage: homepage,
|
|
92
|
+
bugs: bugs,
|
|
93
|
+
repository: repository,
|
|
94
|
+
license: license,
|
|
95
|
+
exports: exports$1,
|
|
96
|
+
main: main,
|
|
97
|
+
module: module$1,
|
|
98
|
+
files: files,
|
|
99
|
+
dependencies: dependencies,
|
|
100
|
+
devDependencies: devDependencies,
|
|
101
|
+
peerDependencies: peerDependencies,
|
|
102
|
+
optionalDependencies: optionalDependencies,
|
|
103
|
+
publishConfig: publishConfig
|
|
104
|
+
};
|
|
105
|
+
|
|
22
106
|
const DruxtNuxtModule = function(moduleOptions = {}) {
|
|
23
107
|
var _a;
|
|
24
108
|
const options = {
|
|
@@ -61,6 +145,15 @@ const DruxtNuxtModule = function(moduleOptions = {}) {
|
|
|
61
145
|
fileName: "druxt.js",
|
|
62
146
|
options
|
|
63
147
|
});
|
|
148
|
+
const extendPlugins = this.options.extendPlugins;
|
|
149
|
+
this.options.extendPlugins = (plugins) => {
|
|
150
|
+
plugins = typeof extendPlugins === "function" ? extendPlugins(plugins) : plugins;
|
|
151
|
+
const index = plugins.findIndex(({ src }) => src === `${this.options.buildDir}/druxt.js`);
|
|
152
|
+
const plugin = plugins[index];
|
|
153
|
+
plugins.splice(index, 1);
|
|
154
|
+
plugins.unshift(plugin);
|
|
155
|
+
return plugins;
|
|
156
|
+
};
|
|
64
157
|
this.addPlugin({
|
|
65
158
|
src: path.resolve(__dirname, "../templates/store.js"),
|
|
66
159
|
fileName: "store/druxt.js",
|
|
@@ -68,12 +161,20 @@ const DruxtNuxtModule = function(moduleOptions = {}) {
|
|
|
68
161
|
});
|
|
69
162
|
this.options.store = true;
|
|
70
163
|
this.options.components = (_a = this.options.components) != null ? _a : true;
|
|
71
|
-
this.options.cli.badgeMessages.push(`${chalk__default['default'].bold("Druxt
|
|
164
|
+
this.options.cli.badgeMessages.push(`${chalk__default['default'].blue.bold("Druxt")} @ v${meta.version}`);
|
|
165
|
+
this.options.cli.badgeMessages.push(`${chalk__default['default'].bold("API:")} ${chalk__default['default'].blue.underline(options.baseUrl + options.endpoint)}`);
|
|
166
|
+
this.nuxt.hook("storybook:config", async ({ stories }) => {
|
|
167
|
+
stories.push("druxt/stories/*.stories.mdx");
|
|
168
|
+
stories.push("druxt/dist/components/*.stories.mdx");
|
|
169
|
+
stories.push("druxt/dist/components/*.stories.mjs");
|
|
170
|
+
});
|
|
72
171
|
};
|
|
73
|
-
DruxtNuxtModule.meta = require("../package.json");
|
|
74
172
|
|
|
75
173
|
class DruxtClient {
|
|
76
174
|
constructor(baseUrl, options = {}) {
|
|
175
|
+
this.log = consola__default['default'].create({ defaults: {
|
|
176
|
+
tag: "DruxtClient"
|
|
177
|
+
} });
|
|
77
178
|
if (!baseUrl) {
|
|
78
179
|
throw new Error("The 'baseUrl' parameter is required.");
|
|
79
180
|
}
|
|
@@ -85,6 +186,16 @@ class DruxtClient {
|
|
|
85
186
|
axiosSettings = Object.assign(axiosSettings, options.axios);
|
|
86
187
|
}
|
|
87
188
|
this.axios = axios__default['default'].create(axiosSettings);
|
|
189
|
+
if (options.debug) {
|
|
190
|
+
const log = this.log;
|
|
191
|
+
this.axios.interceptors.request.use((config) => {
|
|
192
|
+
log.info(config.url);
|
|
193
|
+
return config;
|
|
194
|
+
}, (error) => {
|
|
195
|
+
log.error(error);
|
|
196
|
+
return Promise.reject(error);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
88
199
|
this.options = {
|
|
89
200
|
endpoint: "/jsonapi",
|
|
90
201
|
jsonapiResourceConfig: "jsonapi_resource_config--jsonapi_resource_config",
|
|
@@ -126,9 +237,16 @@ class DruxtClient {
|
|
|
126
237
|
}
|
|
127
238
|
}
|
|
128
239
|
if (Object.keys(permissions).length) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
240
|
+
const err = {
|
|
241
|
+
response: {
|
|
242
|
+
statusText: res.data.meta.omitted.detail,
|
|
243
|
+
data: {
|
|
244
|
+
errors: [{ detail: `Required permissions:
|
|
245
|
+
- ${Object.keys(permissions).join("\n - ")}` }]
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
throw err;
|
|
132
250
|
}
|
|
133
251
|
}
|
|
134
252
|
}
|
|
@@ -148,19 +266,49 @@ class DruxtClient {
|
|
|
148
266
|
}
|
|
149
267
|
});
|
|
150
268
|
} catch (err) {
|
|
151
|
-
|
|
269
|
+
this.error(err, { url: href });
|
|
152
270
|
}
|
|
153
271
|
return response;
|
|
154
272
|
}
|
|
273
|
+
error(err, context = {}) {
|
|
274
|
+
let { url } = context;
|
|
275
|
+
if (!url && ((err.response || {}).config || {}).url) {
|
|
276
|
+
url = err.response.config.url;
|
|
277
|
+
}
|
|
278
|
+
const title = [
|
|
279
|
+
(err.response || {}).status,
|
|
280
|
+
(err.response || {}).statusText || err.message
|
|
281
|
+
].filter((s) => s).join(": ");
|
|
282
|
+
const meta = { url: url && [this.options.baseUrl, url].join("") };
|
|
283
|
+
let message = [title];
|
|
284
|
+
if (Object.values(meta).filter((o) => o).length) {
|
|
285
|
+
message.push(Object.entries(meta).filter(([, v]) => v).map(([key, value]) => `${key.toUpperCase()}: ${value}`).join("\n"));
|
|
286
|
+
}
|
|
287
|
+
if (((((err.response || {}).data || {}).errors || [])[0] || {}).detail) {
|
|
288
|
+
message.push(err.response.data.errors[0].detail);
|
|
289
|
+
}
|
|
290
|
+
const error = Error(message.join("\n\n"));
|
|
291
|
+
error.response = err.response;
|
|
292
|
+
error.druxt = context;
|
|
293
|
+
throw error;
|
|
294
|
+
}
|
|
295
|
+
async get(url, options) {
|
|
296
|
+
try {
|
|
297
|
+
const res = await this.axios.get(url, options);
|
|
298
|
+
this.checkPermissions(res);
|
|
299
|
+
return res;
|
|
300
|
+
} catch (err) {
|
|
301
|
+
this.error(err, { url });
|
|
302
|
+
}
|
|
303
|
+
}
|
|
155
304
|
async getCollection(type, query) {
|
|
156
305
|
const { href } = await this.getIndex(type);
|
|
157
306
|
if (!href) {
|
|
158
307
|
return false;
|
|
159
308
|
}
|
|
160
309
|
const url = this.buildQueryUrl(href, query);
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
return res.data;
|
|
310
|
+
const { data } = await this.get(url);
|
|
311
|
+
return data;
|
|
164
312
|
}
|
|
165
313
|
async getCollectionAll(type, query) {
|
|
166
314
|
const collections = [];
|
|
@@ -180,16 +328,27 @@ class DruxtClient {
|
|
|
180
328
|
if (this.index && resource) {
|
|
181
329
|
return this.index[resource] ? this.index[resource] : false;
|
|
182
330
|
}
|
|
183
|
-
|
|
331
|
+
const url = this.options.endpoint;
|
|
332
|
+
const { data } = await this.get(url);
|
|
333
|
+
let index = data.links;
|
|
334
|
+
if (typeof index !== "object") {
|
|
335
|
+
const err = { response: { statusText: "Invalid JSON:API endpoint" } };
|
|
336
|
+
this.error(err, { url });
|
|
337
|
+
}
|
|
184
338
|
const baseUrl = this.options.baseUrl;
|
|
185
339
|
index = Object.fromEntries(Object.entries(index).map(([key, value]) => {
|
|
186
340
|
value.href = value.href.replace(baseUrl, "");
|
|
187
341
|
return [key, value];
|
|
188
342
|
}));
|
|
189
343
|
if (index[this.options.jsonapiResourceConfig]) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
344
|
+
let resources = [];
|
|
345
|
+
try {
|
|
346
|
+
resources = (await this.get(index[this.options.jsonapiResourceConfig].href)).data.data;
|
|
347
|
+
} catch (err) {
|
|
348
|
+
this.log.warn(err.message);
|
|
349
|
+
}
|
|
350
|
+
for (const resourceType in resources) {
|
|
351
|
+
const resource2 = resources[resourceType];
|
|
193
352
|
const internal = resource2.attributes.drupal_internal__id.split("--");
|
|
194
353
|
const item = {
|
|
195
354
|
resourceType: resource2.attributes.resourceType,
|
|
@@ -205,11 +364,7 @@ class DruxtClient {
|
|
|
205
364
|
}
|
|
206
365
|
}
|
|
207
366
|
this.index = index;
|
|
208
|
-
|
|
209
|
-
const response = this.index[resource] ? this.index[resource] : false;
|
|
210
|
-
return response;
|
|
211
|
-
}
|
|
212
|
-
return this.index;
|
|
367
|
+
return resource ? this.index[resource] || false : this.index;
|
|
213
368
|
}
|
|
214
369
|
async getRelated(type, id, related, query) {
|
|
215
370
|
if (!id || !type || !related) {
|
|
@@ -220,12 +375,8 @@ class DruxtClient {
|
|
|
220
375
|
href = this.options.endpoint + "/" + type.replace("--", "/");
|
|
221
376
|
}
|
|
222
377
|
const url = this.buildQueryUrl(`${href}/${id}/${related}`, query);
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return related2.data;
|
|
226
|
-
} catch (e) {
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
378
|
+
const { data } = await this.get(url);
|
|
379
|
+
return data;
|
|
229
380
|
}
|
|
230
381
|
async getResource(type, id, query) {
|
|
231
382
|
if (!id || !type) {
|
|
@@ -235,13 +386,9 @@ class DruxtClient {
|
|
|
235
386
|
if (!href) {
|
|
236
387
|
href = this.options.endpoint + "/" + type.replace("--", "/");
|
|
237
388
|
}
|
|
238
|
-
const url = this.buildQueryUrl(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return resource.data;
|
|
242
|
-
} catch (e) {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
389
|
+
const url = this.buildQueryUrl([href, id].join("/"), query);
|
|
390
|
+
const { data } = await this.get(url);
|
|
391
|
+
return data;
|
|
245
392
|
}
|
|
246
393
|
async updateResource(resource) {
|
|
247
394
|
const { href } = await this.getIndex(resource.type);
|
|
@@ -257,7 +404,7 @@ class DruxtClient {
|
|
|
257
404
|
}
|
|
258
405
|
});
|
|
259
406
|
} catch (err) {
|
|
260
|
-
|
|
407
|
+
this.error(err);
|
|
261
408
|
}
|
|
262
409
|
return response;
|
|
263
410
|
}
|
|
@@ -268,7 +415,7 @@ const getDrupalJsonApiParams = (query) => {
|
|
|
268
415
|
};
|
|
269
416
|
|
|
270
417
|
const dehydrateResources = ({ commit, queryObject, resources }) => {
|
|
271
|
-
return resources.map((data) => {
|
|
418
|
+
return (resources || []).map((data) => {
|
|
272
419
|
const link = decodeURI(((data.links || {}).self || {}).href || "");
|
|
273
420
|
const href = typeof (queryObject.fields || {})[data.type] === "string" ? [link.split("?")[0], `fields[${data.type}]=${queryObject.fields[data.type]}`].join("?") : link;
|
|
274
421
|
commit("druxt/addResource", {
|
|
@@ -459,6 +606,8 @@ class DruxtClass {
|
|
|
459
606
|
}
|
|
460
607
|
}
|
|
461
608
|
|
|
609
|
+
DruxtNuxtModule.meta = require("../package.json");
|
|
610
|
+
|
|
462
611
|
exports.DruxtClass = DruxtClass;
|
|
463
612
|
exports.DruxtClient = DruxtClient;
|
|
464
613
|
exports.DruxtStore = DruxtStore;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "druxt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "The Fully Decoupled Drupal Framework for Nuxt.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"module": "dist/druxt.esm.js",
|
|
35
35
|
"files": [
|
|
36
36
|
"dist",
|
|
37
|
+
"stories",
|
|
37
38
|
"templates"
|
|
38
39
|
],
|
|
39
40
|
"dependencies": {
|
|
@@ -46,6 +47,12 @@
|
|
|
46
47
|
"querystring": "^0.2.0",
|
|
47
48
|
"scule": "^0.2.0"
|
|
48
49
|
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@storybook/addon-docs": "^6.4.13"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"consola": "*"
|
|
55
|
+
},
|
|
49
56
|
"optionalDependencies": {
|
|
50
57
|
"core-js": "^3.16.1",
|
|
51
58
|
"vue": "^2.6.14",
|
|
@@ -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)
|