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.4.2 to 0.5.0

658

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 md5 from 'md5';

@@ -355,128 +357,2 @@

/**
* Druxt utility class.
*/
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 ) : [];
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('-');
}
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') {
global = true;
break
}
}
variants.unshift({ global: global, kebab: kebab, parts: parts, pascal: pascal, prefix: prefix });
});
// Add variants to results.
variants.map(function (variant) {
// Ensure unique results.
if (unique[variant.pascal]) {
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
}
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
};
/**
* @typedef {object} ModuleData
* @property {Array.<string[]>} componentOptions - An array of arrays of strings for component naming.
* @property {object} propsData - Property data to bind to the wrapper component.
*
* @example @lang js
* {
* componentOptions: [['wrapper', 'component']],
* propsData: {},
* }
*/
/**
* @typedef {object[]} WrapperComponents
* @property {boolean} global - Component global registration state.
* @property {string} kebab - The component name in kebab case.
* @property {string[]} parts - The component naming parts.
* @property {string} pascal - The component name in pascal case.
* @property {string} prefix - The component name prefix.
*
* @example @lang js
* [{
* global: true,
* kebab: 'druxt-test-module-wrapper',
* parts: ['wrapper'],
* pascal: 'DruxtTestModuleWrapper',
* prefix: 'druxt-test-module',
* }]
*/
/**
* Druxt JSON:API client.

@@ -772,35 +648,23 @@ */

/**
* Vue.js Mixin to add Druxt component theming to a Druxt module.
* The DruxtModule base Vue.js component.
*
* @name DruxtComponentMixin
* @see {@link /guide/#component-theme-system|Wrapper theme system}
* Extend this component to build a Druxt module.
*
* @example @lang vue <caption>CustomDruxtModule.vue</caption>
* <template>
* <component :is="component.is" v-bind="component.propsData">
* <!-- -->
* </component>
* </template>
*
* <script>
* import { DruxtComponentMixin } from 'druxt'
* @example @lang js
* import { DruxtModule } from 'druxt'
* export default {
* mixins: [DruxtComponentMixin]
* name: 'DruxtTestModule',
* extends: DruxtModule,
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
* </script>
*/
var DruxtComponentMixin = {
var script$2 = {
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: {

@@ -822,48 +686,250 @@ wrapper: {

* **Important:** If your component has an existing `fetch` method, you must manually invoke
* the `DruxtComponentMixin.fetch()` hook.
* the `DruxtModule.fetch()` hook.
*
* @see {@link https://nuxtjs.org/api/pages-fetch/}
*
* @example @lang vue <caption>Manually invoking DruxtComponentMixin.fetch().</caption>
* <script>
* import { DruxtComponentMixin } from 'druxt'
* @example @lang js <caption>Manually invoking DruxtModule.fetch().</caption>
* import { DruxtModule } from 'druxt'
* export default {
* mixins: [DruxtComponentMixin],
*
* async fetch {
* await DruxtComponentMixin.fetch.call(this)
* name: 'DruxtTestModule',
* extends: DruxtModule,
* async fetch() {
* await DruxtModule.fetch.call(this)
* }
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
* </script>
*/
fetch: async function fetch() {
// @todo - check for this.$druxt plugin.
var druxt = new DruxtClass();
var moduleData = await druxt.getModuleData(this);
if (!(this.$options || {}).druxt) {
return false
}
this.component.propsData = moduleData.propsData || {};
// 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; }) || [],
};
if (!moduleData.componentOptions) {
return
// 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.
*/
data: function () { return ({
component: {
$attrs: {},
is: 'DruxtWrapper',
options: [],
props: {},
propsData: {},
settings: {},
},
}); },
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);
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 }
},
/**
* Get default scoped slots.
*
* Default output is a `JSON.stringify`'d result of the modules propsData.
*
* This method should be overridden in a Druxt modules.
*
* @example js
* getScopedSlots() {
* return {
* default: () => this.$createElement('div', ['Hello world'])
* }
* }
*
* @return {object}
*/
getScopedSlots: function getScopedSlots() {
var this$1 = this;
return {
default: function () { return this$1.$createElement('div', [JSON.stringify(this$1.component.propsData)]); }
}
},
/**
* 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 || {},
}
}
},
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
render: function render(h) {
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)
}
this.component.is = available[0].pascal;
},
// Return wrapped component.
return h(this.wrapper.component, wrapperData, [
h(this.component.is, {
attrs: this.component.$attrs,
props: this.component.props,
scopedSlots: this.getScopedSlots(),
})
])
}
};
/**
* @typedef {object} Component
* @property {string} is=DruxtWrapper - The rendered component name.
* @property {string[]} options - The possible component name options.
* @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',

@@ -873,6 +939,62 @@ * options: [

* ],
* propsData: {},
* 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 DruxtStore = function (ref) {

@@ -1128,3 +1250,177 @@ var store = ref.store;

/**
* 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 ) : [];
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('-');
}
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') {
global = true;
break
}
}
variants.unshift({ global: global, kebab: kebab, parts: parts, pascal: pascal, prefix: prefix });
});
// Add variants to results.
variants.map(function (variant) {
// Ensure unique results.
if (unique[variant.pascal]) {
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
}
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: {},
}); }
}
},
/**
* 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
}
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, DruxtStore, __vue_component__$1 as DruxtWrapper };
export { __vue_component__ as Druxt, DruxtClass, DruxtClient, DruxtComponentMixin, __vue_component__$2 as DruxtModule, DruxtStore, __vue_component__$1 as DruxtWrapper };

@@ -1,1 +0,1 @@

var Druxt=function(t,e,n,o,r){"use strict";function i(t,e,n,o,r,i,a,s,u,p){"boolean"!=typeof a&&(u=s,s=a,a=!1);var c,d="function"==typeof n?n.options:n;if(t&&t.render&&(d.render=t.render,d.staticRenderFns=t.staticRenderFns,d._compiled=!0,r&&(d.functional=!0)),o&&(d._scopeId=o),i?(c=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),e&&e.call(this,u(t)),t&&t._registeredComponents&&t._registeredComponents.add(i)},d._ssrRegister=c):e&&(c=a?function(t){e.call(this,p(t,this.$root.$options.shadowRoot))}:function(t){e.call(this,s(t))}),c)if(d.functional){var l=d.render;d.render=function(t,e){return c.call(e),l(t,e)}}else{var f=d.beforeCreate;d.beforeCreate=f?[].concat(f,c):[c]}return n}n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n,r=r&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r;var a=i({},undefined,{name:"Druxt",props:{inner:{type:[Object,Boolean],default:function(){return{component:"div",propsData:{}}}},module:{type:String,required:!0},propsData:{type:Object,default:function(){return{}}},wrapper:{type:[Object,Boolean],default:function(){return{component:"div",propsData:{}}}}},data:function(){return{component:{is:void 0,propsData:{}}}},created:function(){this.setModuleComponent()},methods:{setModuleComponent:function(){var t="Druxt"+this.module.split("-").map((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})).join("");this.$options.components[t]&&(this.component.is=t,this.component.propsData=this.propsData)}},render:function(t){var e=t(this.component.is,{props:Object.assign({},{wrapper:this.inner},this.component.propsData,this.$attrs)});return(this.wrapper||{}).component?t(this.wrapper.component,{props:this.wrapper.propsData},[e]):e}},undefined,undefined,undefined,!1,void 0,void 0,void 0),s=i({render:function(){var t=this,e=t.$createElement;return(t._self._c||e)("div",[t._t("default")],2)},staticRenderFns:[]},undefined,{name:"DruxtWrapper"},undefined,false,undefined,!1,void 0,void 0,void 0),u=function(t){void 0===t&&(t={});var n=Object.assign({},t,(this.options||{}).druxt);this.addPlugin({src:e.resolve(__dirname,"../nuxt/plugin.js"),fileName:"druxt.js",options:n}),this.addPlugin({src:e.resolve(__dirname,"../nuxt/store.js"),fileName:"store/druxt.js",options:n}),this.options.store=!0};u.meta=require("../package.json");var p=function(){};p.prototype.getComponents=function(t,e,n,o){void 0===n&&(n=!1);var r=[],i={};return e.filter((function(t){return Array.isArray(t)})).map((function(e){var n=[];e.map((function(e){var r=n.length?[].concat(n[0].parts):[];r.push(e);var i=[].concat(r);"string"==typeof o||!1===o&&void 0!==o||!((t||{}).$options||{}).name||(o=t.$options.name.match(/[A-Z][a-z]+/g).map((function(t){return t.toLowerCase()})).join("-")),o&&i.unshift(o);var a=i.map((function(t){return t.toLowerCase().replace(/--|_/g,"-")})).join("-"),s=a.replace(/((\b|[^a-zA-Z0-9]+)[a-zA-Z0-9])/gi,(function(t,e,n){return t.toUpperCase().replace(n,"")})),u=!1;for(var p of[a,s])if(void 0!==(((t||{}).$options||{}).components||{})[p]){u=!0;break}n.unshift({global:u,kebab:a,parts:r,pascal:s,prefix:o})})),n.map((function(t){i[t.pascal]||(i[t.pascal]=!0,r.push(t))}))})),r.filter((function(t){return t.global||!!n})).sort((function(t,e){return e.parts.length-t.parts.length}))},p.prototype.getModuleData=async function(t){if("function"!=typeof((t||{}).$options||{}).druxt)return!1;var e=await t.$options.druxt({vm:t});return(t.$options||{}).name&&(e.name=t.$options.name.match(/[A-Z][a-z]+/g).map((function(t){return t.toLowerCase()})).join("-")),e};var c=function(t,e){if(void 0===e&&(e={}),!t)throw new Error("The 'baseUrl' parameter is required.");var o={baseURL:t};"object"==typeof e.axios&&(o=Object.assign(o,e.axios),delete e.axios),this.axios=n.create(o),this.options=Object.assign({},{endpoint:"/jsonapi",jsonapiResourceConfig:"jsonapi_resource_config--jsonapi_resource_config"},e)};c.prototype.addHeaders=function(t){if(void 0===t)return!1;for(var e in t)this.axios.defaults.headers.common[e]=t[e]},c.prototype.buildQueryUrl=function(t,e){return e?"string"==typeof e?"?"===e.charAt(0)?t+e:[t,e].join("?"):"object"==typeof e&&"function"==typeof e.getQueryString?[t,e.getQueryString()].join("?"):"object"==typeof e&&Object.keys(e).length?[t,o.stringify(e)].join("?"):t:t},c.prototype.checkPermissions=function(t){if(t.data.meta&&t.data.meta.omitted){var e={};for(var n in delete t.data.meta.omitted.links.help,t.data.meta.omitted.links){var o=t.data.meta.omitted.links[n].meta.detail.match(/'(.*?)'/);o&&o[1]&&(e[o[1]]=!0)}if(Object.keys(e).length)throw new TypeError(t.data.meta.omitted.detail+"\n\n Required permissions: "+Object.keys(e).join(", ")+".")}},c.prototype.getCollection=async function(t,e){var n=(await this.getIndex(t)).href;if(!n)return!1;var o=this.buildQueryUrl(n,e),r=await this.axios.get(o);return this.checkPermissions(r),r.data},c.prototype.getCollectionAll=async function(t,e){var n=[],o=await this.getCollection(t,e);for(n.push(o);((o.links||{}).next||{}).href;)e=o.links.next.href.split("?")[1],o=await this.getCollection(t,e),n.push(o);return n},c.prototype.getIndex=async function(t){if(this.index&&!t)return this.index;if(this.index&&t)return!!this.index[t]&&this.index[t];var e=await this.axios.get(this.options.endpoint);if(this.index=e.data.links,this.index[this.options.jsonapiResourceConfig]){var n=await this.axios.get(this.index[this.options.jsonapiResourceConfig].href);for(var o in n.data.data){var r=n.data.data[o],i=r.attributes.drupal_internal__id.split("--"),a={resourceType:r.attributes.resourceType,entityType:i[0],bundle:i[1],resourceFields:r.attributes.resourceFields},s=[a.entityType,a.bundle].join("--");this.index[s]=Object.assign({},a,this.index[s])}}return t?!!this.index[t]&&this.index[t]:this.index},c.prototype.getResource=async function(t,e,n){if(!e||!t)return!1;var o=(await this.getIndex(t)).href;o||(o=this.options.endpoint+"/"+t.replace("--","/"));var r=this.buildQueryUrl(o+"/"+e,n);try{return(await this.axios.get(r)).data}catch(t){return!1}};var d={components:{DruxtWrapper:s},data:function(){return{component:{is:"DruxtWrapper",options:[],propsData:{}}}},props:{wrapper:{type:Object,default:function(){return{component:"div",propsData:{}}}}},fetch:async function(){var t=new p,e=await t.getModuleData(this);if(this.component.propsData=e.propsData||{},e.componentOptions){var n=t.getComponents(this,e.componentOptions,!0);this.component.options=n.map((function(t){return t.pascal}));var o=n.filter((function(t){return t.global}));o.length&&(this.component.is=o[0].pascal)}}};return t.Druxt=a,t.DruxtClass=p,t.DruxtClient=c,t.DruxtComponentMixin=d,t.DruxtStore=function(t){var e=t.store;if(void 0===e)throw new TypeError("Vuex store not found.");var n="druxt",o={namespaced:!0,state:function(){return{collections:{},resources:{}}},mutations:{addCollection:function(t,e){var n=e.collection,o=e.type,r=e.hash;t.collections[o]||(t.collections[o]={}),t.collections[o][r]=n},addResource:function(t,e){var n=e.resource,o=e.hash,r=(n||{}).data||{},i=r.id,a=r.type;i&&a&&(t.resources[a]||(t.resources[a]={}),t.resources[a][i]||(t.resources[a][i]={}),t.resources[a][i][o]=n)}},actions:{getCollection:async function(t,e){var n=t.commit,o=t.state,i=e.type,a=e.query,s=a?r(this.$druxt.buildQueryUrl("",a)):"_default";if((o.collections[i]||{})[s])return o.collections[i][s];var u=await this.$druxt.getCollection(i,a);return n("addCollection",{collection:u,type:i,hash:s}),((u||{}).data||[]).map((function(t){n("addResource",{resource:{data:t},hash:s})})),u},getResource:async function(t,e){var n=t.commit,o=t.state,i=e.type,a=e.id,s=e.query,u=s?r(this.$druxt.buildQueryUrl("",s)):"_default";if(void 0!==((o.resources[i]||{})[a]||{})[u])return o.resources[i][a][u];var p=await this.$druxt.getResource(i,a,s);return n("addResource",{resource:p,hash:u}),p}}};e.registerModule(n,o,{preserveState:Boolean(e.state.druxt)})},t.DruxtWrapper=s,t.default=u,t}({},path,axios,querystring,md5);
var Druxt=function(t,e,n,o,r,i,s){"use strict";function a(t,e,n,o,r,i,s,a,p,u){"boolean"!=typeof s&&(p=a,a=s,s=!1);var c,d="function"==typeof n?n.options:n;if(t&&t.render&&(d.render=t.render,d.staticRenderFns=t.staticRenderFns,d._compiled=!0,r&&(d.functional=!0)),o&&(d._scopeId=o),i?(c=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),e&&e.call(this,p(t)),t&&t._registeredComponents&&t._registeredComponents.add(i)},d._ssrRegister=c):e&&(c=s?function(t){e.call(this,u(t,this.$root.$options.shadowRoot))}:function(t){e.call(this,a(t))}),c)if(d.functional){var l=d.render;d.render=function(t,e){return c.call(e),l(t,e)}}else{var f=d.beforeCreate;d.beforeCreate=f?[].concat(f,c):[c]}return n}n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n,i=i&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i,s=s&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s;var p=a({},undefined,{name:"Druxt",props:{inner:{type:[Object,Boolean],default:function(){return{component:"div",propsData:{}}}},module:{type:String,required:!0},propsData:{type:Object,default:function(){return{}}},wrapper:{type:[Object,Boolean],default:function(){return{component:"div",propsData:{}}}}},data:function(){return{component:{is:void 0,propsData:{}}}},created:function(){this.setModuleComponent()},methods:{setModuleComponent:function(){var t="Druxt"+this.module.split("-").map((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})).join("");this.$options.components[t]&&(this.component.is=t,this.component.propsData=this.propsData)}},render:function(t){var e=t(this.component.is,{props:Object.assign({},{wrapper:this.inner},this.component.propsData,this.$attrs)});return(this.wrapper||{}).component?t(this.wrapper.component,{props:this.wrapper.propsData},[e]):e}},undefined,undefined,undefined,!1,void 0,void 0,void 0),u=a({render:function(){var t=this,e=t.$createElement;return(t._self._c||e)("div",[t._t("default")],2)},staticRenderFns:[]},undefined,{name:"DruxtWrapper"},undefined,false,undefined,!1,void 0,void 0,void 0),c=function(t){void 0===t&&(t={});var n=Object.assign({},t,(this.options||{}).druxt);this.addPlugin({src:e.resolve(__dirname,"../nuxt/plugin.js"),fileName:"druxt.js",options:n}),this.addPlugin({src:e.resolve(__dirname,"../nuxt/store.js"),fileName:"store/druxt.js",options:n}),this.options.store=!0};c.meta=require("../package.json");var d=function(t,e){if(void 0===e&&(e={}),!t)throw new Error("The 'baseUrl' parameter is required.");var o={baseURL:t};"object"==typeof e.axios&&(o=Object.assign(o,e.axios),delete e.axios),this.axios=n.create(o),this.options=Object.assign({},{endpoint:"/jsonapi",jsonapiResourceConfig:"jsonapi_resource_config--jsonapi_resource_config"},e)};d.prototype.addHeaders=function(t){if(void 0===t)return!1;for(var e in t)this.axios.defaults.headers.common[e]=t[e]},d.prototype.buildQueryUrl=function(t,e){return e?"string"==typeof e?"?"===e.charAt(0)?t+e:[t,e].join("?"):"object"==typeof e&&"function"==typeof e.getQueryString?[t,e.getQueryString()].join("?"):"object"==typeof e&&Object.keys(e).length?[t,o.stringify(e)].join("?"):t:t},d.prototype.checkPermissions=function(t){if(t.data.meta&&t.data.meta.omitted){var e={};for(var n in delete t.data.meta.omitted.links.help,t.data.meta.omitted.links){var o=t.data.meta.omitted.links[n].meta.detail.match(/'(.*?)'/);o&&o[1]&&(e[o[1]]=!0)}if(Object.keys(e).length)throw new TypeError(t.data.meta.omitted.detail+"\n\n Required permissions: "+Object.keys(e).join(", ")+".")}},d.prototype.getCollection=async function(t,e){var n=(await this.getIndex(t)).href;if(!n)return!1;var o=this.buildQueryUrl(n,e),r=await this.axios.get(o);return this.checkPermissions(r),r.data},d.prototype.getCollectionAll=async function(t,e){var n=[],o=await this.getCollection(t,e);for(n.push(o);((o.links||{}).next||{}).href;)e=o.links.next.href.split("?")[1],o=await this.getCollection(t,e),n.push(o);return n},d.prototype.getIndex=async function(t){if(this.index&&!t)return this.index;if(this.index&&t)return!!this.index[t]&&this.index[t];var e=await this.axios.get(this.options.endpoint);if(this.index=e.data.links,this.index[this.options.jsonapiResourceConfig]){var n=await this.axios.get(this.index[this.options.jsonapiResourceConfig].href);for(var o in n.data.data){var r=n.data.data[o],i=r.attributes.drupal_internal__id.split("--"),s={resourceType:r.attributes.resourceType,entityType:i[0],bundle:i[1],resourceFields:r.attributes.resourceFields},a=[s.entityType,s.bundle].join("--");this.index[a]=Object.assign({},s,this.index[a])}}return t?!!this.index[t]&&this.index[t]:this.index},d.prototype.getResource=async function(t,e,n){if(!e||!t)return!1;var o=(await this.getIndex(t)).href;o||(o=this.options.endpoint+"/"+t.replace("--","/"));var r=this.buildQueryUrl(o+"/"+e,n);try{return(await this.axios.get(r)).data}catch(t){return!1}};var l=a({},undefined,{components:{DruxtWrapper:u},props:{wrapper:{type:Object,default:function(){return{component:"div",propsData:{}}}}},fetch:async function(){if(!(this.$options||{}).druxt)return!1;var t=this.getModuleComponents(),e={is:((t.filter((function(t){return t.global}))||[])[0]||{}).name||"DruxtWrapper",options:t.map((function(t){return t.name}))||[]},n=await this.getWrapperData(e.is);e.settings=n.druxt||{},e=Object.assign({},e,this.getModulePropsData(n.props)),this.component=e},data:function(){return{component:{$attrs:{},is:"DruxtWrapper",options:[],props:{},propsData:{},settings:{}}}},methods:{getModuleComponents:function(){var t=this;if(!(this.$options.druxt||{}).componentOptions)return[];var e=this.$options.druxt.componentOptions.call(this,this);if(!e||!e.length)return[];var n,o=[],i=function(){var e=[];o=o.concat(s.map((function(n){var o=e.length?[].concat(e[0].parts):[];o.push(r.pascalCase(r.splitByCase(n)));var i=r.pascalCase([t.$options.name].concat(o)),s=!!t.$options.components[i];return e.unshift({global:s,name:i,parts:o}),{global:s,name:i,parts:o}})))};for(var s of e.filter((function(t){return Array.isArray(t)})))i();return o.filter((n=new Set,function(t){return!n.has(t.name)&&n.add(t.name)})).sort((function(t,e){return e.parts.length-t.parts.length}))},getModulePropsData:function(t){if(void 0===t&&(t={}),!(this.$options.druxt||{}).propsData)return{};var e=this.$options.druxt.propsData.call(this,this),n={},o=Object.keys(t).filter((function(t){return Object.keys(e).includes(t)}));for(var r of o)n[r]=e[r];var i=Object.assign({},this.$attrs),s=Object.keys(e).filter((function(e){return!Object.keys(t).includes(e)}));for(var a of s)i[a]=e[a];return{$attrs:i,props:n,propsData:e}},getScopedSlots:function(){var t=this;return{default:function(){return t.$createElement("div",[JSON.stringify(t.component.propsData)])}}},getWrapperData:async function(t){var e={druxt:{},props:{}};if(!this.$options.components[t])return e;this.$options.components[t].options?e=this.$options.components[t].options:"function"==typeof this.$options.components[t]&&this._init&&(e=await this.$options.components[t].call(this)||{});var n=i.util.mergeOptions({},e);return{druxt:n.druxt||{},props:n.props||{}}}},render:function(t){var e={class:this.wrapper.class||void 0,style:this.wrapper.style||void 0,props:this.wrapper.propsData};return this.$fetchState.pending?t(this.wrapper.component,e):t(this.wrapper.component,e,[t(this.component.is,{attrs:this.component.$attrs,props:this.component.props,scopedSlots:this.getScopedSlots()})])}},undefined,undefined,undefined,!1,void 0,void 0,void 0),f=function(){};f.prototype.getComponents=function(t,e,n,o){void 0===n&&(n=!1);var r=[],i={};return e.filter((function(t){return Array.isArray(t)})).map((function(e){var n=[];e.map((function(e){var r=n.length?[].concat(n[0].parts):[];r.push(e);var i=[].concat(r);"string"==typeof o||!1===o&&void 0!==o||!((t||{}).$options||{}).name||(o=t.$options.name.match(/[A-Z][a-z]+/g).map((function(t){return t.toLowerCase()})).join("-")),o&&i.unshift(o);var s=i.map((function(t){return t.toLowerCase().replace(/--|_/g,"-")})).join("-"),a=s.replace(/((\b|[^a-zA-Z0-9]+)[a-zA-Z0-9])/gi,(function(t,e,n){return t.toUpperCase().replace(n,"")})),p=!1;for(var u of[s,a])if(void 0!==(((t||{}).$options||{}).components||{})[u]){p=!0;break}n.unshift({global:p,kebab:s,parts:r,pascal:a,prefix:o})})),n.map((function(t){i[t.pascal]||(i[t.pascal]=!0,r.push(t))}))})),r.filter((function(t){return t.global||!!n})).sort((function(t,e){return e.parts.length-t.parts.length}))},f.prototype.getModuleData=async function(t){if("function"!=typeof((t||{}).$options||{}).druxt)return!1;var e=await t.$options.druxt({vm:t});return(t.$options||{}).name&&(e.name=t.$options.name.match(/[A-Z][a-z]+/g).map((function(t){return t.toLowerCase()})).join("-")),e};var h={components:{DruxtWrapper:u},data:function(){return{component:{is:"DruxtWrapper",options:[],propsData:{}}}},props:{wrapper:{type:Object,default:function(){return{component:"div",propsData:{}}}}},fetch:async function(){console.warn("DruxtComponentMixin is deprecated in favour of DruxtModule.");var t=new f,e=await t.getModuleData(this);if(this.component.propsData=e.propsData||{},e.componentOptions){var n=t.getComponents(this,e.componentOptions,!0);this.component.options=n.map((function(t){return t.pascal}));var o=n.filter((function(t){return t.global}));o.length&&(this.component.is=o[0].pascal)}}};return t.Druxt=p,t.DruxtClass=f,t.DruxtClient=d,t.DruxtComponentMixin=h,t.DruxtModule=l,t.DruxtStore=function(t){var e=t.store;if(void 0===e)throw new TypeError("Vuex store not found.");var n="druxt",o={namespaced:!0,state:function(){return{collections:{},resources:{}}},mutations:{addCollection:function(t,e){var n=e.collection,o=e.type,r=e.hash;t.collections[o]||(t.collections[o]={}),t.collections[o][r]=n},addResource:function(t,e){var n=e.resource,o=e.hash,r=(n||{}).data||{},i=r.id,s=r.type;i&&s&&(t.resources[s]||(t.resources[s]={}),t.resources[s][i]||(t.resources[s][i]={}),t.resources[s][i][o]=n)}},actions:{getCollection:async function(t,e){var n=t.commit,o=t.state,r=e.type,i=e.query,a=i?s(this.$druxt.buildQueryUrl("",i)):"_default";if((o.collections[r]||{})[a])return o.collections[r][a];var p=await this.$druxt.getCollection(r,i);return n("addCollection",{collection:p,type:r,hash:a}),((p||{}).data||[]).map((function(t){n("addResource",{resource:{data:t},hash:a})})),p},getResource:async function(t,e){var n=t.commit,o=t.state,r=e.type,i=e.id,a=e.query,p=a?s(this.$druxt.buildQueryUrl("",a)):"_default";if(void 0!==((o.resources[r]||{})[i]||{})[p])return o.resources[r][i][p];var u=await this.$druxt.getResource(r,i,a);return n("addResource",{resource:u,hash:p}),u}}};e.registerModule(n,o,{preserveState:Boolean(e.state.druxt)})},t.DruxtWrapper=u,t.default=c,t}({},path,axios,querystring,scule,Vue,md5);

@@ -1,2 +0,2 @@

'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'),md5=_interopDefault(require('md5'));/**
'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')),md5=_interopDefault(require('md5'));/**
* The Vue.js Druxt component.

@@ -338,126 +338,2 @@ *

*//**
* Druxt utility class.
*/
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 ) : [];
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('-');
}
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') {
global = true;
break
}
}
variants.unshift({ global: global, kebab: kebab, parts: parts, pascal: pascal, prefix: prefix });
});
// Add variants to results.
variants.map(function (variant) {
// Ensure unique results.
if (unique[variant.pascal]) {
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
}
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
};
/**
* @typedef {object} ModuleData
* @property {Array.<string[]>} componentOptions - An array of arrays of strings for component naming.
* @property {object} propsData - Property data to bind to the wrapper component.
*
* @example @lang js
* {
* componentOptions: [['wrapper', 'component']],
* propsData: {},
* }
*/
/**
* @typedef {object[]} WrapperComponents
* @property {boolean} global - Component global registration state.
* @property {string} kebab - The component name in kebab case.
* @property {string[]} parts - The component naming parts.
* @property {string} pascal - The component name in pascal case.
* @property {string} prefix - The component name prefix.
*
* @example @lang js
* [{
* global: true,
* kebab: 'druxt-test-module-wrapper',
* parts: ['wrapper'],
* pascal: 'DruxtTestModuleWrapper',
* prefix: 'druxt-test-module',
* }]
*//**
* Druxt JSON:API client.

@@ -751,35 +627,23 @@ */

*//**
* Vue.js Mixin to add Druxt component theming to a Druxt module.
* The DruxtModule base Vue.js component.
*
* @name DruxtComponentMixin
* @see {@link /guide/#component-theme-system|Wrapper theme system}
* Extend this component to build a Druxt module.
*
* @example @lang vue <caption>CustomDruxtModule.vue</caption>
* <template>
* <component :is="component.is" v-bind="component.propsData">
* <!-- -->
* </component>
* </template>
*
* <script>
* import { DruxtComponentMixin } from 'druxt'
* @example @lang js
* import { DruxtModule } from 'druxt'
* export default {
* mixins: [DruxtComponentMixin]
* name: 'DruxtTestModule',
* extends: DruxtModule,
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
* </script>
*/
var DruxtComponentMixin = {
var script$2 = {
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: {

@@ -801,48 +665,250 @@ wrapper: {

* **Important:** If your component has an existing `fetch` method, you must manually invoke
* the `DruxtComponentMixin.fetch()` hook.
* the `DruxtModule.fetch()` hook.
*
* @see {@link https://nuxtjs.org/api/pages-fetch/}
*
* @example @lang vue <caption>Manually invoking DruxtComponentMixin.fetch().</caption>
* <script>
* import { DruxtComponentMixin } from 'druxt'
* @example @lang js <caption>Manually invoking DruxtModule.fetch().</caption>
* import { DruxtModule } from 'druxt'
* export default {
* mixins: [DruxtComponentMixin],
*
* async fetch {
* await DruxtComponentMixin.fetch.call(this)
* name: 'DruxtTestModule',
* extends: DruxtModule,
* async fetch() {
* await DruxtModule.fetch.call(this)
* }
* druxt: {
* componentOptions: () => ([['wrapper']]),
* propsData: (ctx) => ({
* bar: ctx.bar,
* foo: ctx.foo,
* }),
* }
* }
* </script>
*/
fetch: async function fetch() {
// @todo - check for this.$druxt plugin.
var druxt = new DruxtClass();
var moduleData = await druxt.getModuleData(this);
if (!(this.$options || {}).druxt) {
return false
}
this.component.propsData = moduleData.propsData || {};
// 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; }) || [],
};
if (!moduleData.componentOptions) {
return
// 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.
*/
data: function () { return ({
component: {
$attrs: {},
is: 'DruxtWrapper',
options: [],
props: {},
propsData: {},
settings: {},
},
}); },
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);
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 }
},
/**
* Get default scoped slots.
*
* Default output is a `JSON.stringify`'d result of the modules propsData.
*
* This method should be overridden in a Druxt modules.
*
* @example js
* getScopedSlots() {
* return {
* default: () => this.$createElement('div', ['Hello world'])
* }
* }
*
* @return {object}
*/
getScopedSlots: function getScopedSlots() {
var this$1 = this;
return {
default: function () { return this$1.$createElement('div', [JSON.stringify(this$1.component.propsData)]); }
}
},
/**
* 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 || {},
}
}
},
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
render: function render(h) {
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)
}
this.component.is = available[0].pascal;
},
// Return wrapped component.
return h(this.wrapper.component, wrapperData, [
h(this.component.is, {
attrs: this.component.$attrs,
props: this.component.props,
scopedSlots: this.getScopedSlots(),
})
])
}
};
/**
* @typedef {object} Component
* @property {string} is=DruxtWrapper - The rendered component name.
* @property {string[]} options - The possible component name options.
* @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',

@@ -852,5 +918,59 @@ * options: [

* ],
* propsData: {},
* props: { foo: 'bar' },
* propsData: {
* bar: 'foo',
* foo: 'bar',
* },
* settings: { fooBar: true },
* }
*/var DruxtStore = function (ref) {
*/
/**
* @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-38c77b16";
/* 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 DruxtStore = function (ref) {
var store = ref.store;

@@ -1103,2 +1223,172 @@

* @see {@link https://www.npmjs.com/package/drupal-jsonapi-params}
*/exports.Druxt=__vue_component__;exports.DruxtClass=DruxtClass;exports.DruxtClient=DruxtClient;exports.DruxtComponentMixin=DruxtComponentMixin;exports.DruxtStore=DruxtStore;exports.DruxtWrapper=__vue_component__$1;exports.default=DruxtNuxtModule;
*//**
* 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 ) : [];
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('-');
}
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') {
global = true;
break
}
}
variants.unshift({ global: global, kebab: kebab, parts: parts, pascal: pascal, prefix: prefix });
});
// Add variants to results.
variants.map(function (variant) {
// Ensure unique results.
if (unique[variant.pascal]) {
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
}
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: {},
}); }
}
},
/**
* 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
}
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;
{
"name": "druxt",
"version": "0.4.2",
"description": "A Bridge between frameworks, NuxtJS in the front, Drupal in the back.",
"version": "0.5.0",
"description": "A Bridge between frameworks, Nuxt.js in the front, Drupal in the back.",
"repository": {

@@ -10,8 +10,18 @@ "type": "git",

"keywords": [
"cms",
"decoupled",
"drupal",
"druxt",
"headless",
"jsonapi",
"nuxt"
"json:api",
"nuxt",
"module",
"vue"
],
"author": "Stuart Clark <stuart@realityloop.com> (realityloop.com)",
"author": {
"name": "Stuart Clark",
"email": "stuart@realityloop.com",
"url": "https://realityloop.com"
},
"license": "MIT",

@@ -51,2 +61,3 @@ "bugs": {

"querystring": "^0.2.0",
"scule": "^0.1.1",
"vuex": "^3.6.0"

@@ -53,0 +64,0 @@ },

@@ -8,3 +8,3 @@ # DruxtJS; A bridge between frameworks.

> DruxtJS provides an easy connection between a Drupal JSON:API backend and NuxtJS frontend application.
> DruxtJS provides an easy connection between a Drupal JSON:API backend and Nuxt.js frontend application.

@@ -24,5 +24,5 @@

### DruxtClient
### Drupal JSON:API client
The DruxtClient is the communication layer between Nuxt and the Drupal JSON:API.
Two methods of communication with the Drupal JSON:API are provided by Druxt, a framework agnostic [**DruxtClient**](https://druxtjs.org/api/client) and the [**DruxtStore**](https://druxtjs.org/api/stores/druxt) Vuex module, which adds an additional cache layer.

@@ -32,8 +32,7 @@ **Example:**

const { DruxtClient } = require('druxt')
const druxt = new DruxtClient('https://demo-api.druxtjs.org')
druxt.getCollection('node--page').then((res) => {
...
})
new DruxtClient('https://demo-api.druxtjs.org')
.getCollection('node--page')
.then((res) => {
// Do the thing!
})
```

@@ -51,5 +50,3 @@

module.exports = {
modules: [
'druxt'
],
modules: ['druxt'],
druxt: {

@@ -68,4 +65,2 @@ baseUrl: 'https://demo-api.druxtjs.org'

export default {
data: () => ({ page: null }),
async fetch() {

@@ -77,2 +72,3 @@ this.page = await this.$druxt.getResource({

},
data: () => ({ page: null }),
}

@@ -82,25 +78,22 @@ </script>

### The Druxt component
## Themable modules
Druxt provides a Vue.js component to easily access Drupal's JSON:API data, with a simple Slot based theming system.
Druxt uses a Module and slot-based Wrapper component system, making it easy to render and theme Drupal data.
```vue
<Druxt :module="module" :props-data="propsData" :wrapper="wrapper" />
```
Find more details in the [Guide](https://druxtjs.org/guide/)
Get started with the [Guide](https://druxtjs.org/guide/) and [API Documentation](https://druxtjs.org/api/components/Druxt.html).
## Community support
## Join the community
Druxt is an open source project, built by the comunity for the community.
DruxtJS is an open source project, built by the comunity for the community.
Find support or get involved in building Druxt via the community channels:
- [DruxtJS Discord server](https://discord.druxtjs.org)
- **#druxt** Slack channel on [Drupal.org slack](https://drupal.org/slack)
Find support or get involved in building Druxt via our community channels:
- [DruxtJS Discord server](https://discord.druxtjs.org)
- #druxt Slack channel on [Drupal.org slack](https://drupal.org/slack)
## Fully decoupled Drupal sites
The [**DruxtSite**](https://site.druxtjs.org) module provides minimal configuration, decoupled Drupal site functionality.
## Decoupled sites
The [DruxtJS Site module](http://site.druxtjs.org/) provides minimal configuration, decoupled Drupal site functionality.
Try out the [Umami demo](https://demo.druxtjs.org), or checkout the source for the [Nuxt.js frontend](https://github.com/druxt/demo.druxtjs.org) and the [Drupal 9 backend](https://github.com/druxt/demo-api.druxtjs.org).
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