Socket
Socket
Sign inDemoInstall

druxt

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

druxt - npm Package Compare versions

Comparing version 0.8.3 to 0.9.0

CHANGELOG.md

1825

dist/druxt.esm.js
import { resolve } from 'path';
import axios from 'axios';
import { stringify } from 'querystring';
import { pascalCase, splitByCase } from 'scule';
import Vue from 'vue';
import merge from 'deepmerge';
import md5 from 'md5';
import Vue from 'vue';
import { DrupalJsonApiParams } from 'drupal-jsonapi-params';
/**
* The Vue.js Druxt component.
*
* @example @lang vue
* <Druxt
* :module="module"
* :props-data="propsData"
* :wrapper="{
* component,
* propsData: {}
* }"
* />
*/
var script = {
name: 'Druxt',
/**
* Vue.js Props.
*/
props: {
/**
* Inner element.
*
* @type {object}
* @default { component: 'div', propsData: {} }
*/
inner: {
type: [Object, Boolean],
default: function () { return ({
component: 'div',
propsData: {},
}); }
},
/**
* The DruxtJS module to render.
*
* @type {string}
*
* @example @lang vue <caption>Using the [DruxtJS Site module](https://site.druxtjs.org).</caption>
* <Druxt module="site" />
*/
module: {
type: String,
required: true,
},
/**
* Props data to bind to the specified DruxtJS module.
*
* @type {object}
*
* @example @lang vue <caption>Using the [DruxtJS Entity module](https://entity.druxtjs.org) to render a 'node--article' resource.</caption>
* <Druxt
* module="entity"
* :props-data="{
* mode: 'teaser',
* type: 'node--article',
* uuid
* }"
* />
*/
propsData: {
type: Object,
default: function () { return ({}); }
},
/**
* The module value.
*
* @type {(Array|Boolean|Date|Number|Object|String)}
* @model
*/
value: {
type: [Array, Boolean, Date, Number, Object, String],
default: null,
},
/**
* Wrapper element.
*
* @type {object}
* @default { component: 'div', propsData: {} }
*/
wrapper: {
type: [Object, Boolean],
default: function () { return ({
component: 'div',
propsData: {},
}); }
},
},
/**
* Vue.js Data object.
*
* @property {objects} components - The module and wrapper components settinsg.
* @property {object} model - The model object.
*/
data: function (ref) {
var value = ref.value;
return ({
component: {
is: undefined,
propsData: {},
},
model: value,
const DruxtNuxtModule = function(moduleOptions = {}) {
const options = {
...moduleOptions,
...(this.options || {}).druxt
};
this.addPlugin({
src: resolve(__dirname, "../nuxt/plugin.js"),
fileName: "druxt.js",
options
});
},
this.addPlugin({
src: resolve(__dirname, "../nuxt/store.js"),
fileName: "store/druxt.js",
options
});
this.options.store = true;
};
DruxtNuxtModule.meta = require("../package.json");
created: function created() {
this.setModuleComponent();
},
methods: {
/**
* Sets the module component and propsData.
*/
setModuleComponent: function setModuleComponent() {
var component = "Druxt" + (this.module.split('-').map(function (string) { return string.charAt(0).toUpperCase() + string.slice(1); }).join(''));
if (!this.$options.components[component]) {
return
}
// Set component data.
this.component.is = component;
this.component.propsData = this.propsData;
},
},
watch: {
model: function model() {
if (this.value !== this.model) {
this.$emit('input', this.model);
}
},
value: function value() {
if (this.value !== this.model) {
this.model = this.value;
}
class DruxtClient {
constructor(baseUrl, options = {}) {
if (!baseUrl) {
throw new Error("The 'baseUrl' parameter is required.");
}
},
render: function render(h) {
var component = h(this.component.is, {
props: Object.assign({}, {wrapper: this.inner},
this.component.propsData,
this.$attrs,
{value: this.model}),
ref: 'module',
});
if ((this.wrapper || {}).component) {
return h(this.wrapper.component, { props: this.wrapper.propsData }, [component])
let axiosSettings = { baseURL: baseUrl };
if (typeof options.axios === "object") {
axiosSettings = Object.assign(axiosSettings, options.axios);
delete options.axios;
}
return component
this.axios = axios.create(axiosSettings);
this.options = {
endpoint: "/jsonapi",
jsonapiResourceConfig: "jsonapi_resource_config--jsonapi_resource_config",
...options
};
}
};
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
addHeaders(headers) {
if (typeof headers === "undefined") {
return false;
}
// Vue.extend constructor export interop.
var options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
for (const name in headers) {
this.axios.defaults.headers.common[name] = headers[name];
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
buildQueryUrl(url, query) {
if (!query) {
return url;
}
var hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
if (typeof query === "string") {
return query.charAt(0) === "?" ? url + query : [url, query].join("?");
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
if (typeof query === "object" && typeof query.getQueryString === "function" && (query = query.getQueryString())) {
return [url, query].join("?");
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
var originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
if (typeof query === "object" && Object.keys(query).length) {
return [url, stringify(query)].join("?");
}
return script;
}
/* script */
var __vue_script__ = script;
/* template */
/* style */
var __vue_inject_styles__ = undefined;
/* scoped */
var __vue_scope_id__ = undefined;
/* module identifier */
var __vue_module_identifier__ = undefined;
/* functional template */
var __vue_is_functional_template__ = undefined;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__ = /*#__PURE__*/normalizeComponent(
{},
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);
//
//
//
//
//
//
/**
* The default Druxt module wrapper Vue.js component.
*
* This component is used by the Druxt component if an appropriate component can not be found
* for the specified module.
*
* @private
*/
var script$1 = {
name: 'DruxtWrapper'
};
/* script */
var __vue_script__$1 = script$1;
/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_vm._t("default")],2)};
var __vue_staticRenderFns__ = [];
/* style */
var __vue_inject_styles__$1 = undefined;
/* scoped */
var __vue_scope_id__$1 = undefined;
/* module identifier */
var __vue_module_identifier__$1 = undefined;
/* functional template */
var __vue_is_functional_template__$1 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$1 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__$1,
__vue_script__$1,
__vue_scope_id__$1,
__vue_is_functional_template__$1,
__vue_module_identifier__$1,
false,
undefined,
undefined,
undefined
);
/**
* Nuxt module function to install Druxt.
*
* @param {ModuleOptions} moduleOptions - DruxtJS module options.
*
* @example <caption>Nuxt configuration with module options</caption> @lang js
* module.exports = {
* modules: [
* ['druxt', { baseUrl: 'https://demo-api.druxtjs.org' }]
* ]
* }
*
* @example <caption>Nuxt configuration with root level options</caption> @lang js
* module.exports = {
* modules: [
* 'druxt'
* ],
* druxt: {
* baseUrl: 'https://demo-api.druxtjs.org'
* }
* }
*/
var DruxtNuxtModule = function (moduleOptions) {
if ( moduleOptions === void 0 ) moduleOptions = {};
var options = Object.assign({}, moduleOptions,
(this.options || {}).druxt);
// Add plugin.
this.addPlugin({
src: resolve(__dirname, '../nuxt/plugin.js'),
fileName: 'druxt.js',
options: options
});
// Add Vuex plugin.
this.addPlugin({
src: resolve(__dirname, '../nuxt/store.js'),
fileName: 'store/druxt.js',
options: options
});
// Enable Vuex Store.
this.options.store = true;
};
DruxtNuxtModule.meta = require('../package.json');
/**
* Module options object.
*
* @typedef {object} ModuleOptions
* @property {string} baseUrl - The Base URL of the Drupal JSON:API backend.
*/
/**
* Druxt JSON:API client.
*/
var DruxtClient = function DruxtClient(baseUrl, options) {
if ( options === void 0 ) options = {};
// Check for URL.
if (!baseUrl) {
throw new Error('The \'baseUrl\' parameter is required.')
return url;
}
checkPermissions(res) {
if (res.data.meta && res.data.meta.omitted) {
const permissions = {};
delete res.data.meta.omitted.links.help;
for (const key in res.data.meta.omitted.links) {
const link = res.data.meta.omitted.links[key];
const match = link.meta.detail.match(/'(.*?)'/);
if (match && match[1]) {
permissions[match[1]] = true;
}
}
if (Object.keys(permissions).length) {
throw new TypeError(`${res.data.meta.omitted.detail}
// Setup Axios.
var axiosSettings = { baseURL: baseUrl };
if (typeof options.axios === 'object') {
axiosSettings = Object.assign(axiosSettings, options.axios);
delete options.axios;
}
/**
* The Axios instance.
*
* @see {@link https://github.com/axios/axios#instance-methods}
* @type {object}
*/
this.axios = axios.create(axiosSettings);
/**
* Druxt base options.
* @type {object}
* @private
*/
this.options = Object.assign({}, {endpoint: '/jsonapi',
jsonapiResourceConfig: 'jsonapi_resource_config--jsonapi_resource_config'},
options);
};
/**
* Add headers to the Axios instance.
*
* @example @lang js
* this.$druxt.addHeaders({ 'Authorization': `Basic ${token}` })
*
* @param {object} headers - An object containing HTTP headers.
*/
DruxtClient.prototype.addHeaders = function addHeaders (headers) {
if (typeof headers === 'undefined') {
return false
}
for (var name in headers) {
this.axios.defaults.headers.common[name] = headers[name];
}
};
/**
* Build query URL.
*
* @example @lang js
* const query = new DrupalJsonApiParams()
* query.addFilter('status', '1')
* const queryUrl = this.$druxt.buildQueryUrl(resourceUrl, query)
*
* @param {string} url - The base query URL.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @return {string} The URL with query string.
*/
DruxtClient.prototype.buildQueryUrl = function buildQueryUrl (url, query) {
if (!query) {
return url
}
// If Query is string...
if (typeof query === 'string') {
return query.charAt(0) === '?' ? url + query : [url, query].join('?')
}
// If Query is object with 'getQueryString' function, (e.g., drupal-jsonapi-params)...
if (typeof query === 'object' && typeof query.getQueryString === 'function' && (query = query.getQueryString())) {
return [url, query].join('?')
}
// If query is object...
if (typeof query === 'object' && Object.keys(query).length) {
return [url, stringify(query)].join('?')
}
// Else...
return url
};
/**
* Check response for permissions.
*
* @todo - Move this to utils?
*
* @param {object} res - Axios GET request response object.
*
* @private
*/
DruxtClient.prototype.checkPermissions = function checkPermissions (res) {
// Error handling: Required permissions.
if (res.data.meta && res.data.meta.omitted) {
var permissions = {};
delete res.data.meta.omitted.links.help;
for (var key in res.data.meta.omitted.links) {
var link = res.data.meta.omitted.links[key];
var match = link.meta.detail.match(/'(.*?)'/);
if (match && match[1]) {
permissions[match[1]] = true;
Required permissions: ${Object.keys(permissions).join(", ")}.`);
}
}
if (Object.keys(permissions).length) {
throw new TypeError(((res.data.meta.omitted.detail) + "\n\n Required permissions: " + (Object.keys(permissions).join(', ')) + "."))
}
async getCollection(type, query) {
const { href } = await this.getIndex(type);
if (!href) {
return false;
}
const url = this.buildQueryUrl(href, query);
const res = await this.axios.get(url);
this.checkPermissions(res);
return res.data;
}
};
/**
* Get a collection of resources from the JSON:API server.
*
* @param {string} type - The JSON:API Resource type.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @returns {object} The JSON:API collection response.
*
* @example @lang js
* const collection = await this.$druxt.getCollection('node--recipe')
*/
DruxtClient.prototype.getCollection = async function getCollection (type, query) {
var ref = await this.getIndex(type);
var href = ref.href;
if (!href) {
return false
}
var url = this.buildQueryUrl(href, query);
var res = await this.axios.get(url);
this.checkPermissions(res);
return res.data
};
/**
* Get all resources of a collection.
*
* @param {string} type - The JSON:API Resource type.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @returns {object[]} An array of JSON:API collections.
*
* @example @lang js
* const collections = await this.$druxt.getCollectionAll('node--recipe', 'fields[node--recipe]=title')
*/
DruxtClient.prototype.getCollectionAll = async function getCollectionAll (type, query) {
var collections = [];
var res = await this.getCollection(type, query);
collections.push(res);
while (((res.links || {}).next || {}).href) {
query = res.links.next.href.split('?')[1];
res = await this.getCollection(type, query);
async getCollectionAll(type, query) {
const collections = [];
let res = await this.getCollection(type, query);
collections.push(res);
}
return collections
};
/**
* Get index of all available resources, or the optionally specified resource.
*
* @example @lang js
* const { href } = await this.$druxt.getIndex('node--article')
*
* @param {string} resource - (Optional) A specific resource to query.
*
* @returns {object} The resource index object or the specified resource.
*/
DruxtClient.prototype.getIndex = async function getIndex (resource) {
if (this.index && !resource) {
return this.index
}
if (this.index && resource) {
return this.index[resource] ? this.index[resource] : false
}
var index = await this.axios.get(this.options.endpoint);
this.index = index.data.links;
// Use JSON API resource config to decorate the index.
if (this.index[this.options.jsonapiResourceConfig]) {
var resources = await this.axios.get(this.index[this.options.jsonapiResourceConfig].href);
for (var resourceType in resources.data.data) {
var resource$1 = resources.data.data[resourceType];
var internal = resource$1.attributes.drupal_internal__id.split('--');
var item = {
resourceType: resource$1.attributes.resourceType,
entityType: internal[0],
bundle: internal[1],
resourceFields: resource$1.attributes.resourceFields
};
var id = [item.entityType, item.bundle].join('--');
this.index[id] = Object.assign({}, item,
this.index[id]);
while (((res.links || {}).next || {}).href) {
query = res.links.next.href.split("?")[1];
res = await this.getCollection(type, query);
collections.push(res);
}
return collections;
}
if (resource) {
return this.index[resource] ? this.index[resource] : false
}
return this.index
};
/**
* Get a JSON:API resource by type and ID.
*
* @example @lang js
* const data = await this.$druxt.getResource('node--article', id)
*
* @param {string} type - The JSON:API Resource type.
* @param {string} id - The Drupal resource UUID.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @returns {object} The JSON:API resource data.
*/
DruxtClient.prototype.getResource = async function getResource (type, id, query) {
if (!id || !type) {
return false
}
var ref = await this.getIndex(type);
var href = ref.href;
if (!href) {
href = this.options.endpoint + '/' + type.replace('--', '/');
}
var url = this.buildQueryUrl((href + "/" + id), query);
try {
var resource = await this.axios.get(url);
return resource.data
} catch (e) {
return false
}
};
/**
* DruxtClient options object.
*
* @typedef {object} DruxtClientOptions
*
* @param {object} [axios] - Axios instance settings.
* @param {string} [endpoint=jsonapi] - The JSON:API endpoint.
* @param {string} [jsonapiResourceConfig=jsonapi_resource_config--jsonapi_resource_config] -
* The JSON:API resource config type, used for [JSON:API Extras](https://www.drupal.org/project/jsonapi_extras) support.
*
* @see {@link https://github.com/axios/axios#request-config}
*
* @example @lang js
* {
* axios: {
* headers: { 'X-Custom-Header': true },
* },
* endpoint: 'api',
* }
*/
/**
* @typedef {string|object} DruxtClientQuery
*
* A correctly formatted JSON:API query string or object.
*
* @example
* page[limit]=5&page[offset]=5
*
* @example @lang js
* new DrupalJsonApiParams().addPageLimit(5)
*
* @see {@link https://www.npmjs.com/package/drupal-jsonapi-params}
*/
/**
* The DruxtModule base Vue.js component.
*
* Extend this component to build a Druxt module.
*
* @example @lang js
* import { DruxtModule } from 'druxt'
* export default {
* name: 'DruxtTestModule',
* extends: DruxtModule,
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
*/
var script$2 = {
components: { DruxtWrapper: __vue_component__$1 },
/** */
props: {
/**
* The module value.
*
* @type {(Array|Boolean|Date|Number|Object|String)}
* @model
*/
value: {
type: [Array, Boolean, Date, Number, Object, String],
default: null,
},
wrapper: {
type: Object,
default: function () { return ({
component: 'div',
propsData: {},
}); }
},
},
/**
* Loads the Druxt module data and applies a wrapper component as required.
*
* **Important:** If your component has an existing `fetch` method, you must manually invoke
* the `DruxtModule.fetch()` hook.
*
* @example @lang js <caption>Manually invoking DruxtModule.fetch().</caption>
* import { DruxtModule } from 'druxt'
* export default {
* name: 'DruxtTestModule',
* extends: DruxtModule,
* async fetch() {
* await DruxtModule.fetch.call(this)
* }
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
*/
fetch: async function fetch() {
if (!(this.$options || {}).druxt) {
return false
async getIndex(resource) {
if (this.index && !resource) {
return this.index;
}
// Build wrapper component object.
var options = this.getModuleComponents();
var component = {
is: (((options.filter(function (o) { return o.global; }) || [])[0] || {}).name || 'DruxtWrapper'),
options: options.map(function (o) { return o.name; }) || [],
};
// Get scoped slots.
component.slots = Object.keys(this.getScopedSlots());
// Get wrapper data.
var wrapperData = await this.getWrapperData(component.is);
component.settings = wrapperData.druxt || {};
// Build wrapper component propsData.
component = Object.assign({}, component, this.getModulePropsData(wrapperData.props));
// Set component data.
this.component = component;
},
/**
* @property {ComponentData} component - The wrapper component and propsData to be rendered.
* @property {object} model - The model object.
*/
data: function (ref) {
var value = ref.value;
return ({
component: {
$attrs: {},
is: 'DruxtWrapper',
options: [],
props: {},
propsData: {},
settings: {},
slots: [],
},
model: value,
});
},
/** */
methods: {
/**
* Get list of module wrapper components.
*
* @returns {Components}
*/
getModuleComponents: function getModuleComponents() {
var this$1 = this;
if (!(this.$options.druxt || {}).componentOptions) {
return []
}
var options = this.$options.druxt.componentOptions.call(this, this);
if (!options || !options.length) {
return []
}
// Build list of available components.
var components = [];
var loop = function () {
var variants = [];
components = components.concat( set.map(function (item) {
// Build array of name parts.
var parts = variants.length ? [].concat( variants[0].parts ) : [];
parts.push(pascalCase(splitByCase(item)));
// Convert parts into a pascalCase component name.
var name = pascalCase([this$1.$options.name ].concat( parts));
// Check if component is globally registered.
var global = !!this$1.$options.components[name];
// Store set variant data to be used in next set item.
variants.unshift({ global: global, name: name, parts: parts });
return { global: global, name: name, parts: parts }
}));
};
for (var set of options.filter(function (set) { return Array.isArray(set); })) loop();
// Filter unique components.
var unique = components.filter((function (s) { return function (o) { return !s.has(o.name) && s.add(o.name); }; })(new Set));
// Sort items by parts length.
var sorted = unique.sort(function (a, b) { return b.parts.length - a.parts.length; });
return sorted
},
/**
* Get module propsData via modules `druxt.propsData()` callback.
*
* @example @lang js
* {
* bar: 'foo',
* foo: 'bar',
* }
*
* @return {object}
*/
getModulePropsData: function getModulePropsData(wrapperProps) {
if ( wrapperProps === void 0 ) wrapperProps = {};
if (!(this.$options.druxt || {}).propsData) {
return {}
}
var propsData = this.$options.druxt.propsData.call(this, this);
// Props.
var props = {};
var propsKeys = Object.keys(wrapperProps).filter(function (i) { return Object.keys(propsData).includes(i); });
for (var key of propsKeys) {
props[key] = propsData[key];
}
// $attrs.
var $attrs = Object.assign({}, this.$attrs);
delete $attrs['data-fetch-key'];
var $attrsKeys = Object.keys(propsData).filter(function (i) { return !Object.keys(wrapperProps).includes(i); });
for (var key$1 of $attrsKeys) {
$attrs[key$1] = propsData[key$1];
}
return { $attrs: $attrs, props: props, propsData: propsData }
},
/**
* Gets a Druxt modules scoped slots, and if there's no default slots,
* provides a develop mode debug default or passes through to a
* default template.
*
* @return {object}
*/
getScopedSlots: function getScopedSlots() {
var this$1 = this;
var h = this.$createElement;
var scopedSlots = typeof (this.$options.druxt || {}).slots === 'function'
? this.$options.druxt.slots.call(this, h)
: {};
// Pass through default scoped slot if provided.
if (typeof this.$scopedSlots.default === 'function') {
scopedSlots.default = function (attrs) { return this$1.$scopedSlots.default(Object.assign({}, ((this$1.$options.druxt || {}).propsData || (function () {}))(this$1),
attrs)); };
}
// Provide debug data if Nuxt is running in dev mode.
if (!scopedSlots.default && this.$nuxt.context.isDev) {
scopedSlots.default = function () { return h(
'details',
{
style: {
border: '2px dashed lightgrey',
margin: '0.5em 0',
padding: '1em',
},
},
[
h('summary', [("[" + (this$1.$options._componentTag) + "] Missing default slot.")]),
h('label', ['Component options:', h('ul', this$1.component.options.map(function (s) { return h('li', [s]); }))]),
h('br'),
h('label', ['propsData:', h('pre', [h('code', [JSON.stringify(this$1.component.propsData, null, '\t')])])])
]
); };
}
return scopedSlots
},
/**
* Get wrapper component data.
*
* @param {string} component - The Wrapper component name.
*
* @return {WrapperData}
*/
getWrapperData: async function getWrapperData(component) {
var wrapperData = { druxt: {}, props: {} };
if (!this.$options.components[component]) {
return wrapperData
}
// Get data from resolved component.
if (this.$options.components[component].options) {
wrapperData = this.$options.components[component].options;
}
// Get data from unresolved component.
else if (typeof this.$options.components[component] === 'function' && this._init) {
wrapperData = (await this.$options.components[component].call(this)) || {};
}
var options = Vue.util.mergeOptions({}, wrapperData);
return {
druxt: options.druxt || {},
props: options.props || {},
}
if (this.index && resource) {
return this.index[resource] ? this.index[resource] : false;
}
},
watch: {
model: function model() {
if (this.component.props.value !== this.model) {
this.component.props.value = this.model;
// Only emit 'input' if using the default 'DruxtWrapper' component.
if (this.component.is === 'DruxtWrapper') {
this.$emit('input', this.model);
}
const index = await this.axios.get(this.options.endpoint);
this.index = index.data.links;
if (this.index[this.options.jsonapiResourceConfig]) {
const resources = await this.axios.get(this.index[this.options.jsonapiResourceConfig].href);
for (const resourceType in resources.data.data) {
const resource2 = resources.data.data[resourceType];
const internal = resource2.attributes.drupal_internal__id.split("--");
const item = {
resourceType: resource2.attributes.resourceType,
entityType: internal[0],
bundle: internal[1],
resourceFields: resource2.attributes.resourceFields
};
const id = [item.entityType, item.bundle].join("--");
this.index[id] = {
...item,
...this.index[id]
};
}
},
value: function value() {
if (this.value !== this.model) {
this.model = this.value;
}
}
},
render: function render(h) {
var self = this;
var wrapperData = {
class: this.wrapper.class || undefined,
style: this.wrapper.style || undefined,
props: this.wrapper.propsData,
};
// Return only wrapper if fetch state is still pending.
if (this.$fetchState.pending) {
return h(this.wrapper.component, wrapperData)
if (resource) {
return this.index[resource] ? this.index[resource] : false;
}
// Return wrapped component.
var attrs = Object.assign({}, this.component.$attrs, this.$attrs);
delete attrs['data-fetch-key'];
return h(this.wrapper.component, wrapperData, [
h(this.component.is, {
attrs: attrs,
on: {
input: function input(value) {
self.model = value;
self.$emit('input', value);
}
},
props: this.component.props,
ref: 'component',
scopedSlots: this.getScopedSlots(),
})
])
return this.index;
}
};
async getResource(type, id, query) {
if (!id || !type) {
return false;
}
let { href } = await this.getIndex(type);
if (!href) {
href = this.options.endpoint + "/" + type.replace("--", "/");
}
const url = this.buildQueryUrl(`${href}/${id}`, query);
try {
const resource = await this.axios.get(url);
return resource.data;
} catch (e) {
return false;
}
}
}
/**
* @typedef {object[]} Components
* @property {boolean} global - Component global registration state.
* @property {string} name - The component name.
* @property {string[]} parts - The component naming parts.
*
* @example @lang js
* [{
* global: true,
* pascal: 'DruxtTestModuleWrapper',
* parts: ['Wrapper'],
* }]
*/
/**
* @typedef {object} ComponentData
* @property {object} $attrs - propsData not registered by the Wrapper component.
* @property {string} is=DruxtWrapper - The Wrapper component name.
* @property {string[]} options - The Wrapper component options.
* @property {object} props - propsData registered by the Wrapper component.
* @property {object} propsData - The component propsData object.
* @property {object} settings - Druxt settings object provided by the Wrapper component.
*
* @example @lang js
* {
* $attrs: { bar: 'foo' },
* is: 'DruxtTestModuleWrapper',
* options: [
* 'DruxtTestModuleWrapper',
* ],
* props: { foo: 'bar' },
* propsData: {
* bar: 'foo',
* foo: 'bar',
* },
* settings: { fooBar: true },
* }
*/
/**
* @typedef {object} WrapperData
* @property {object} druxt - Druxt settings object for use by Druxt module.
* @property {object} props - Registered props oject.
*
* @example @lang js
* {
* druxt: { fooBar: true },
* props: {
* foo: {
* type: String,
* default: '',
* }
* }
* }
*/
/* script */
var __vue_script__$2 = script$2;
/* template */
/* style */
var __vue_inject_styles__$2 = undefined;
/* scoped */
var __vue_scope_id__$2 = undefined;
/* module identifier */
var __vue_module_identifier__$2 = undefined;
/* functional template */
var __vue_is_functional_template__$2 = undefined;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$2 = /*#__PURE__*/normalizeComponent(
{},
__vue_inject_styles__$2,
__vue_script__$2,
__vue_scope_id__$2,
__vue_is_functional_template__$2,
__vue_module_identifier__$2,
false,
undefined,
undefined,
undefined
);
var getDrupalJsonApiParams = function (query) {
const getDrupalJsonApiParams = (query) => {
return new DrupalJsonApiParams().initialize(query);
};
var dehydrateResources = function (ref) {
var commit = ref.commit;
var queryObject = ref.queryObject;
var resources = ref.resources;
return resources.map(function (data) {
// Generate a query link for included resources.
// This is used to determine if the resource is a partial.
var link = decodeURI(((data.links || {}).self || {}).href || '');
var href = typeof (queryObject.fields || {})[data.type] === 'string'
? [link.split('?')[0], ("fields[" + (data.type) + "]=" + (queryObject.fields[data.type]))].join('?')
: link;
// Commit the included resource.
commit('druxt/addResource', {
const dehydrateResources = ({ commit, queryObject, resources }) => {
return resources.map((data) => {
const link = decodeURI(((data.links || {}).self || {}).href || "");
const href = typeof (queryObject.fields || {})[data.type] === "string" ? [link.split("?")[0], `fields[${data.type}]=${queryObject.fields[data.type]}`].join("?") : link;
commit("druxt/addResource", {
resource: {
data: data,
links: { self: { href: href } },
data,
links: { self: { href } }
}
});
return { id: data.id, type: data.type }
})
return { id: data.id, type: data.type };
});
};
var DruxtStore = function (ref) {
var store = ref.store;
if (typeof store === 'undefined') {
throw new TypeError('Vuex store not found.')
const DruxtStore = ({ store }) => {
if (typeof store === "undefined") {
throw new TypeError("Vuex store not found.");
}
/**
* @namespace
*/
var namespace = 'druxt';
/**
* The DruxtStore Vuex module.
*
* Provides a Vuex state object, mutations and actions for interacting with the DruxtClient.
*
* @name druxt
* @module druxt
*/
var module = {
const namespace = "druxt";
const module = {
namespaced: true,
/**
* Vuex State object.
*
* @name state
* @type {object}
* @property {DruxtClientCollections} collections - JSON:API resource collections store.
* @property {object} resources - JSON:API resources store.
* @readonly
*/
state: function () { return ({
state: () => ({
collections: {},
resources: {}
}); },
/**
* Vuex Mutations.
*/
}),
mutations: {
/**
* @name addCollection
* @mutator {object} addCollection=collections Adds a JSON:API collection to the Vuex state object.
* @param {addCollectionContext} context
*
* @example @lang js
* this.$store.commit('druxt/addCollection', { collection, type, hash })
*/
addCollection: function addCollection (state, ref) {
var collection = ref.collection;
var type = ref.type;
var hash = ref.hash;
if (!state.collections[type]) { Vue.set(state.collections, type, {}); }
// Parse the query.
var link = decodeURI((((collection || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Store and dehydrate collection resources.
collection.data = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.data });
// Extract and store included resources.
addCollection(state, { collection, type, hash }) {
if (!state.collections[type])
Vue.set(state.collections, type, {});
const link = decodeURI((((collection || {}).links || {}).self || {}).href || "");
const query = link.split("?")[1] || "";
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
collection.data = dehydrateResources({ commit: this.commit, queryObject, resources: collection.data });
if (collection.included) {
collection.included = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.included });
collection.included = dehydrateResources({ commit: this.commit, queryObject, resources: collection.included });
delete collection.included;
}
// Recursively merge new collection data into stored collection.
collection = merge(state.collections[type][hash] || {}, collection, { arrayMerge: function (dst, src) { return src; } });
collection = merge(state.collections[type][hash] || {}, collection, { arrayMerge: (dst, src) => src });
Vue.set(state.collections[type], hash, collection);
},
/**
* @name addResource
* @mutator {object} addResource=resources Adds a JSON:API resource to the Vuex state object.
* @param {addResourceContext} context
*
* @example @lang js
* this.$store.commit('druxt/addResource', { resource })
*/
addResource: function addResource (state, ref) {
var resource = ref.resource;
var hash = ref.hash;
addResource(state, { resource, hash }) {
if (hash) {
console.warn('[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/guide/deprecations.html#druxtstore-addresource-hash');
console.warn("[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/guide/deprecations.html#druxtstore-addresource-hash");
}
var ref$1 = (resource || {}).data || {};
var id = ref$1.id;
var type = ref$1.type;
const { id, type } = (resource || {}).data || {};
if (!id || !type) {
// @TODO - Error?
return
return;
}
// Parse the query.
var link = decodeURI((((resource || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Add cache flag to resource.
var flag = typeof (queryObject.fields || {})[((resource || {}).data || {}).type] === 'string' ? '_druxt_partial' : '_druxt_full';
const link = decodeURI((((resource || {}).links || {}).self || {}).href || "");
const query = link.split("?")[1] || "";
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
const flag = typeof (queryObject.fields || {})[((resource || {}).data || {}).type] === "string" ? "_druxt_partial" : "_druxt_full";
resource[flag] = Date.now();
// Ensure Resource type array is reactive.
if (!state.resources[type]) { Vue.set(state.resources, type, {}); }
// Extract and store included data.
if (!state.resources[type])
Vue.set(state.resources, type, {});
if (resource.included) {
dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: resource.included });
dehydrateResources({ commit: this.commit, queryObject, resources: resource.included });
delete resource.included;
}
// Recursively merge new resource data into stored resource.
resource = merge(state.resources[type][id] || {}, resource, { arrayMerge: function (dst, src) { return src; } });
resource = merge(state.resources[type][id] || {}, resource, { arrayMerge: (dst, src) => src });
Vue.set(state.resources[type], id, resource);
},
}
},
/**
* Vuex Actions.
*/
actions: {
/**
* Get collection of resources.
*
* @name getCollection
* @action getCollection
* @param {getCollectionContext} context
* @return {object[]} Array of Drupal JSON:API resource data.
*
* @example @lang js
* // Load all currently published Articles.
* const resources = await this.$store.dispatch('druxt/getCollection', {
* type: 'node--article',
* query: new DrupalJsonApiParams().addFilter('status', '1'),
* })
*/
getCollection: async function getCollection (ref, ref$1) {
var commit = ref.commit;
var state = ref.state;
var type = ref$1.type;
var query = ref$1.query;
// Generate a hash using query data excluding the 'fields' and 'include' data.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
var hash = query ? md5(JSON.stringify(Object.assign({}, queryObject, {fields: {}, include: []}))) : '_default';
// If collection hash exists, re-hydrate and return the data.
async getCollection({ commit, state }, { type, query }) {
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
const hash = query ? md5(JSON.stringify({ ...queryObject, fields: {}, include: [] })) : "_default";
if ((state.collections[type] || {})[hash]) {
return Object.assign({}, state.collections[type][hash],
// Hydrate resource data.
{data: state.collections[type][hash].data.map(function (o) { return (state.resources[o.type][o.id] || {}).data; })})
return {
...state.collections[type][hash],
data: state.collections[type][hash].data.map((o) => (state.resources[o.type][o.id] || {}).data)
};
}
// Get the collection using the DruxtClient instance.
var collection = await this.$druxt.getCollection(type, query);
// Store the collection in the DruxtStore.
commit('addCollection', { collection: Object.assign({}, collection), type: type, hash: hash });
return collection
const collection = await this.$druxt.getCollection(type, query);
commit("addCollection", { collection: { ...collection }, type, hash });
return collection;
},
/**
* Get JSON:API Resource.
*
* - Executes query against Drupal JSON:API.
* - Caches result in the Vuex store.
* - Returns cached result from Vuex store when available.
*
* @name getResource
* @action getResource=resources
* @param {getResourceContext} context
* @return {object} The Drupal JSON:API resource.
*
* @example @lang js
* const resource = await this.$store.dispatch('druxt/getResource', { type: 'node--article', id })
*/
getResource: async function getResource (ref, ref$1) {
var commit = ref.commit;
var dispatch = ref.dispatch;
var state = ref.state;
var type = ref$1.type;
var id = ref$1.id;
var query = ref$1.query;
// Get the resource from the store if it's avaialble.
var storedResource = (state.resources[type] || {})[id] ?
Object.assign({}, state.resources[type][id])
: null;
// Parse the query.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
queryObject.include = Array.isArray(queryObject.include)
? queryObject.include.join(',')
: queryObject.include;
// Ensure that includes are in the fields filter.
if (queryObject.include && typeof (queryObject.fields || {})[type] === 'string') {
var fields$1 = queryObject.fields[type].split(',').filter(function (s) { return s; });
var includes = queryObject.include.split(',').filter(function (s) { return s && !s.includes('.'); });
queryObject.fields[type] = Array.from(
new Set(fields$1.concat( includes))
).filter(function (s) { return s; }).join(',');
async getResource({ commit, dispatch, state }, { type, id, query }) {
const storedResource = (state.resources[type] || {})[id] ? { ...state.resources[type][id] } : null;
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
queryObject.include = Array.isArray(queryObject.include) ? queryObject.include.join(",") : queryObject.include;
if (queryObject.include && typeof (queryObject.fields || {})[type] === "string") {
const fields2 = queryObject.fields[type].split(",").filter((s) => s);
const includes = queryObject.include.split(",").filter((s) => s && !s.includes("."));
queryObject.fields[type] = Array.from(new Set([...fields2, ...includes])).filter((s) => s).join(",");
}
// Hydrate included data based on the include query.
var included = [];
let included = [];
if (queryObject.include && storedResource) {
// Request included resources from druxt/getResource.
var resources =
await Promise.all(queryObject.include.split(',')
.filter(function (s) { return Object.keys((storedResource.data.relationships || {})).includes(s); })
.map(function (key) {
var ref = storedResource.data.relationships[key];
var data = ref.data;
data = Array.isArray(data) ? data : [data];
// Get any sub-includes, e.g., `media,media.image` becomes `image`.
var include = queryObject.include.split(',')
.filter(function (s) { return s.startsWith((key + ".")); })
.map(function (s) { return s.slice(key.length + 1); })
.join(',');
return data.filter(function (o) { return typeof o === 'object' && o; }).map(function (o) {
return dispatch('getResource', {
type: o.type,
id: o.id,
query: Object.assign({}, queryObject, {include: include}),
})
})
})
.flat()
);
// Merge all nested, included resources.
for (var include of resources) {
included = included.concat( [include.data], include.included || []);
const resources = await Promise.all(queryObject.include.split(",").filter((s) => Object.keys(storedResource.data.relationships || {}).includes(s)).map((key) => {
let { data } = storedResource.data.relationships[key];
data = Array.isArray(data) ? data : [data];
const include = queryObject.include.split(",").filter((s) => s.startsWith(`${key}.`)).map((s) => s.slice(key.length + 1)).join(",");
return data.filter((o) => typeof o === "object" && o).map((o) => {
return dispatch("getResource", {
type: o.type,
id: o.id,
query: { ...queryObject, include }
});
});
}).flat());
for (const include of resources) {
included = [...included, include.data, ...include.included || []];
}
storedResource.included = included;
}
// Return if we have the full resource.
if ((storedResource || {})._druxt_full) {
return storedResource
return storedResource;
}
var isFull = typeof (queryObject.fields || {})[type] !== 'string';
// Determine if we have all the requested field data.
var fields = isFull ? true : (queryObject.fields || {})[type];
const isFull = typeof (queryObject.fields || {})[type] !== "string";
let fields = isFull ? true : (queryObject.fields || {})[type];
if (storedResource && !isFull && fields) {
var queryFields = fields.split(',');
var resourceFields = Object.keys(((storedResource || {}).data || {}).attributes || {}).concat( Object.keys(((storedResource || {}).data || {}).relationships || {}) );
var missingFields = queryFields.filter(function (key) { return !resourceFields.includes(key); });
const queryFields = fields.split(",");
const resourceFields = [
...Object.keys(((storedResource || {}).data || {}).attributes || {}),
...Object.keys(((storedResource || {}).data || {}).relationships || {})
];
const missingFields = queryFields.filter((key) => !resourceFields.includes(key));
fields = !!missingFields.length;
// Modify query to load additional fields, if required.
queryObject.fields[type] = (missingFields || []).join(',') || undefined;
queryObject.fields[type] = (missingFields || []).join(",") || void 0;
}
// Request the resource from the DruxtClient if required.
var resource;
let resource;
if (!storedResource || fields) {
resource = await this.$druxt.getResource(type, id, getDrupalJsonApiParams(queryObject));
commit('addResource', { resource: Object.assign({}, resource) });
commit("addResource", { resource: { ...resource } });
}
// Build resource to be returned.
var result = Object.assign({}, (state.resources[type] || {})[id]);
// Merge included resources into resource.
const result = { ...(state.resources[type] || {})[id] };
if (queryObject.include && ((resource || {}).included || (storedResource || {}).included)) {
included = ( (resource || {}).included || [] ).concat( (storedResource || {}).included || [] );
result.included = Array.from(new Set(included.filter(function (o) { return (o || {}).id; }).map(function (o) { return o.id; })))
.map(function (id) { return included.find(function (o) { return o.id === id; }); });
included = [
...(resource || {}).included || [],
...(storedResource || {}).included || []
];
result.included = Array.from(new Set(included.filter((o) => (o || {}).id).map((o) => o.id))).map((id2) => included.find((o) => o.id === id2));
}
return result
},
return result;
}
}
};
store.registerModule(namespace, module, {

@@ -1426,260 +302,53 @@ preserveState: Boolean(store.state[namespace])

/**
* Parameters for the `addCollection` mutation.
*
* @typedef {object} addCollectionContext
*
* @param {object} collection - A collection of JSON:API resources.
* @param {string} type - The JSON:API collection resource type.
* @param {string} hash - An md5 hash of the query string.
*
* @example @lang js
* {
* collection: {
* jsonapi: {},
* data: [{}],
* links: {}
* },
* type: 'node--page',
* hash: '_default'
* }
*/
/**
* Parameters for the `addResource` mutation.
*
* @typedef {object} addResourceContext
*
* @param {object} resource - The JSON:API resource.
*
* @example @lang js
* {
* resource: {
* jsonapi: {},
* data: {},
* links: {}
* },
* }
*/
/**
* Parameters for the `getCollection` action.
*
* @typedef {object} getCollectionContext
*
* @param {string} type - The JSON:API collection resource type.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @example @lang js
* {
* type: 'node--page',
* query: new DrupalJsonApiParams().addFilter('status', '1')
* }
*/
/**
* Parameters for the `getResource` action.
*
* @typedef {object} getResourceContext
*
* @param {string} type - The JSON:API Resource type.
* @param {string} id - The Drupal resource UUID.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @example @lang js
* {
* type: 'node--page',
* id: 'd8dfd355-7f2f-4fc3-a149-288e4e293bdd'
* }
*/
/**
* @typedef {string|object} DruxtClientQuery
*
* A correctly formatted JSON:API query string or object.
*
* @example
* page[limit]=5&page[offset]=5
*
* @example @lang js
* new DrupalJsonApiParams().addPageLimit(5)
*
* @see {@link https://www.npmjs.com/package/drupal-jsonapi-params}
*/
/**
* Druxt utility class.
*
* @deprecated
* @private
*/
var DruxtClass = function DruxtClass() {};
/**
* Get component data from available options.
*
* @param {object} vm - The DruxtJS module Vue.js component.
* @param {string[]} options - The component naming options.
* @param {boolean} [all=false] - Returns all options if true, else only globally registered options.
* @param {string} [prefix] - A string to prefix all components.
*
* @returns {WrapperComponents}
*/
DruxtClass.prototype.getComponents = function getComponents (vm, options, all, prefix) {
if ( all === void 0 ) all = false;
var results = [];
var unique = {};
options
// Filter out incorrectly typed items.
.filter(function (item) { return Array.isArray(item); })
// Process each item.
.map(function (item) {
var variants = [];
item.map(function (string) {
var parts = variants.length ? [].concat( variants[0].parts ) : [];
class DruxtClass {
constructor() {
}
getComponents(vm, options, all = false, prefix) {
const results = [];
const unique = {};
options.filter((item) => Array.isArray(item)).map((item) => {
const variants = [];
item.map((string) => {
const parts = variants.length ? [...variants[0].parts] : [];
parts.push(string);
var clone = [].concat( parts );
// Attach prefix as required.
if (typeof prefix !== 'string' && (prefix !== false || typeof prefix === 'undefined') && ((vm || {}).$options || {}).name) {
prefix = vm.$options.name.match(/[A-Z][a-z]+/g).map(function (word) { return word.toLowerCase(); }).join('-');
const clone = [...parts];
if (typeof prefix !== "string" && (prefix !== false || typeof prefix === "undefined") && ((vm || {}).$options || {}).name) {
prefix = vm.$options.name.match(/[A-Z][a-z]+/g).map((word) => word.toLowerCase()).join("-");
}
if (prefix) {
clone.unshift(prefix);
}
// Generate component name values.
var kebab = clone.map(function (string) { return string.toLowerCase().replace(/--|_/g, '-'); }).join('-');
var pascal = kebab.replace(/((\b|[^a-zA-Z0-9]+)[a-zA-Z0-9])/gi, function (match, p1, p2) { return match.toUpperCase().replace(p2, ''); });
// Check if component is globally registered.
var global = false;
for (var name of [kebab, pascal]) {
if (typeof (((vm || {}).$options || {}).components || {})[name] !== 'undefined') {
const kebab = clone.map((string2) => string2.toLowerCase().replace(/--|_/g, "-")).join("-");
const pascal = kebab.replace(/((\b|[^a-zA-Z0-9]+)[a-zA-Z0-9])/gi, (match, p1, p2) => match.toUpperCase().replace(p2, ""));
let global = false;
for (const name of [kebab, pascal]) {
if (typeof (((vm || {}).$options || {}).components || {})[name] !== "undefined") {
global = true;
break
break;
}
}
variants.unshift({ global: global, kebab: kebab, parts: parts, pascal: pascal, prefix: prefix });
variants.unshift({ global, kebab, parts, pascal, prefix });
});
// Add variants to results.
variants.map(function (variant) {
// Ensure unique results.
variants.map((variant) => {
if (unique[variant.pascal]) {
return
return;
}
unique[variant.pascal] = true;
results.push(variant);
});
});
// Return globally registered components or all.
return results
.filter(function (option) { return option.global || !!all; })
.sort(function (a, b) { return b.parts.length - a.parts.length; })
};
/**
* Get the Druxt module data from the referenced component.
*
* @returns {ModuleData}
*/
DruxtClass.prototype.getModuleData = async function getModuleData (vm) {
if (typeof ((vm || {}).$options || {}).druxt !== 'function') {
return false
return results.filter((option) => option.global || !!all).sort((a, b) => b.parts.length - a.parts.length);
}
var moduleData = await vm.$options.druxt({ vm: vm });
if ((vm.$options || {}).name) {
moduleData.name = vm.$options.name.match(/[A-Z][a-z]+/g).map(function (word) { return word.toLowerCase(); }).join('-');
}
return moduleData
};
/**
* @name DruxtComponentMixin
* @deprecated
* @private
*/
var DruxtComponentMixin = {
components: { DruxtWrapper: __vue_component__$1 },
/**
* @property {Component} component - The wrapper component and propsData to be rendered.
*/
data: function () { return ({
component: {
is: 'DruxtWrapper',
options: [],
propsData: {},
},
}); },
props: {
wrapper: {
type: Object,
default: function () { return ({
component: 'div',
propsData: {},
}); }
async getModuleData(vm) {
if (typeof ((vm || {}).$options || {}).druxt !== "function") {
return false;
}
},
/**
* The Nuxt Fetch hook.
*
* Loads the Druxt module data and applies a wrapper component as required.
*
* **Important:** If your component has an existing `fetch` method, you must manually invoke
* the `DruxtComponentMixin.fetch()` hook.
*
* @see {@link https://nuxtjs.org/api/pages-fetch/}
*
* @example @lang vue <caption>Manually invoking DruxtComponentMixin.fetch().</caption>
* <script>
* import { DruxtComponentMixin } from 'druxt'
* export default {
* mixins: [DruxtComponentMixin],
*
* async fetch {
* await DruxtComponentMixin.fetch.call(this)
* }
* }
* </script>
*/
fetch: async function fetch() {
console.warn('DruxtComponentMixin is deprecated in favour of DruxtModule.');
// @todo - check for this.$druxt plugin.
var druxt = new DruxtClass();
var moduleData = await druxt.getModuleData(this);
this.component.propsData = moduleData.propsData || {};
if (!moduleData.componentOptions) {
return
const moduleData = await vm.$options.druxt({ vm });
if ((vm.$options || {}).name) {
moduleData.name = vm.$options.name.match(/[A-Z][a-z]+/g).map((word) => word.toLowerCase()).join("-");
}
return moduleData;
}
}
var options = druxt.getComponents(this, moduleData.componentOptions, true);
this.component.options = options.map(function (item) { return item.pascal; });
var available = options.filter(function (item) { return item.global; });
if (!available.length) {
return
}
this.component.is = available[0].pascal;
},
};
export default DruxtNuxtModule;
export { __vue_component__ as Druxt, DruxtClass, DruxtClient, DruxtComponentMixin, __vue_component__$2 as DruxtModule, DruxtStore, __vue_component__$1 as DruxtWrapper };
export { DruxtClass, DruxtClient, DruxtStore, DruxtNuxtModule as default };

@@ -1,1392 +0,308 @@

'use strict';Object.defineProperty(exports,'__esModule',{value:true});function _interopDefault(e){return(e&&(typeof e==='object')&&'default'in e)?e['default']:e}var path=require('path'),axios=_interopDefault(require('axios')),querystring=require('querystring'),scule=require('scule'),Vue=_interopDefault(require('vue')),merge=_interopDefault(require('deepmerge')),md5=_interopDefault(require('md5')),drupalJsonapiParams=require('drupal-jsonapi-params');/**
* The Vue.js Druxt component.
*
* @example @lang vue
* <Druxt
* :module="module"
* :props-data="propsData"
* :wrapper="{
* component,
* propsData: {}
* }"
* />
*/
var script = {
name: 'Druxt',
'use strict';
/**
* Vue.js Props.
*/
props: {
/**
* Inner element.
*
* @type {object}
* @default { component: 'div', propsData: {} }
*/
inner: {
type: [Object, Boolean],
default: function () { return ({
component: 'div',
propsData: {},
}); }
},
Object.defineProperty(exports, '__esModule', { value: true });
/**
* The DruxtJS module to render.
*
* @type {string}
*
* @example @lang vue <caption>Using the [DruxtJS Site module](https://site.druxtjs.org).</caption>
* <Druxt module="site" />
*/
module: {
type: String,
required: true,
},
const path = require('path');
const axios = require('axios');
const querystring = require('querystring');
const merge = require('deepmerge');
const md5 = require('md5');
const Vue = require('vue');
const drupalJsonapiParams = require('drupal-jsonapi-params');
/**
* Props data to bind to the specified DruxtJS module.
*
* @type {object}
*
* @example @lang vue <caption>Using the [DruxtJS Entity module](https://entity.druxtjs.org) to render a 'node--article' resource.</caption>
* <Druxt
* module="entity"
* :props-data="{
* mode: 'teaser',
* type: 'node--article',
* uuid
* }"
* />
*/
propsData: {
type: Object,
default: function () { return ({}); }
},
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
/**
* The module value.
*
* @type {(Array|Boolean|Date|Number|Object|String)}
* @model
*/
value: {
type: [Array, Boolean, Date, Number, Object, String],
default: null,
},
const axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
const merge__default = /*#__PURE__*/_interopDefaultLegacy(merge);
const md5__default = /*#__PURE__*/_interopDefaultLegacy(md5);
const Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue);
/**
* Wrapper element.
*
* @type {object}
* @default { component: 'div', propsData: {} }
*/
wrapper: {
type: [Object, Boolean],
default: function () { return ({
component: 'div',
propsData: {},
}); }
},
},
/**
* Vue.js Data object.
*
* @property {objects} components - The module and wrapper components settinsg.
* @property {object} model - The model object.
*/
data: function (ref) {
var value = ref.value;
return ({
component: {
is: undefined,
propsData: {},
},
model: value,
const DruxtNuxtModule = function(moduleOptions = {}) {
const options = {
...moduleOptions,
...(this.options || {}).druxt
};
this.addPlugin({
src: path.resolve(__dirname, "../nuxt/plugin.js"),
fileName: "druxt.js",
options
});
},
this.addPlugin({
src: path.resolve(__dirname, "../nuxt/store.js"),
fileName: "store/druxt.js",
options
});
this.options.store = true;
};
DruxtNuxtModule.meta = require("../package.json");
created: function created() {
this.setModuleComponent();
},
methods: {
/**
* Sets the module component and propsData.
*/
setModuleComponent: function setModuleComponent() {
var component = "Druxt" + (this.module.split('-').map(function (string) { return string.charAt(0).toUpperCase() + string.slice(1); }).join(''));
if (!this.$options.components[component]) {
return
}
// Set component data.
this.component.is = component;
this.component.propsData = this.propsData;
},
},
watch: {
model: function model() {
if (this.value !== this.model) {
this.$emit('input', this.model);
}
},
value: function value() {
if (this.value !== this.model) {
this.model = this.value;
}
class DruxtClient {
constructor(baseUrl, options = {}) {
if (!baseUrl) {
throw new Error("The 'baseUrl' parameter is required.");
}
},
render: function render(h) {
var component = h(this.component.is, {
props: Object.assign({}, {wrapper: this.inner},
this.component.propsData,
this.$attrs,
{value: this.model}),
ref: 'module',
});
if ((this.wrapper || {}).component) {
return h(this.wrapper.component, { props: this.wrapper.propsData }, [component])
let axiosSettings = { baseURL: baseUrl };
if (typeof options.axios === "object") {
axiosSettings = Object.assign(axiosSettings, options.axios);
delete options.axios;
}
return component
this.axios = axios__default['default'].create(axiosSettings);
this.options = {
endpoint: "/jsonapi",
jsonapiResourceConfig: "jsonapi_resource_config--jsonapi_resource_config",
...options
};
}
};function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
addHeaders(headers) {
if (typeof headers === "undefined") {
return false;
}
// Vue.extend constructor export interop.
var options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
for (const name in headers) {
this.axios.defaults.headers.common[name] = headers[name];
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
buildQueryUrl(url, query) {
if (!query) {
return url;
}
var hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
if (typeof query === "string") {
return query.charAt(0) === "?" ? url + query : [url, query].join("?");
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
if (typeof query === "object" && typeof query.getQueryString === "function" && (query = query.getQueryString())) {
return [url, query].join("?");
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
var originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
if (typeof query === "object" && Object.keys(query).length) {
return [url, querystring.stringify(query)].join("?");
}
return script;
}/* script */
var __vue_script__ = script;
/* template */
/* style */
var __vue_inject_styles__ = undefined;
/* scoped */
var __vue_scope_id__ = undefined;
/* module identifier */
var __vue_module_identifier__ = "data-v-9ca6675a";
/* functional template */
var __vue_is_functional_template__ = undefined;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__ = /*#__PURE__*/normalizeComponent(
{},
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);//
//
//
//
//
//
/**
* The default Druxt module wrapper Vue.js component.
*
* This component is used by the Druxt component if an appropriate component can not be found
* for the specified module.
*
* @private
*/
var script$1 = {
name: 'DruxtWrapper'
};/* script */
var __vue_script__$1 = script$1;
/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_vm._t("default")],2)};
var __vue_staticRenderFns__ = [];
/* style */
var __vue_inject_styles__$1 = undefined;
/* scoped */
var __vue_scope_id__$1 = undefined;
/* module identifier */
var __vue_module_identifier__$1 = "data-v-35409ca9";
/* functional template */
var __vue_is_functional_template__$1 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$1 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__$1,
__vue_script__$1,
__vue_scope_id__$1,
__vue_is_functional_template__$1,
__vue_module_identifier__$1,
false,
undefined,
undefined,
undefined
);/**
* Nuxt module function to install Druxt.
*
* @param {ModuleOptions} moduleOptions - DruxtJS module options.
*
* @example <caption>Nuxt configuration with module options</caption> @lang js
* module.exports = {
* modules: [
* ['druxt', { baseUrl: 'https://demo-api.druxtjs.org' }]
* ]
* }
*
* @example <caption>Nuxt configuration with root level options</caption> @lang js
* module.exports = {
* modules: [
* 'druxt'
* ],
* druxt: {
* baseUrl: 'https://demo-api.druxtjs.org'
* }
* }
*/
var DruxtNuxtModule = function (moduleOptions) {
if ( moduleOptions === void 0 ) moduleOptions = {};
var options = Object.assign({}, moduleOptions,
(this.options || {}).druxt);
// Add plugin.
this.addPlugin({
src: path.resolve(__dirname, '../nuxt/plugin.js'),
fileName: 'druxt.js',
options: options
});
// Add Vuex plugin.
this.addPlugin({
src: path.resolve(__dirname, '../nuxt/store.js'),
fileName: 'store/druxt.js',
options: options
});
// Enable Vuex Store.
this.options.store = true;
};
DruxtNuxtModule.meta = require('../package.json');
/**
* Module options object.
*
* @typedef {object} ModuleOptions
* @property {string} baseUrl - The Base URL of the Drupal JSON:API backend.
*//**
* Druxt JSON:API client.
*/
var DruxtClient = function DruxtClient(baseUrl, options) {
if ( options === void 0 ) options = {};
// Check for URL.
if (!baseUrl) {
throw new Error('The \'baseUrl\' parameter is required.')
return url;
}
checkPermissions(res) {
if (res.data.meta && res.data.meta.omitted) {
const permissions = {};
delete res.data.meta.omitted.links.help;
for (const key in res.data.meta.omitted.links) {
const link = res.data.meta.omitted.links[key];
const match = link.meta.detail.match(/'(.*?)'/);
if (match && match[1]) {
permissions[match[1]] = true;
}
}
if (Object.keys(permissions).length) {
throw new TypeError(`${res.data.meta.omitted.detail}
// Setup Axios.
var axiosSettings = { baseURL: baseUrl };
if (typeof options.axios === 'object') {
axiosSettings = Object.assign(axiosSettings, options.axios);
delete options.axios;
}
/**
* The Axios instance.
*
* @see {@link https://github.com/axios/axios#instance-methods}
* @type {object}
*/
this.axios = axios.create(axiosSettings);
/**
* Druxt base options.
* @type {object}
* @private
*/
this.options = Object.assign({}, {endpoint: '/jsonapi',
jsonapiResourceConfig: 'jsonapi_resource_config--jsonapi_resource_config'},
options);
};
/**
* Add headers to the Axios instance.
*
* @example @lang js
* this.$druxt.addHeaders({ 'Authorization': `Basic ${token}` })
*
* @param {object} headers - An object containing HTTP headers.
*/
DruxtClient.prototype.addHeaders = function addHeaders (headers) {
if (typeof headers === 'undefined') {
return false
}
for (var name in headers) {
this.axios.defaults.headers.common[name] = headers[name];
}
};
/**
* Build query URL.
*
* @example @lang js
* const query = new DrupalJsonApiParams()
* query.addFilter('status', '1')
* const queryUrl = this.$druxt.buildQueryUrl(resourceUrl, query)
*
* @param {string} url - The base query URL.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @return {string} The URL with query string.
*/
DruxtClient.prototype.buildQueryUrl = function buildQueryUrl (url, query) {
if (!query) {
return url
}
// If Query is string...
if (typeof query === 'string') {
return query.charAt(0) === '?' ? url + query : [url, query].join('?')
}
// If Query is object with 'getQueryString' function, (e.g., drupal-jsonapi-params)...
if (typeof query === 'object' && typeof query.getQueryString === 'function' && (query = query.getQueryString())) {
return [url, query].join('?')
}
// If query is object...
if (typeof query === 'object' && Object.keys(query).length) {
return [url, querystring.stringify(query)].join('?')
}
// Else...
return url
};
/**
* Check response for permissions.
*
* @todo - Move this to utils?
*
* @param {object} res - Axios GET request response object.
*
* @private
*/
DruxtClient.prototype.checkPermissions = function checkPermissions (res) {
// Error handling: Required permissions.
if (res.data.meta && res.data.meta.omitted) {
var permissions = {};
delete res.data.meta.omitted.links.help;
for (var key in res.data.meta.omitted.links) {
var link = res.data.meta.omitted.links[key];
var match = link.meta.detail.match(/'(.*?)'/);
if (match && match[1]) {
permissions[match[1]] = true;
Required permissions: ${Object.keys(permissions).join(", ")}.`);
}
}
if (Object.keys(permissions).length) {
throw new TypeError(((res.data.meta.omitted.detail) + "\n\n Required permissions: " + (Object.keys(permissions).join(', ')) + "."))
}
async getCollection(type, query) {
const { href } = await this.getIndex(type);
if (!href) {
return false;
}
const url = this.buildQueryUrl(href, query);
const res = await this.axios.get(url);
this.checkPermissions(res);
return res.data;
}
};
/**
* Get a collection of resources from the JSON:API server.
*
* @param {string} type - The JSON:API Resource type.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @returns {object} The JSON:API collection response.
*
* @example @lang js
* const collection = await this.$druxt.getCollection('node--recipe')
*/
DruxtClient.prototype.getCollection = async function getCollection (type, query) {
var ref = await this.getIndex(type);
var href = ref.href;
if (!href) {
return false
}
var url = this.buildQueryUrl(href, query);
var res = await this.axios.get(url);
this.checkPermissions(res);
return res.data
};
/**
* Get all resources of a collection.
*
* @param {string} type - The JSON:API Resource type.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @returns {object[]} An array of JSON:API collections.
*
* @example @lang js
* const collections = await this.$druxt.getCollectionAll('node--recipe', 'fields[node--recipe]=title')
*/
DruxtClient.prototype.getCollectionAll = async function getCollectionAll (type, query) {
var collections = [];
var res = await this.getCollection(type, query);
collections.push(res);
while (((res.links || {}).next || {}).href) {
query = res.links.next.href.split('?')[1];
res = await this.getCollection(type, query);
async getCollectionAll(type, query) {
const collections = [];
let res = await this.getCollection(type, query);
collections.push(res);
}
return collections
};
/**
* Get index of all available resources, or the optionally specified resource.
*
* @example @lang js
* const { href } = await this.$druxt.getIndex('node--article')
*
* @param {string} resource - (Optional) A specific resource to query.
*
* @returns {object} The resource index object or the specified resource.
*/
DruxtClient.prototype.getIndex = async function getIndex (resource) {
if (this.index && !resource) {
return this.index
}
if (this.index && resource) {
return this.index[resource] ? this.index[resource] : false
}
var index = await this.axios.get(this.options.endpoint);
this.index = index.data.links;
// Use JSON API resource config to decorate the index.
if (this.index[this.options.jsonapiResourceConfig]) {
var resources = await this.axios.get(this.index[this.options.jsonapiResourceConfig].href);
for (var resourceType in resources.data.data) {
var resource$1 = resources.data.data[resourceType];
var internal = resource$1.attributes.drupal_internal__id.split('--');
var item = {
resourceType: resource$1.attributes.resourceType,
entityType: internal[0],
bundle: internal[1],
resourceFields: resource$1.attributes.resourceFields
};
var id = [item.entityType, item.bundle].join('--');
this.index[id] = Object.assign({}, item,
this.index[id]);
while (((res.links || {}).next || {}).href) {
query = res.links.next.href.split("?")[1];
res = await this.getCollection(type, query);
collections.push(res);
}
return collections;
}
if (resource) {
return this.index[resource] ? this.index[resource] : false
}
return this.index
};
/**
* Get a JSON:API resource by type and ID.
*
* @example @lang js
* const data = await this.$druxt.getResource('node--article', id)
*
* @param {string} type - The JSON:API Resource type.
* @param {string} id - The Drupal resource UUID.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @returns {object} The JSON:API resource data.
*/
DruxtClient.prototype.getResource = async function getResource (type, id, query) {
if (!id || !type) {
return false
}
var ref = await this.getIndex(type);
var href = ref.href;
if (!href) {
href = this.options.endpoint + '/' + type.replace('--', '/');
}
var url = this.buildQueryUrl((href + "/" + id), query);
try {
var resource = await this.axios.get(url);
return resource.data
} catch (e) {
return false
}
};
/**
* DruxtClient options object.
*
* @typedef {object} DruxtClientOptions
*
* @param {object} [axios] - Axios instance settings.
* @param {string} [endpoint=jsonapi] - The JSON:API endpoint.
* @param {string} [jsonapiResourceConfig=jsonapi_resource_config--jsonapi_resource_config] -
* The JSON:API resource config type, used for [JSON:API Extras](https://www.drupal.org/project/jsonapi_extras) support.
*
* @see {@link https://github.com/axios/axios#request-config}
*
* @example @lang js
* {
* axios: {
* headers: { 'X-Custom-Header': true },
* },
* endpoint: 'api',
* }
*/
/**
* @typedef {string|object} DruxtClientQuery
*
* A correctly formatted JSON:API query string or object.
*
* @example
* page[limit]=5&page[offset]=5
*
* @example @lang js
* new DrupalJsonApiParams().addPageLimit(5)
*
* @see {@link https://www.npmjs.com/package/drupal-jsonapi-params}
*//**
* The DruxtModule base Vue.js component.
*
* Extend this component to build a Druxt module.
*
* @example @lang js
* import { DruxtModule } from 'druxt'
* export default {
* name: 'DruxtTestModule',
* extends: DruxtModule,
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
*/
var script$2 = {
components: { DruxtWrapper: __vue_component__$1 },
/** */
props: {
/**
* The module value.
*
* @type {(Array|Boolean|Date|Number|Object|String)}
* @model
*/
value: {
type: [Array, Boolean, Date, Number, Object, String],
default: null,
},
wrapper: {
type: Object,
default: function () { return ({
component: 'div',
propsData: {},
}); }
},
},
/**
* Loads the Druxt module data and applies a wrapper component as required.
*
* **Important:** If your component has an existing `fetch` method, you must manually invoke
* the `DruxtModule.fetch()` hook.
*
* @example @lang js <caption>Manually invoking DruxtModule.fetch().</caption>
* import { DruxtModule } from 'druxt'
* export default {
* name: 'DruxtTestModule',
* extends: DruxtModule,
* async fetch() {
* await DruxtModule.fetch.call(this)
* }
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
*/
fetch: async function fetch() {
if (!(this.$options || {}).druxt) {
return false
async getIndex(resource) {
if (this.index && !resource) {
return this.index;
}
// Build wrapper component object.
var options = this.getModuleComponents();
var component = {
is: (((options.filter(function (o) { return o.global; }) || [])[0] || {}).name || 'DruxtWrapper'),
options: options.map(function (o) { return o.name; }) || [],
};
// Get scoped slots.
component.slots = Object.keys(this.getScopedSlots());
// Get wrapper data.
var wrapperData = await this.getWrapperData(component.is);
component.settings = wrapperData.druxt || {};
// Build wrapper component propsData.
component = Object.assign({}, component, this.getModulePropsData(wrapperData.props));
// Set component data.
this.component = component;
},
/**
* @property {ComponentData} component - The wrapper component and propsData to be rendered.
* @property {object} model - The model object.
*/
data: function (ref) {
var value = ref.value;
return ({
component: {
$attrs: {},
is: 'DruxtWrapper',
options: [],
props: {},
propsData: {},
settings: {},
slots: [],
},
model: value,
});
},
/** */
methods: {
/**
* Get list of module wrapper components.
*
* @returns {Components}
*/
getModuleComponents: function getModuleComponents() {
var this$1 = this;
if (!(this.$options.druxt || {}).componentOptions) {
return []
}
var options = this.$options.druxt.componentOptions.call(this, this);
if (!options || !options.length) {
return []
}
// Build list of available components.
var components = [];
var loop = function () {
var variants = [];
components = components.concat( set.map(function (item) {
// Build array of name parts.
var parts = variants.length ? [].concat( variants[0].parts ) : [];
parts.push(scule.pascalCase(scule.splitByCase(item)));
// Convert parts into a pascalCase component name.
var name = scule.pascalCase([this$1.$options.name ].concat( parts));
// Check if component is globally registered.
var global = !!this$1.$options.components[name];
// Store set variant data to be used in next set item.
variants.unshift({ global: global, name: name, parts: parts });
return { global: global, name: name, parts: parts }
}));
};
for (var set of options.filter(function (set) { return Array.isArray(set); })) loop();
// Filter unique components.
var unique = components.filter((function (s) { return function (o) { return !s.has(o.name) && s.add(o.name); }; })(new Set));
// Sort items by parts length.
var sorted = unique.sort(function (a, b) { return b.parts.length - a.parts.length; });
return sorted
},
/**
* Get module propsData via modules `druxt.propsData()` callback.
*
* @example @lang js
* {
* bar: 'foo',
* foo: 'bar',
* }
*
* @return {object}
*/
getModulePropsData: function getModulePropsData(wrapperProps) {
if ( wrapperProps === void 0 ) wrapperProps = {};
if (!(this.$options.druxt || {}).propsData) {
return {}
}
var propsData = this.$options.druxt.propsData.call(this, this);
// Props.
var props = {};
var propsKeys = Object.keys(wrapperProps).filter(function (i) { return Object.keys(propsData).includes(i); });
for (var key of propsKeys) {
props[key] = propsData[key];
}
// $attrs.
var $attrs = Object.assign({}, this.$attrs);
delete $attrs['data-fetch-key'];
var $attrsKeys = Object.keys(propsData).filter(function (i) { return !Object.keys(wrapperProps).includes(i); });
for (var key$1 of $attrsKeys) {
$attrs[key$1] = propsData[key$1];
}
return { $attrs: $attrs, props: props, propsData: propsData }
},
/**
* Gets a Druxt modules scoped slots, and if there's no default slots,
* provides a develop mode debug default or passes through to a
* default template.
*
* @return {object}
*/
getScopedSlots: function getScopedSlots() {
var this$1 = this;
var h = this.$createElement;
var scopedSlots = typeof (this.$options.druxt || {}).slots === 'function'
? this.$options.druxt.slots.call(this, h)
: {};
// Pass through default scoped slot if provided.
if (typeof this.$scopedSlots.default === 'function') {
scopedSlots.default = function (attrs) { return this$1.$scopedSlots.default(Object.assign({}, ((this$1.$options.druxt || {}).propsData || (function () {}))(this$1),
attrs)); };
}
// Provide debug data if Nuxt is running in dev mode.
if (!scopedSlots.default && this.$nuxt.context.isDev) {
scopedSlots.default = function () { return h(
'details',
{
style: {
border: '2px dashed lightgrey',
margin: '0.5em 0',
padding: '1em',
},
},
[
h('summary', [("[" + (this$1.$options._componentTag) + "] Missing default slot.")]),
h('label', ['Component options:', h('ul', this$1.component.options.map(function (s) { return h('li', [s]); }))]),
h('br'),
h('label', ['propsData:', h('pre', [h('code', [JSON.stringify(this$1.component.propsData, null, '\t')])])])
]
); };
}
return scopedSlots
},
/**
* Get wrapper component data.
*
* @param {string} component - The Wrapper component name.
*
* @return {WrapperData}
*/
getWrapperData: async function getWrapperData(component) {
var wrapperData = { druxt: {}, props: {} };
if (!this.$options.components[component]) {
return wrapperData
}
// Get data from resolved component.
if (this.$options.components[component].options) {
wrapperData = this.$options.components[component].options;
}
// Get data from unresolved component.
else if (typeof this.$options.components[component] === 'function' && this._init) {
wrapperData = (await this.$options.components[component].call(this)) || {};
}
var options = Vue.util.mergeOptions({}, wrapperData);
return {
druxt: options.druxt || {},
props: options.props || {},
}
if (this.index && resource) {
return this.index[resource] ? this.index[resource] : false;
}
},
watch: {
model: function model() {
if (this.component.props.value !== this.model) {
this.component.props.value = this.model;
// Only emit 'input' if using the default 'DruxtWrapper' component.
if (this.component.is === 'DruxtWrapper') {
this.$emit('input', this.model);
}
const index = await this.axios.get(this.options.endpoint);
this.index = index.data.links;
if (this.index[this.options.jsonapiResourceConfig]) {
const resources = await this.axios.get(this.index[this.options.jsonapiResourceConfig].href);
for (const resourceType in resources.data.data) {
const resource2 = resources.data.data[resourceType];
const internal = resource2.attributes.drupal_internal__id.split("--");
const item = {
resourceType: resource2.attributes.resourceType,
entityType: internal[0],
bundle: internal[1],
resourceFields: resource2.attributes.resourceFields
};
const id = [item.entityType, item.bundle].join("--");
this.index[id] = {
...item,
...this.index[id]
};
}
},
value: function value() {
if (this.value !== this.model) {
this.model = this.value;
}
}
},
render: function render(h) {
var self = this;
var wrapperData = {
class: this.wrapper.class || undefined,
style: this.wrapper.style || undefined,
props: this.wrapper.propsData,
};
// Return only wrapper if fetch state is still pending.
if (this.$fetchState.pending) {
return h(this.wrapper.component, wrapperData)
if (resource) {
return this.index[resource] ? this.index[resource] : false;
}
// Return wrapped component.
var attrs = Object.assign({}, this.component.$attrs, this.$attrs);
delete attrs['data-fetch-key'];
return h(this.wrapper.component, wrapperData, [
h(this.component.is, {
attrs: attrs,
on: {
input: function input(value) {
self.model = value;
self.$emit('input', value);
}
},
props: this.component.props,
ref: 'component',
scopedSlots: this.getScopedSlots(),
})
])
return this.index;
}
};
async getResource(type, id, query) {
if (!id || !type) {
return false;
}
let { href } = await this.getIndex(type);
if (!href) {
href = this.options.endpoint + "/" + type.replace("--", "/");
}
const url = this.buildQueryUrl(`${href}/${id}`, query);
try {
const resource = await this.axios.get(url);
return resource.data;
} catch (e) {
return false;
}
}
}
/**
* @typedef {object[]} Components
* @property {boolean} global - Component global registration state.
* @property {string} name - The component name.
* @property {string[]} parts - The component naming parts.
*
* @example @lang js
* [{
* global: true,
* pascal: 'DruxtTestModuleWrapper',
* parts: ['Wrapper'],
* }]
*/
/**
* @typedef {object} ComponentData
* @property {object} $attrs - propsData not registered by the Wrapper component.
* @property {string} is=DruxtWrapper - The Wrapper component name.
* @property {string[]} options - The Wrapper component options.
* @property {object} props - propsData registered by the Wrapper component.
* @property {object} propsData - The component propsData object.
* @property {object} settings - Druxt settings object provided by the Wrapper component.
*
* @example @lang js
* {
* $attrs: { bar: 'foo' },
* is: 'DruxtTestModuleWrapper',
* options: [
* 'DruxtTestModuleWrapper',
* ],
* props: { foo: 'bar' },
* propsData: {
* bar: 'foo',
* foo: 'bar',
* },
* settings: { fooBar: true },
* }
*/
/**
* @typedef {object} WrapperData
* @property {object} druxt - Druxt settings object for use by Druxt module.
* @property {object} props - Registered props oject.
*
* @example @lang js
* {
* druxt: { fooBar: true },
* props: {
* foo: {
* type: String,
* default: '',
* }
* }
* }
*//* script */
var __vue_script__$2 = script$2;
/* template */
/* style */
var __vue_inject_styles__$2 = undefined;
/* scoped */
var __vue_scope_id__$2 = undefined;
/* module identifier */
var __vue_module_identifier__$2 = "data-v-f605eeaa";
/* functional template */
var __vue_is_functional_template__$2 = undefined;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__$2 = /*#__PURE__*/normalizeComponent(
{},
__vue_inject_styles__$2,
__vue_script__$2,
__vue_scope_id__$2,
__vue_is_functional_template__$2,
__vue_module_identifier__$2,
false,
undefined,
undefined,
undefined
);var getDrupalJsonApiParams = function (query) {
const getDrupalJsonApiParams = (query) => {
return new drupalJsonapiParams.DrupalJsonApiParams().initialize(query);
};var dehydrateResources = function (ref) {
var commit = ref.commit;
var queryObject = ref.queryObject;
var resources = ref.resources;
};
return resources.map(function (data) {
// Generate a query link for included resources.
// This is used to determine if the resource is a partial.
var link = decodeURI(((data.links || {}).self || {}).href || '');
var href = typeof (queryObject.fields || {})[data.type] === 'string'
? [link.split('?')[0], ("fields[" + (data.type) + "]=" + (queryObject.fields[data.type]))].join('?')
: link;
// Commit the included resource.
commit('druxt/addResource', {
const dehydrateResources = ({ commit, queryObject, resources }) => {
return resources.map((data) => {
const link = decodeURI(((data.links || {}).self || {}).href || "");
const href = typeof (queryObject.fields || {})[data.type] === "string" ? [link.split("?")[0], `fields[${data.type}]=${queryObject.fields[data.type]}`].join("?") : link;
commit("druxt/addResource", {
resource: {
data: data,
links: { self: { href: href } },
data,
links: { self: { href } }
}
});
return { id: data.id, type: data.type }
})
return { id: data.id, type: data.type };
});
};
var DruxtStore = function (ref) {
var store = ref.store;
if (typeof store === 'undefined') {
throw new TypeError('Vuex store not found.')
const DruxtStore = ({ store }) => {
if (typeof store === "undefined") {
throw new TypeError("Vuex store not found.");
}
/**
* @namespace
*/
var namespace = 'druxt';
/**
* The DruxtStore Vuex module.
*
* Provides a Vuex state object, mutations and actions for interacting with the DruxtClient.
*
* @name druxt
* @module druxt
*/
var module = {
const namespace = "druxt";
const module = {
namespaced: true,
/**
* Vuex State object.
*
* @name state
* @type {object}
* @property {DruxtClientCollections} collections - JSON:API resource collections store.
* @property {object} resources - JSON:API resources store.
* @readonly
*/
state: function () { return ({
state: () => ({
collections: {},
resources: {}
}); },
/**
* Vuex Mutations.
*/
}),
mutations: {
/**
* @name addCollection
* @mutator {object} addCollection=collections Adds a JSON:API collection to the Vuex state object.
* @param {addCollectionContext} context
*
* @example @lang js
* this.$store.commit('druxt/addCollection', { collection, type, hash })
*/
addCollection: function addCollection (state, ref) {
var collection = ref.collection;
var type = ref.type;
var hash = ref.hash;
if (!state.collections[type]) { Vue.set(state.collections, type, {}); }
// Parse the query.
var link = decodeURI((((collection || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Store and dehydrate collection resources.
collection.data = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.data });
// Extract and store included resources.
addCollection(state, { collection, type, hash }) {
if (!state.collections[type])
Vue__default['default'].set(state.collections, type, {});
const link = decodeURI((((collection || {}).links || {}).self || {}).href || "");
const query = link.split("?")[1] || "";
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
collection.data = dehydrateResources({ commit: this.commit, queryObject, resources: collection.data });
if (collection.included) {
collection.included = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.included });
collection.included = dehydrateResources({ commit: this.commit, queryObject, resources: collection.included });
delete collection.included;
}
// Recursively merge new collection data into stored collection.
collection = merge(state.collections[type][hash] || {}, collection, { arrayMerge: function (dst, src) { return src; } });
Vue.set(state.collections[type], hash, collection);
collection = merge__default['default'](state.collections[type][hash] || {}, collection, { arrayMerge: (dst, src) => src });
Vue__default['default'].set(state.collections[type], hash, collection);
},
/**
* @name addResource
* @mutator {object} addResource=resources Adds a JSON:API resource to the Vuex state object.
* @param {addResourceContext} context
*
* @example @lang js
* this.$store.commit('druxt/addResource', { resource })
*/
addResource: function addResource (state, ref) {
var resource = ref.resource;
var hash = ref.hash;
addResource(state, { resource, hash }) {
if (hash) {
console.warn('[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/guide/deprecations.html#druxtstore-addresource-hash');
console.warn("[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/guide/deprecations.html#druxtstore-addresource-hash");
}
var ref$1 = (resource || {}).data || {};
var id = ref$1.id;
var type = ref$1.type;
const { id, type } = (resource || {}).data || {};
if (!id || !type) {
// @TODO - Error?
return
return;
}
// Parse the query.
var link = decodeURI((((resource || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Add cache flag to resource.
var flag = typeof (queryObject.fields || {})[((resource || {}).data || {}).type] === 'string' ? '_druxt_partial' : '_druxt_full';
const link = decodeURI((((resource || {}).links || {}).self || {}).href || "");
const query = link.split("?")[1] || "";
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
const flag = typeof (queryObject.fields || {})[((resource || {}).data || {}).type] === "string" ? "_druxt_partial" : "_druxt_full";
resource[flag] = Date.now();
// Ensure Resource type array is reactive.
if (!state.resources[type]) { Vue.set(state.resources, type, {}); }
// Extract and store included data.
if (!state.resources[type])
Vue__default['default'].set(state.resources, type, {});
if (resource.included) {
dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: resource.included });
dehydrateResources({ commit: this.commit, queryObject, resources: resource.included });
delete resource.included;
}
// Recursively merge new resource data into stored resource.
resource = merge(state.resources[type][id] || {}, resource, { arrayMerge: function (dst, src) { return src; } });
Vue.set(state.resources[type], id, resource);
},
resource = merge__default['default'](state.resources[type][id] || {}, resource, { arrayMerge: (dst, src) => src });
Vue__default['default'].set(state.resources[type], id, resource);
}
},
/**
* Vuex Actions.
*/
actions: {
/**
* Get collection of resources.
*
* @name getCollection
* @action getCollection
* @param {getCollectionContext} context
* @return {object[]} Array of Drupal JSON:API resource data.
*
* @example @lang js
* // Load all currently published Articles.
* const resources = await this.$store.dispatch('druxt/getCollection', {
* type: 'node--article',
* query: new DrupalJsonApiParams().addFilter('status', '1'),
* })
*/
getCollection: async function getCollection (ref, ref$1) {
var commit = ref.commit;
var state = ref.state;
var type = ref$1.type;
var query = ref$1.query;
// Generate a hash using query data excluding the 'fields' and 'include' data.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
var hash = query ? md5(JSON.stringify(Object.assign({}, queryObject, {fields: {}, include: []}))) : '_default';
// If collection hash exists, re-hydrate and return the data.
async getCollection({ commit, state }, { type, query }) {
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
const hash = query ? md5__default['default'](JSON.stringify({ ...queryObject, fields: {}, include: [] })) : "_default";
if ((state.collections[type] || {})[hash]) {
return Object.assign({}, state.collections[type][hash],
// Hydrate resource data.
{data: state.collections[type][hash].data.map(function (o) { return (state.resources[o.type][o.id] || {}).data; })})
return {
...state.collections[type][hash],
data: state.collections[type][hash].data.map((o) => (state.resources[o.type][o.id] || {}).data)
};
}
// Get the collection using the DruxtClient instance.
var collection = await this.$druxt.getCollection(type, query);
// Store the collection in the DruxtStore.
commit('addCollection', { collection: Object.assign({}, collection), type: type, hash: hash });
return collection
const collection = await this.$druxt.getCollection(type, query);
commit("addCollection", { collection: { ...collection }, type, hash });
return collection;
},
/**
* Get JSON:API Resource.
*
* - Executes query against Drupal JSON:API.
* - Caches result in the Vuex store.
* - Returns cached result from Vuex store when available.
*
* @name getResource
* @action getResource=resources
* @param {getResourceContext} context
* @return {object} The Drupal JSON:API resource.
*
* @example @lang js
* const resource = await this.$store.dispatch('druxt/getResource', { type: 'node--article', id })
*/
getResource: async function getResource (ref, ref$1) {
var commit = ref.commit;
var dispatch = ref.dispatch;
var state = ref.state;
var type = ref$1.type;
var id = ref$1.id;
var query = ref$1.query;
// Get the resource from the store if it's avaialble.
var storedResource = (state.resources[type] || {})[id] ?
Object.assign({}, state.resources[type][id])
: null;
// Parse the query.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
queryObject.include = Array.isArray(queryObject.include)
? queryObject.include.join(',')
: queryObject.include;
// Ensure that includes are in the fields filter.
if (queryObject.include && typeof (queryObject.fields || {})[type] === 'string') {
var fields$1 = queryObject.fields[type].split(',').filter(function (s) { return s; });
var includes = queryObject.include.split(',').filter(function (s) { return s && !s.includes('.'); });
queryObject.fields[type] = Array.from(
new Set(fields$1.concat( includes))
).filter(function (s) { return s; }).join(',');
async getResource({ commit, dispatch, state }, { type, id, query }) {
const storedResource = (state.resources[type] || {})[id] ? { ...state.resources[type][id] } : null;
const queryObject = getDrupalJsonApiParams(query).getQueryObject();
queryObject.include = Array.isArray(queryObject.include) ? queryObject.include.join(",") : queryObject.include;
if (queryObject.include && typeof (queryObject.fields || {})[type] === "string") {
const fields2 = queryObject.fields[type].split(",").filter((s) => s);
const includes = queryObject.include.split(",").filter((s) => s && !s.includes("."));
queryObject.fields[type] = Array.from(new Set([...fields2, ...includes])).filter((s) => s).join(",");
}
// Hydrate included data based on the include query.
var included = [];
let included = [];
if (queryObject.include && storedResource) {
// Request included resources from druxt/getResource.
var resources =
await Promise.all(queryObject.include.split(',')
.filter(function (s) { return Object.keys((storedResource.data.relationships || {})).includes(s); })
.map(function (key) {
var ref = storedResource.data.relationships[key];
var data = ref.data;
data = Array.isArray(data) ? data : [data];
// Get any sub-includes, e.g., `media,media.image` becomes `image`.
var include = queryObject.include.split(',')
.filter(function (s) { return s.startsWith((key + ".")); })
.map(function (s) { return s.slice(key.length + 1); })
.join(',');
return data.filter(function (o) { return typeof o === 'object' && o; }).map(function (o) {
return dispatch('getResource', {
type: o.type,
id: o.id,
query: Object.assign({}, queryObject, {include: include}),
})
})
})
.flat()
);
// Merge all nested, included resources.
for (var include of resources) {
included = included.concat( [include.data], include.included || []);
const resources = await Promise.all(queryObject.include.split(",").filter((s) => Object.keys(storedResource.data.relationships || {}).includes(s)).map((key) => {
let { data } = storedResource.data.relationships[key];
data = Array.isArray(data) ? data : [data];
const include = queryObject.include.split(",").filter((s) => s.startsWith(`${key}.`)).map((s) => s.slice(key.length + 1)).join(",");
return data.filter((o) => typeof o === "object" && o).map((o) => {
return dispatch("getResource", {
type: o.type,
id: o.id,
query: { ...queryObject, include }
});
});
}).flat());
for (const include of resources) {
included = [...included, include.data, ...include.included || []];
}
storedResource.included = included;
}
// Return if we have the full resource.
if ((storedResource || {})._druxt_full) {
return storedResource
return storedResource;
}
var isFull = typeof (queryObject.fields || {})[type] !== 'string';
// Determine if we have all the requested field data.
var fields = isFull ? true : (queryObject.fields || {})[type];
const isFull = typeof (queryObject.fields || {})[type] !== "string";
let fields = isFull ? true : (queryObject.fields || {})[type];
if (storedResource && !isFull && fields) {
var queryFields = fields.split(',');
var resourceFields = Object.keys(((storedResource || {}).data || {}).attributes || {}).concat( Object.keys(((storedResource || {}).data || {}).relationships || {}) );
var missingFields = queryFields.filter(function (key) { return !resourceFields.includes(key); });
const queryFields = fields.split(",");
const resourceFields = [
...Object.keys(((storedResource || {}).data || {}).attributes || {}),
...Object.keys(((storedResource || {}).data || {}).relationships || {})
];
const missingFields = queryFields.filter((key) => !resourceFields.includes(key));
fields = !!missingFields.length;
// Modify query to load additional fields, if required.
queryObject.fields[type] = (missingFields || []).join(',') || undefined;
queryObject.fields[type] = (missingFields || []).join(",") || void 0;
}
// Request the resource from the DruxtClient if required.
var resource;
let resource;
if (!storedResource || fields) {
resource = await this.$druxt.getResource(type, id, getDrupalJsonApiParams(queryObject));
commit('addResource', { resource: Object.assign({}, resource) });
commit("addResource", { resource: { ...resource } });
}
// Build resource to be returned.
var result = Object.assign({}, (state.resources[type] || {})[id]);
// Merge included resources into resource.
const result = { ...(state.resources[type] || {})[id] };
if (queryObject.include && ((resource || {}).included || (storedResource || {}).included)) {
included = ( (resource || {}).included || [] ).concat( (storedResource || {}).included || [] );
result.included = Array.from(new Set(included.filter(function (o) { return (o || {}).id; }).map(function (o) { return o.id; })))
.map(function (id) { return included.find(function (o) { return o.id === id; }); });
included = [
...(resource || {}).included || [],
...(storedResource || {}).included || []
];
result.included = Array.from(new Set(included.filter((o) => (o || {}).id).map((o) => o.id))).map((id2) => included.find((o) => o.id === id2));
}
return result
},
return result;
}
}
};
store.registerModule(namespace, module, {

@@ -1397,253 +313,56 @@ preserveState: Boolean(store.state[namespace])

/**
* Parameters for the `addCollection` mutation.
*
* @typedef {object} addCollectionContext
*
* @param {object} collection - A collection of JSON:API resources.
* @param {string} type - The JSON:API collection resource type.
* @param {string} hash - An md5 hash of the query string.
*
* @example @lang js
* {
* collection: {
* jsonapi: {},
* data: [{}],
* links: {}
* },
* type: 'node--page',
* hash: '_default'
* }
*/
/**
* Parameters for the `addResource` mutation.
*
* @typedef {object} addResourceContext
*
* @param {object} resource - The JSON:API resource.
*
* @example @lang js
* {
* resource: {
* jsonapi: {},
* data: {},
* links: {}
* },
* }
*/
/**
* Parameters for the `getCollection` action.
*
* @typedef {object} getCollectionContext
*
* @param {string} type - The JSON:API collection resource type.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @example @lang js
* {
* type: 'node--page',
* query: new DrupalJsonApiParams().addFilter('status', '1')
* }
*/
/**
* Parameters for the `getResource` action.
*
* @typedef {object} getResourceContext
*
* @param {string} type - The JSON:API Resource type.
* @param {string} id - The Drupal resource UUID.
* @param {DruxtClientQuery} [query] - A correctly formatted JSON:API query string or object.
*
* @example @lang js
* {
* type: 'node--page',
* id: 'd8dfd355-7f2f-4fc3-a149-288e4e293bdd'
* }
*/
/**
* @typedef {string|object} DruxtClientQuery
*
* A correctly formatted JSON:API query string or object.
*
* @example
* page[limit]=5&page[offset]=5
*
* @example @lang js
* new DrupalJsonApiParams().addPageLimit(5)
*
* @see {@link https://www.npmjs.com/package/drupal-jsonapi-params}
*//**
* Druxt utility class.
*
* @deprecated
* @private
*/
var DruxtClass = function DruxtClass() {};
/**
* Get component data from available options.
*
* @param {object} vm - The DruxtJS module Vue.js component.
* @param {string[]} options - The component naming options.
* @param {boolean} [all=false] - Returns all options if true, else only globally registered options.
* @param {string} [prefix] - A string to prefix all components.
*
* @returns {WrapperComponents}
*/
DruxtClass.prototype.getComponents = function getComponents (vm, options, all, prefix) {
if ( all === void 0 ) all = false;
var results = [];
var unique = {};
options
// Filter out incorrectly typed items.
.filter(function (item) { return Array.isArray(item); })
// Process each item.
.map(function (item) {
var variants = [];
item.map(function (string) {
var parts = variants.length ? [].concat( variants[0].parts ) : [];
class DruxtClass {
constructor() {
}
getComponents(vm, options, all = false, prefix) {
const results = [];
const unique = {};
options.filter((item) => Array.isArray(item)).map((item) => {
const variants = [];
item.map((string) => {
const parts = variants.length ? [...variants[0].parts] : [];
parts.push(string);
var clone = [].concat( parts );
// Attach prefix as required.
if (typeof prefix !== 'string' && (prefix !== false || typeof prefix === 'undefined') && ((vm || {}).$options || {}).name) {
prefix = vm.$options.name.match(/[A-Z][a-z]+/g).map(function (word) { return word.toLowerCase(); }).join('-');
const clone = [...parts];
if (typeof prefix !== "string" && (prefix !== false || typeof prefix === "undefined") && ((vm || {}).$options || {}).name) {
prefix = vm.$options.name.match(/[A-Z][a-z]+/g).map((word) => word.toLowerCase()).join("-");
}
if (prefix) {
clone.unshift(prefix);
}
// Generate component name values.
var kebab = clone.map(function (string) { return string.toLowerCase().replace(/--|_/g, '-'); }).join('-');
var pascal = kebab.replace(/((\b|[^a-zA-Z0-9]+)[a-zA-Z0-9])/gi, function (match, p1, p2) { return match.toUpperCase().replace(p2, ''); });
// Check if component is globally registered.
var global = false;
for (var name of [kebab, pascal]) {
if (typeof (((vm || {}).$options || {}).components || {})[name] !== 'undefined') {
const kebab = clone.map((string2) => string2.toLowerCase().replace(/--|_/g, "-")).join("-");
const pascal = kebab.replace(/((\b|[^a-zA-Z0-9]+)[a-zA-Z0-9])/gi, (match, p1, p2) => match.toUpperCase().replace(p2, ""));
let global = false;
for (const name of [kebab, pascal]) {
if (typeof (((vm || {}).$options || {}).components || {})[name] !== "undefined") {
global = true;
break
break;
}
}
variants.unshift({ global: global, kebab: kebab, parts: parts, pascal: pascal, prefix: prefix });
variants.unshift({ global, kebab, parts, pascal, prefix });
});
// Add variants to results.
variants.map(function (variant) {
// Ensure unique results.
variants.map((variant) => {
if (unique[variant.pascal]) {
return
return;
}
unique[variant.pascal] = true;
results.push(variant);
});
});
// Return globally registered components or all.
return results
.filter(function (option) { return option.global || !!all; })
.sort(function (a, b) { return b.parts.length - a.parts.length; })
};
/**
* Get the Druxt module data from the referenced component.
*
* @returns {ModuleData}
*/
DruxtClass.prototype.getModuleData = async function getModuleData (vm) {
if (typeof ((vm || {}).$options || {}).druxt !== 'function') {
return false
return results.filter((option) => option.global || !!all).sort((a, b) => b.parts.length - a.parts.length);
}
var moduleData = await vm.$options.druxt({ vm: vm });
if ((vm.$options || {}).name) {
moduleData.name = vm.$options.name.match(/[A-Z][a-z]+/g).map(function (word) { return word.toLowerCase(); }).join('-');
}
return moduleData
};/**
* @name DruxtComponentMixin
* @deprecated
* @private
*/
var DruxtComponentMixin = {
components: { DruxtWrapper: __vue_component__$1 },
/**
* @property {Component} component - The wrapper component and propsData to be rendered.
*/
data: function () { return ({
component: {
is: 'DruxtWrapper',
options: [],
propsData: {},
},
}); },
props: {
wrapper: {
type: Object,
default: function () { return ({
component: 'div',
propsData: {},
}); }
async getModuleData(vm) {
if (typeof ((vm || {}).$options || {}).druxt !== "function") {
return false;
}
},
/**
* The Nuxt Fetch hook.
*
* Loads the Druxt module data and applies a wrapper component as required.
*
* **Important:** If your component has an existing `fetch` method, you must manually invoke
* the `DruxtComponentMixin.fetch()` hook.
*
* @see {@link https://nuxtjs.org/api/pages-fetch/}
*
* @example @lang vue <caption>Manually invoking DruxtComponentMixin.fetch().</caption>
* <script>
* import { DruxtComponentMixin } from 'druxt'
* export default {
* mixins: [DruxtComponentMixin],
*
* async fetch {
* await DruxtComponentMixin.fetch.call(this)
* }
* }
* </script>
*/
fetch: async function fetch() {
console.warn('DruxtComponentMixin is deprecated in favour of DruxtModule.');
// @todo - check for this.$druxt plugin.
var druxt = new DruxtClass();
var moduleData = await druxt.getModuleData(this);
this.component.propsData = moduleData.propsData || {};
if (!moduleData.componentOptions) {
return
const moduleData = await vm.$options.druxt({ vm });
if ((vm.$options || {}).name) {
moduleData.name = vm.$options.name.match(/[A-Z][a-z]+/g).map((word) => word.toLowerCase()).join("-");
}
return moduleData;
}
}
var options = druxt.getComponents(this, moduleData.componentOptions, true);
this.component.options = options.map(function (item) { return item.pascal; });
var available = options.filter(function (item) { return item.global; });
if (!available.length) {
return
}
this.component.is = available[0].pascal;
},
};exports.Druxt=__vue_component__;exports.DruxtClass=DruxtClass;exports.DruxtClient=DruxtClient;exports.DruxtComponentMixin=DruxtComponentMixin;exports.DruxtModule=__vue_component__$2;exports.DruxtStore=DruxtStore;exports.DruxtWrapper=__vue_component__$1;exports.default=DruxtNuxtModule;
exports.DruxtClass = DruxtClass;
exports.DruxtClient = DruxtClient;
exports.DruxtStore = DruxtStore;
exports['default'] = DruxtNuxtModule;
import Vue from 'vue'
import { Druxt, DruxtClient, DruxtWrapper } from 'druxt'
import { DruxtClient } from 'druxt'
import Druxt from 'druxt/dist/components/Druxt.vue'
import DruxtWrapper from 'druxt/dist/components/DruxtWrapper.vue'
// Install the Druxt Vue.js component.

@@ -5,0 +8,0 @@ Vue.use({

{
"name": "druxt",
"version": "0.8.3",
"description": "A Bridge between frameworks, Nuxt.js in the front, Drupal in the back.",
"repository": {
"type": "git",
"url": "git+https://github.com/druxt/druxt.js"
},
"version": "0.9.0",
"description": "The Fully Decoupled Drupal Framework for Nuxt.js.",
"keywords": [

@@ -21,2 +17,11 @@ "cms",

],
"homepage": "https://druxtjs.org",
"bugs": {
"url": "https://github.com/druxt/druxt.js/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/druxt/druxt.js"
},
"license": "MIT",
"author": {

@@ -27,10 +32,11 @@ "name": "Stuart Clark",

},
"license": "MIT",
"bugs": {
"url": "https://github.com/druxt/druxt.js/issues"
"exports": {
".": {
"require": "./dist/druxt.ssr.js",
"import": "./dist/druxt.esm.js"
},
"./components/*": "./dist/components/*"
},
"homepage": "https://druxtjs.org",
"main": "dist/druxt.ssr.js",
"module": "dist/druxt.esm.js",
"unpkg": "dist/druxt.min.js",
"files": [

@@ -40,22 +46,4 @@ "dist",

],
"scripts": {
"build": "cross-env NODE_ENV=production rollup -c",
"build:es": "cross-env NODE_ENV=production rollup -c --format es",
"build:ssr": "cross-env NODE_ENV=production rollup -c --format cjs",
"build:unpkg": "cross-env NODE_ENV=production rollup -c --format iife",
"dev": "nodemon --ext js,vue --exec 'npm run lint && npm run build && npm run test'",
"docs:dev": "npx druxt-docgen -c vuepress.config dev",
"docs:build": "npx druxt-docgen -c vuepress.config build",
"lint": "eslint --ext .js,.vue src",
"start": "npm run dev",
"test": "jest"
},
"nodemonConfig": {
"ignore": [
"dist/*"
]
},
"dependencies": {
"axios": "^0.21.1",
"codecov": "^3.8.2",
"deepmerge": "^4.2.2",

@@ -65,49 +53,12 @@ "drupal-jsonapi-params": "^1.2.1",

"querystring": "^0.2.0",
"scule": "^0.1.1",
"vuex": "^3.6.0"
"scule": "^0.2.0"
},
"devDependencies": {
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@rollup/plugin-alias": "^2.2.0",
"@rollup/plugin-buble": "^0.20.0",
"@rollup/plugin-replace": "^2.3.4",
"@vue/test-utils": "^1.1.2",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"bootstrap-vue": "^2.21.2",
"cross-env": "^6.0.3",
"druxt-docgen": "^0.4.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"jest": "^25.1.0",
"jest-junit": "^11.1.0",
"jest-mock-axios": "^3.2.0",
"minimist": "^1.2.0",
"nodemon": "^2.0.7",
"rollup": "^1.26.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-vue": "^5.1.6",
"vue": "^2.6.12",
"vue-jest": "^3.0.7",
"vue-template-compiler": "^2.6.12",
"vue-test-utils": "^1.0.0-beta.11"
"optionalDependencies": {
"core-js": "^3.16.1",
"vue": "^2.6.14",
"vuex": "^3.6.2"
},
"engines": {
"node": ">=8"
},
"jest": {
"coverageDirectory": "./coverage/",
"collectCoverage": true,
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
".*\\.(vue)$": "vue-jest",
"^.+\\.js$": "<rootDir>/node_modules/babel-jest"
}
"publishConfig": {
"access": "public"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc