Comparing version 0.4.2 to 0.5.0
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). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
95106
2500
6
93
+ Addedscule@^0.1.1
+ Addedscule@0.1.1(transitive)