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.5.1 to 0.6.0

203

dist/druxt.esm.js

@@ -6,2 +6,4 @@ import { resolve } from 'path';

import Vue from 'vue';
import { DrupalJsonApiParams } from 'drupal-jsonapi-params';
import merge from 'deepmerge';
import md5 from 'md5';

@@ -436,4 +438,4 @@

// If Query is object with 'getQueryString' function, (e.g., drupal-jsonapi-params)...
if (typeof query === 'object' && typeof query.getQueryString === 'function') {
return [url, query.getQueryString()].join('?')
if (typeof query === 'object' && typeof query.getQueryString === 'function' && (query = query.getQueryString())) {
return [url, query].join('?')
}

@@ -998,2 +1000,39 @@

var getDrupalJsonApiParams = function (query) {
var apiParams = new DrupalJsonApiParams();
if (!query) {
return apiParams
}
typeof query === 'object'
? apiParams.initializeWithQueryObject(typeof query.getQueryObject === 'function' ? query.getQueryObject() : query)
: apiParams.initializeWithQueryString(query);
return apiParams
};
var dehydrateResources = function (ref) {
var commit = ref.commit;
var queryObject = ref.queryObject;
var resources = ref.resources;
return resources.map(function (data) {
// Generate a query link for included resources.
// This is used to determine if the resource is a partial.
var link = decodeURI(((data.links || {}).self || {}).href || '');
var href = typeof (queryObject.fields || {})[data.type] === 'string'
? [link.split('?')[0], ("fields[" + (data.type) + "]=" + (queryObject.fields[data.type]))].join('?')
: link;
// Commit the included resource.
commit('druxt/addResource', {
resource: {
data: data,
links: { self: { href: href } },
}
});
return { id: data.id, type: data.type }
})
};
var DruxtStore = function (ref) {

@@ -1054,2 +1093,20 @@ var store = ref.store;

if (!state.collections[type]) { Vue.set(state.collections, type, {}); }
// Parse the query.
var link = decodeURI((((collection || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Store and dehydrate collection resources.
collection.data = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.data });
// Extract and store included resources.
if (collection.included) {
collection.included = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.included });
delete collection.included;
}
// Recursively merge new collection data into stored collection.
collection = merge(state.collections[type][hash] || {}, collection, { arrayMerge: function (dst, src) { return src; } });
Vue.set(state.collections[type], hash, collection);

@@ -1064,3 +1121,3 @@ },

* @example @lang js
* this.$store.commit('druxt/addResource', { resource, hash })
* this.$store.commit('druxt/addResource', { resource })
*/

@@ -1071,2 +1128,6 @@ addResource: function addResource (state, ref) {

if (hash) {
console.warn('[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/guide/deprecations.html#druxtstore-addresource-hash');
}
var ref$1 = (resource || {}).data || {};

@@ -1080,5 +1141,24 @@ var id = ref$1.id;

// Parse the query.
var link = decodeURI((((resource || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Add cache flag to resource.
var flag = typeof (queryObject.fields || {})[((resource || {}).data || {}).type] === 'string' ? '_druxt_partial' : '_druxt_full';
resource[flag] = Date.now();
// Ensure Resource type array is reactive.
if (!state.resources[type]) { Vue.set(state.resources, type, {}); }
if (!state.resources[type][id]) { Vue.set(state.resources[type], id, {}); }
Vue.set(state.resources[type][id], hash, resource);
// Extract and store included data.
if (resource.included) {
dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: resource.included });
delete resource.included;
}
// Recursively merge new resource data into stored resource.
resource = merge(state.resources[type][id] || {}, resource, { arrayMerge: function (dst, src) { return src; } });
Vue.set(state.resources[type], id, resource);
},

@@ -1112,14 +1192,18 @@ },

var hash = query ? md5(this.$druxt.buildQueryUrl('', query)) : '_default';
// Generate a hash using query data excluding the 'fields' and 'include' data.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
var hash = query ? md5(JSON.stringify(Object.assign({}, queryObject, {fields: {}, include: []}))) : '_default';
// If collection hash exists, re-hydrate and return the data.
if ((state.collections[type] || {})[hash]) {
return state.collections[type][hash]
return Object.assign({}, state.collections[type][hash],
// Hydrate resource data.
{data: state.collections[type][hash].data.map(function (o) { return (state.resources[o.type][o.id] || {}).data; })})
}
// Get the collection using the DruxtClient instance.
var collection = await this.$druxt.getCollection(type, query);
commit('addCollection', { collection: collection, type: type, hash: hash });
var data = (collection || {}).data || [];
data.map(function (resource) {
commit('addResource', { resource: { data: resource }, hash: hash });
});
// Store the collection in the DruxtStore.
commit('addCollection', { collection: Object.assign({}, collection), type: type, hash: hash });

@@ -1146,2 +1230,3 @@ return collection

var commit = ref.commit;
var dispatch = ref.dispatch;
var state = ref.state;

@@ -1152,11 +1237,91 @@ var type = ref$1.type;

var hash = query ? md5(this.$druxt.buildQueryUrl('', query)) : '_default';
if (typeof ((state.resources[type] || {})[id] || {})[hash] !== 'undefined') {
return state.resources[type][id][hash]
// Get the resource from the store if it's avaialble.
var storedResource = (state.resources[type] || {})[id] ?
Object.assign({}, state.resources[type][id])
: null;
// Parse the query.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Ensure that includes are in the fields filter.
if (queryObject.include && typeof (queryObject.fields || {})[type] === 'string') {
var fields$1 = queryObject.fields[type].split(',').filter(function (s) { return s; });
var includes = queryObject.include.split(',').filter(function (s) { return s && !s.includes('.'); });
queryObject.fields[type] = Array.from(
new Set(fields$1.concat( includes))
).filter(function (s) { return s; }).join(',');
}
var resource = await this.$druxt.getResource(type, id, query);
commit('addResource', { resource: resource, hash: hash });
// Hydrate included data based on the include query.
var included = [];
if (queryObject.include && storedResource) {
// Request included resources from druxt/getResource.
var resources =
await Promise.all(queryObject.include.split(',')
.filter(function (s) { return Object.keys((storedResource.data.relationships || {})).includes(s); })
.map(function (key) {
var ref = storedResource.data.relationships[key];
var data = ref.data;
data = Array.isArray(data) ? data : [data];
return resource
// Get any sub-includes, e.g., `media,media.image` becomes `image`.
var include = queryObject.include.split(',')
.filter(function (s) { return s.startsWith((key + ".")); })
.map(function (s) { return s.slice(key.length + 1); })
.join(',');
return data.filter(function (o) { return typeof o === 'object' && o; }).map(function (o) {
return dispatch('getResource', {
type: o.type,
id: o.id,
query: Object.assign({}, queryObject, {include: include}),
})
})
})
.flat()
);
// Merge all nested, included resources.
for (var include of resources) {
included = included.concat( [include.data], include.included || []);
}
storedResource.included = included;
}
// Return if we have the full resource.
if ((storedResource || {})._druxt_full) {
return storedResource
}
var isFull = typeof (queryObject.fields || {})[type] !== 'string';
// Determine if we have all the requested field data.
var fields = isFull ? true : (queryObject.fields || {})[type];
if (storedResource && !isFull && fields) {
var queryFields = fields.split(',');
var resourceFields = Object.keys(((storedResource || {}).data || {}).attributes || {}).concat( Object.keys(((storedResource || {}).data || {}).relationships || {}) );
var missingFields = queryFields.filter(function (key) { return !resourceFields.includes(key); });
fields = !!missingFields.length;
// Modify query to load additional fields, if required.
queryObject.fields[type] = (missingFields || []).join(',') || undefined;
}
// Request the resource from the DruxtClient if required.
var resource;
if (!storedResource || fields) {
resource = await this.$druxt.getResource(type, id, getDrupalJsonApiParams(queryObject));
commit('addResource', { resource: Object.assign({}, resource) });
}
// Build resource to be returned.
var result = Object.assign({}, (state.resources[type] || {})[id]);
// Merge included resources into resource.
if (queryObject.include && ((resource || {}).included || (storedResource || {}).included)) {
included = ( (resource || {}).included || [] ).concat( (storedResource || {}).included || [] );
result.included = Array.from(new Set(included.filter(function (o) { return (o || {}).id; }).map(function (o) { return o.id; })))
.map(function (id) { return included.find(function (o) { return o.id === id; }); });
}
return result
},

@@ -1198,3 +1363,2 @@ }

* @param {object} resource - The JSON:API resource.
* @param {string} hash - An md5 hash of the query string.
*

@@ -1208,3 +1372,2 @@ * @example @lang js

* },
* hash: '_default'
* }

@@ -1211,0 +1374,0 @@ */

2

dist/druxt.min.js

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

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]||i.set(t.collections,o,{}),i.set(t.collections[o],r,n)},addResource:function(t,e){var n=e.resource,o=e.hash,r=(n||{}).data||{},s=r.id,a=r.type;s&&a&&(t.resources[a]||i.set(t.resources,a,{}),t.resources[a][s]||i.set(t.resources[a],s,{}),i.set(t.resources[a][s],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);
var Druxt=function(t,e,n,r,o,i,s,a,u){"use strict";function c(t,e,n,r,o,i,s,a,u,c){"boolean"!=typeof s&&(u=a,a=s,s=!1);var p,d="function"==typeof n?n.options:n;if(t&&t.render&&(d.render=t.render,d.staticRenderFns=t.staticRenderFns,d._compiled=!0,o&&(d.functional=!0)),r&&(d._scopeId=r),i?(p=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=p):e&&(p=s?function(t){e.call(this,c(t,this.$root.$options.shadowRoot))}:function(t){e.call(this,a(t))}),p)if(d.functional){var l=d.render;d.render=function(t,e){return p.call(e),l(t,e)}}else{var f=d.beforeCreate;d.beforeCreate=f?[].concat(f,p):[p]}return n}n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n,i=i&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i,a=a&&Object.prototype.hasOwnProperty.call(a,"default")?a.default:a,u=u&&Object.prototype.hasOwnProperty.call(u,"default")?u.default:u;var p=c({},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),d=c({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),l=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};l.meta=require("../package.json");var f=function(t,e){if(void 0===e&&(e={}),!t)throw new Error("The 'baseUrl' parameter is required.");var r={baseURL:t};"object"==typeof e.axios&&(r=Object.assign(r,e.axios),delete e.axios),this.axios=n.create(r),this.options=Object.assign({},{endpoint:"/jsonapi",jsonapiResourceConfig:"jsonapi_resource_config--jsonapi_resource_config"},e)};f.prototype.addHeaders=function(t){if(void 0===t)return!1;for(var e in t)this.axios.defaults.headers.common[e]=t[e]},f.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&&(e=e.getQueryString())?[t,e].join("?"):"object"==typeof e&&Object.keys(e).length?[t,r.stringify(e)].join("?"):t:t},f.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 r=t.data.meta.omitted.links[n].meta.detail.match(/'(.*?)'/);r&&r[1]&&(e[r[1]]=!0)}if(Object.keys(e).length)throw new TypeError(t.data.meta.omitted.detail+"\n\n Required permissions: "+Object.keys(e).join(", ")+".")}},f.prototype.getCollection=async function(t,e){var n=(await this.getIndex(t)).href;if(!n)return!1;var r=this.buildQueryUrl(n,e),o=await this.axios.get(r);return this.checkPermissions(o),o.data},f.prototype.getCollectionAll=async function(t,e){var n=[],r=await this.getCollection(t,e);for(n.push(r);((r.links||{}).next||{}).href;)e=r.links.next.href.split("?")[1],r=await this.getCollection(t,e),n.push(r);return n},f.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 r in n.data.data){var o=n.data.data[r],i=o.attributes.drupal_internal__id.split("--"),s={resourceType:o.attributes.resourceType,entityType:i[0],bundle:i[1],resourceFields:o.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},f.prototype.getResource=async function(t,e,n){if(!e||!t)return!1;var r=(await this.getIndex(t)).href;r||(r=this.options.endpoint+"/"+t.replace("--","/"));var o=this.buildQueryUrl(r+"/"+e,n);try{return(await this.axios.get(o)).data}catch(t){return!1}};var h=c({},undefined,{components:{DruxtWrapper:d},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,r=[],i=function(){var e=[];r=r.concat(s.map((function(n){var r=e.length?[].concat(e[0].parts):[];r.push(o.pascalCase(o.splitByCase(n)));var i=o.pascalCase([t.$options.name].concat(r)),s=!!t.$options.components[i];return e.unshift({global:s,name:i,parts:r}),{global:s,name:i,parts:r}})))};for(var s of e.filter((function(t){return Array.isArray(t)})))i();return r.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={},r=Object.keys(t).filter((function(t){return Object.keys(e).includes(t)}));for(var o of r)n[o]=e[o];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),m=function(t){var e=new s.DrupalJsonApiParams;return t?("object"==typeof t?e.initializeWithQueryObject("function"==typeof t.getQueryObject?t.getQueryObject():t):e.initializeWithQueryString(t),e):e},y=function(t){var e=t.commit,n=t.queryObject;return t.resources.map((function(t){var r=decodeURI(((t.links||{}).self||{}).href||""),o="string"==typeof(n.fields||{})[t.type]?[r.split("?")[0],"fields["+t.type+"]="+n.fields[t.type]].join("?"):r;return e("druxt/addResource",{resource:{data:t,links:{self:{href:o}}}}),{id:t.id,type:t.type}}))},g=function(){};g.prototype.getComponents=function(t,e,n,r){void 0===n&&(n=!1);var o=[],i={};return e.filter((function(t){return Array.isArray(t)})).map((function(e){var n=[];e.map((function(e){var o=n.length?[].concat(n[0].parts):[];o.push(e);var i=[].concat(o);"string"==typeof r||!1===r&&void 0!==r||!((t||{}).$options||{}).name||(r=t.$options.name.match(/[A-Z][a-z]+/g).map((function(t){return t.toLowerCase()})).join("-")),r&&i.unshift(r);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,"")})),u=!1;for(var c of[s,a])if(void 0!==(((t||{}).$options||{}).components||{})[c]){u=!0;break}n.unshift({global:u,kebab:s,parts:o,pascal:a,prefix:r})})),n.map((function(t){i[t.pascal]||(i[t.pascal]=!0,o.push(t))}))})),o.filter((function(t){return t.global||!!n})).sort((function(t,e){return e.parts.length-t.parts.length}))},g.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 v={components:{DruxtWrapper:d},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 g,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 r=n.filter((function(t){return t.global}));r.length&&(this.component.is=r[0].pascal)}}};return t.Druxt=p,t.DruxtClass=g,t.DruxtClient=f,t.DruxtComponentMixin=v,t.DruxtModule=h,t.DruxtStore=function(t){var e=t.store;if(void 0===e)throw new TypeError("Vuex store not found.");var n="druxt",r={namespaced:!0,state:function(){return{collections:{},resources:{}}},mutations:{addCollection:function(t,e){var n=e.collection,r=e.type,o=e.hash;t.collections[r]||i.set(t.collections,r,{});var s=decodeURI((((n||{}).links||{}).self||{}).href||"").split("?")[1]||"",u=m(s).getQueryObject();n.data=y({commit:this.commit,queryObject:u,resources:n.data}),n.included&&(n.included=y({commit:this.commit,queryObject:u,resources:n.included}),delete n.included),n=a(t.collections[r][o]||{},n,{arrayMerge:function(t,e){return e}}),i.set(t.collections[r],o,n)},addResource:function(t,e){var n=e.resource;e.hash&&console.warn("[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/guide/deprecations.html#druxtstore-addresource-hash");var r=(n||{}).data||{},o=r.id,s=r.type;if(o&&s){var u=decodeURI((((n||{}).links||{}).self||{}).href||"").split("?")[1]||"",c=m(u).getQueryObject();n["string"==typeof(c.fields||{})[((n||{}).data||{}).type]?"_druxt_partial":"_druxt_full"]=Date.now(),t.resources[s]||i.set(t.resources,s,{}),n.included&&(y({commit:this.commit,queryObject:c,resources:n.included}),delete n.included),n=a(t.resources[s][o]||{},n,{arrayMerge:function(t,e){return e}}),i.set(t.resources[s],o,n)}}},actions:{getCollection:async function(t,e){var n=t.commit,r=t.state,o=e.type,i=e.query,s=m(i).getQueryObject(),a=i?u(JSON.stringify(Object.assign({},s,{fields:{},include:[]}))):"_default";if((r.collections[o]||{})[a])return Object.assign({},r.collections[o][a],{data:r.collections[o][a].data.map((function(t){return(r.resources[t.type][t.id]||{}).data}))});var c=await this.$druxt.getCollection(o,i);return n("addCollection",{collection:Object.assign({},c),type:o,hash:a}),c},getResource:async function(t,e){var n=t.commit,r=t.dispatch,o=t.state,i=e.type,s=e.id,a=e.query,u=(o.resources[i]||{})[s]?Object.assign({},o.resources[i][s]):null,c=m(a).getQueryObject();if(c.include&&"string"==typeof(c.fields||{})[i]){var p=c.fields[i].split(",").filter((function(t){return t})),d=c.include.split(",").filter((function(t){return t&&!t.includes(".")}));c.fields[i]=Array.from(new Set(p.concat(d))).filter((function(t){return t})).join(",")}var l=[];if(c.include&&u){var f=await Promise.all(c.include.split(",").filter((function(t){return Object.keys(u.data.relationships||{}).includes(t)})).map((function(t){var e=u.data.relationships[t].data;e=Array.isArray(e)?e:[e];var n=c.include.split(",").filter((function(e){return e.startsWith(t+".")})).map((function(e){return e.slice(t.length+1)})).join(",");return e.filter((function(t){return"object"==typeof t&&t})).map((function(t){return r("getResource",{type:t.type,id:t.id,query:Object.assign({},c,{include:n})})}))})).flat());for(var h of f)l=l.concat([h.data],h.included||[]);u.included=l}if((u||{})._druxt_full)return u;var y,g="string"!=typeof(c.fields||{})[i],v=!!g||(c.fields||{})[i];if(u&&!g&&v){var x=v.split(","),b=Object.keys(((u||{}).data||{}).attributes||{}).concat(Object.keys(((u||{}).data||{}).relationships||{})),j=x.filter((function(t){return!b.includes(t)}));v=!!j.length,c.fields[i]=(j||[]).join(",")||void 0}u&&!v||(y=await this.$druxt.getResource(i,s,m(c)),n("addResource",{resource:Object.assign({},y)}));var O=Object.assign({},(o.resources[i]||{})[s]);return c.include&&((y||{}).included||(u||{}).included)&&(l=((y||{}).included||[]).concat((u||{}).included||[]),O.included=Array.from(new Set(l.filter((function(t){return(t||{}).id})).map((function(t){return t.id})))).map((function(t){return l.find((function(e){return e.id===t}))}))),O}}};e.registerModule(n,r,{preserveState:Boolean(e.state.druxt)})},t.DruxtWrapper=d,t.default=l,t}({},path,axios,querystring,scule,Vue,drupalJsonapiParams,merge,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'),scule=require('scule'),Vue=_interopDefault(require('vue')),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')),drupalJsonapiParams=require('drupal-jsonapi-params'),merge=_interopDefault(require('deepmerge')),md5=_interopDefault(require('md5'));/**
* The Vue.js Druxt component.

@@ -416,4 +416,4 @@ *

// If Query is object with 'getQueryString' function, (e.g., drupal-jsonapi-params)...
if (typeof query === 'object' && typeof query.getQueryString === 'function') {
return [url, query.getQueryString()].join('?')
if (typeof query === 'object' && typeof query.getQueryString === 'function' && (query = query.getQueryString())) {
return [url, query].join('?')
}

@@ -972,3 +972,40 @@

undefined
);var DruxtStore = function (ref) {
);var getDrupalJsonApiParams = function (query) {
var apiParams = new drupalJsonapiParams.DrupalJsonApiParams();
if (!query) {
return apiParams
}
typeof query === 'object'
? apiParams.initializeWithQueryObject(typeof query.getQueryObject === 'function' ? query.getQueryObject() : query)
: apiParams.initializeWithQueryString(query);
return apiParams
};
var dehydrateResources = function (ref) {
var commit = ref.commit;
var queryObject = ref.queryObject;
var resources = ref.resources;
return resources.map(function (data) {
// Generate a query link for included resources.
// This is used to determine if the resource is a partial.
var link = decodeURI(((data.links || {}).self || {}).href || '');
var href = typeof (queryObject.fields || {})[data.type] === 'string'
? [link.split('?')[0], ("fields[" + (data.type) + "]=" + (queryObject.fields[data.type]))].join('?')
: link;
// Commit the included resource.
commit('druxt/addResource', {
resource: {
data: data,
links: { self: { href: href } },
}
});
return { id: data.id, type: data.type }
})
};
var DruxtStore = function (ref) {
var store = ref.store;

@@ -1028,2 +1065,20 @@

if (!state.collections[type]) { Vue.set(state.collections, type, {}); }
// Parse the query.
var link = decodeURI((((collection || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Store and dehydrate collection resources.
collection.data = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.data });
// Extract and store included resources.
if (collection.included) {
collection.included = dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: collection.included });
delete collection.included;
}
// Recursively merge new collection data into stored collection.
collection = merge(state.collections[type][hash] || {}, collection, { arrayMerge: function (dst, src) { return src; } });
Vue.set(state.collections[type], hash, collection);

@@ -1038,3 +1093,3 @@ },

* @example @lang js
* this.$store.commit('druxt/addResource', { resource, hash })
* this.$store.commit('druxt/addResource', { resource })
*/

@@ -1045,2 +1100,6 @@ addResource: function addResource (state, ref) {

if (hash) {
console.warn('[druxt] The `hash` argument for `druxt/addResource` has been deprecated, see https://druxtjs.org/guide/deprecations.html#druxtstore-addresource-hash');
}
var ref$1 = (resource || {}).data || {};

@@ -1054,5 +1113,24 @@ var id = ref$1.id;

// Parse the query.
var link = decodeURI((((resource || {}).links || {}).self || {}).href || '');
var query = link.split('?')[1] || '';
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Add cache flag to resource.
var flag = typeof (queryObject.fields || {})[((resource || {}).data || {}).type] === 'string' ? '_druxt_partial' : '_druxt_full';
resource[flag] = Date.now();
// Ensure Resource type array is reactive.
if (!state.resources[type]) { Vue.set(state.resources, type, {}); }
if (!state.resources[type][id]) { Vue.set(state.resources[type], id, {}); }
Vue.set(state.resources[type][id], hash, resource);
// Extract and store included data.
if (resource.included) {
dehydrateResources({ commit: this.commit, queryObject: queryObject, resources: resource.included });
delete resource.included;
}
// Recursively merge new resource data into stored resource.
resource = merge(state.resources[type][id] || {}, resource, { arrayMerge: function (dst, src) { return src; } });
Vue.set(state.resources[type], id, resource);
},

@@ -1086,14 +1164,18 @@ },

var hash = query ? md5(this.$druxt.buildQueryUrl('', query)) : '_default';
// Generate a hash using query data excluding the 'fields' and 'include' data.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
var hash = query ? md5(JSON.stringify(Object.assign({}, queryObject, {fields: {}, include: []}))) : '_default';
// If collection hash exists, re-hydrate and return the data.
if ((state.collections[type] || {})[hash]) {
return state.collections[type][hash]
return Object.assign({}, state.collections[type][hash],
// Hydrate resource data.
{data: state.collections[type][hash].data.map(function (o) { return (state.resources[o.type][o.id] || {}).data; })})
}
// Get the collection using the DruxtClient instance.
var collection = await this.$druxt.getCollection(type, query);
commit('addCollection', { collection: collection, type: type, hash: hash });
var data = (collection || {}).data || [];
data.map(function (resource) {
commit('addResource', { resource: { data: resource }, hash: hash });
});
// Store the collection in the DruxtStore.
commit('addCollection', { collection: Object.assign({}, collection), type: type, hash: hash });

@@ -1120,2 +1202,3 @@ return collection

var commit = ref.commit;
var dispatch = ref.dispatch;
var state = ref.state;

@@ -1126,11 +1209,91 @@ var type = ref$1.type;

var hash = query ? md5(this.$druxt.buildQueryUrl('', query)) : '_default';
if (typeof ((state.resources[type] || {})[id] || {})[hash] !== 'undefined') {
return state.resources[type][id][hash]
// Get the resource from the store if it's avaialble.
var storedResource = (state.resources[type] || {})[id] ?
Object.assign({}, state.resources[type][id])
: null;
// Parse the query.
var queryObject = getDrupalJsonApiParams(query).getQueryObject();
// Ensure that includes are in the fields filter.
if (queryObject.include && typeof (queryObject.fields || {})[type] === 'string') {
var fields$1 = queryObject.fields[type].split(',').filter(function (s) { return s; });
var includes = queryObject.include.split(',').filter(function (s) { return s && !s.includes('.'); });
queryObject.fields[type] = Array.from(
new Set(fields$1.concat( includes))
).filter(function (s) { return s; }).join(',');
}
var resource = await this.$druxt.getResource(type, id, query);
commit('addResource', { resource: resource, hash: hash });
// Hydrate included data based on the include query.
var included = [];
if (queryObject.include && storedResource) {
// Request included resources from druxt/getResource.
var resources =
await Promise.all(queryObject.include.split(',')
.filter(function (s) { return Object.keys((storedResource.data.relationships || {})).includes(s); })
.map(function (key) {
var ref = storedResource.data.relationships[key];
var data = ref.data;
data = Array.isArray(data) ? data : [data];
return resource
// Get any sub-includes, e.g., `media,media.image` becomes `image`.
var include = queryObject.include.split(',')
.filter(function (s) { return s.startsWith((key + ".")); })
.map(function (s) { return s.slice(key.length + 1); })
.join(',');
return data.filter(function (o) { return typeof o === 'object' && o; }).map(function (o) {
return dispatch('getResource', {
type: o.type,
id: o.id,
query: Object.assign({}, queryObject, {include: include}),
})
})
})
.flat()
);
// Merge all nested, included resources.
for (var include of resources) {
included = included.concat( [include.data], include.included || []);
}
storedResource.included = included;
}
// Return if we have the full resource.
if ((storedResource || {})._druxt_full) {
return storedResource
}
var isFull = typeof (queryObject.fields || {})[type] !== 'string';
// Determine if we have all the requested field data.
var fields = isFull ? true : (queryObject.fields || {})[type];
if (storedResource && !isFull && fields) {
var queryFields = fields.split(',');
var resourceFields = Object.keys(((storedResource || {}).data || {}).attributes || {}).concat( Object.keys(((storedResource || {}).data || {}).relationships || {}) );
var missingFields = queryFields.filter(function (key) { return !resourceFields.includes(key); });
fields = !!missingFields.length;
// Modify query to load additional fields, if required.
queryObject.fields[type] = (missingFields || []).join(',') || undefined;
}
// Request the resource from the DruxtClient if required.
var resource;
if (!storedResource || fields) {
resource = await this.$druxt.getResource(type, id, getDrupalJsonApiParams(queryObject));
commit('addResource', { resource: Object.assign({}, resource) });
}
// Build resource to be returned.
var result = Object.assign({}, (state.resources[type] || {})[id]);
// Merge included resources into resource.
if (queryObject.include && ((resource || {}).included || (storedResource || {}).included)) {
included = ( (resource || {}).included || [] ).concat( (storedResource || {}).included || [] );
result.included = Array.from(new Set(included.filter(function (o) { return (o || {}).id; }).map(function (o) { return o.id; })))
.map(function (id) { return included.find(function (o) { return o.id === id; }); });
}
return result
},

@@ -1172,3 +1335,2 @@ }

* @param {object} resource - The JSON:API resource.
* @param {string} hash - An md5 hash of the query string.
*

@@ -1182,3 +1344,2 @@ * @example @lang js

* },
* hash: '_default'
* }

@@ -1185,0 +1346,0 @@ */

{
"name": "druxt",
"version": "0.5.1",
"version": "0.6.0",
"description": "A Bridge between frameworks, Nuxt.js in the front, Drupal in the back.",

@@ -57,3 +57,5 @@ "repository": {

"axios": "^0.21.1",
"codecov": "^3.8.1",
"codecov": "^3.8.2",
"deepmerge": "^4.2.2",
"drupal-jsonapi-params": "^1.1.12",
"md5": "^2.3.0",

@@ -60,0 +62,0 @@ "querystring": "^0.2.0",

# DruxtJS; A bridge between frameworks.
[![npm](https://badgen.net/npm/v/druxt)](https://www.npmjs.com/package/druxt)
[![CircleCI](https://circleci.com/gh/druxt/druxt.js.svg?style=svg)](https://circleci.com/gh/druxt/druxt.js)

@@ -4,0 +5,0 @@ [![Known Vulnerabilities](https://snyk.io/test/github/druxt/druxt.js/badge.svg?targetFile=package.json)](https://snyk.io/test/github/druxt/druxt.js?targetFile=package.json)

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