@plone/registry
Version:
Add-on and configuration registry for Plone and for JavaScript and TypeScript-based apps.
435 lines (433 loc) • 13.4 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
default: () => index_default
});
module.exports = __toCommonJS(index_exports);
var Config = class _Config {
_data;
static instance;
constructor() {
if (!_Config.instance) {
this._data = {
settings: {},
blocks: {},
views: {},
widgets: {},
slots: {},
components: {},
utilities: {}
};
_Config.instance = this;
}
return _Config.instance;
}
set(registry, item) {
this._data[registry] = item;
}
get(registry) {
return this._data[registry];
}
get settings() {
return this._data.settings;
}
set settings(settings) {
this._data.settings = settings;
}
get experimental() {
return this._data.experimental;
}
set experimental(experimental) {
this._data.experimental = experimental;
}
get blocks() {
return this._data.blocks;
}
set blocks(blocks) {
this._data.blocks = blocks;
}
get views() {
return this._data.views;
}
set views(views) {
this._data.views = views;
}
get widgets() {
return this._data.widgets;
}
set widgets(widgets) {
this._data.widgets = widgets;
}
get addonReducers() {
return this._data.addonReducers;
}
set addonReducers(addonReducers) {
this._data.addonReducers = addonReducers;
}
get addonRoutes() {
return this._data.addonRoutes;
}
set addonRoutes(addonRoutes) {
this._data.addonRoutes = addonRoutes;
}
get routes() {
return this._data.routes;
}
set routes(routes) {
this._data.routes = routes;
}
get slots() {
return this._data.slots;
}
set slots(slots) {
this._data.slots = slots;
}
get components() {
return this._data.components;
}
set components(components) {
this._data.components = components;
}
get utilities() {
return this._data.utilities;
}
set utilities(utilities) {
this._data.utilities = utilities;
}
getComponent(options) {
if (typeof options === "object") {
const { name, dependencies = "" } = options;
let depsString = "";
if (dependencies && Array.isArray(dependencies)) {
depsString = dependencies.join("+");
} else if (typeof dependencies === "string") {
depsString = dependencies;
}
const componentName = `${name}${depsString ? `|${depsString}` : ""}`;
return this._data.components[componentName] || {};
} else {
const componentName = options;
return this._data.components[componentName] || {};
}
}
registerComponent(options) {
const { name, component, dependencies = "" } = options;
let depsString = "";
if (!component) {
throw new Error("No component provided");
} else {
if (dependencies && Array.isArray(dependencies)) {
depsString = dependencies.join("+");
} else if (typeof dependencies === "string") {
depsString = dependencies;
}
const componentName = `${name}${depsString ? `|${depsString}` : ""}`;
this._data.components[componentName] = { component };
try {
const displayName = this._data.components[componentName].component.displayName;
if (!displayName && typeof this._data.components[componentName].component === "function") {
this._data.components[componentName].component.displayName = name;
}
} catch (error) {
console.warn(`Not setting the component displayName because ${error}`);
}
}
}
getSlot(name, args) {
if (!this._data.slots[name]) {
return;
}
const { slots, data } = this._data.slots[name];
const slotComponents = [];
for (const slotName of slots) {
let noPredicateComponent;
const reversedSlotComponents = data[slotName].slice().reverse();
for (const slotComponent of reversedSlotComponents) {
let isPredicateTrueFound = false;
if (slotComponent.predicates) {
isPredicateTrueFound = slotComponent.predicates.every(
(predicate) => predicate(args)
);
} else {
noPredicateComponent = slotComponent;
}
if (isPredicateTrueFound) {
slotComponents.push({
component: slotComponent.component,
name: slotName
});
noPredicateComponent = void 0;
break;
}
}
if (noPredicateComponent) {
slotComponents.push({
component: noPredicateComponent.component,
name: slotName
});
}
}
return slotComponents;
}
registerSlotComponent(options) {
const { name, component, predicates, slot } = options;
if (!component) {
throw new Error("No component provided");
}
if (!predicates) {
const hasRegisteredNoPredicatesComponent = this._data.slots?.[slot]?.data?.[name]?.find(({ predicates: predicates2 }) => !predicates2);
if (hasRegisteredNoPredicatesComponent && component !== hasRegisteredNoPredicatesComponent.component) {
hasRegisteredNoPredicatesComponent.component = component;
}
}
let currentSlot = this._data.slots[slot];
if (!currentSlot) {
this._data.slots[slot] = {
slots: [],
data: {}
};
currentSlot = this._data.slots[slot];
}
if (!currentSlot.data[name]) {
currentSlot.data[name] = [];
}
const currentSlotComponents = currentSlot.data[name];
if (!currentSlot.slots.includes(name)) {
currentSlot.slots.push(name);
}
const slotComponentData = {
component,
predicates
};
try {
const displayName = slotComponentData.component.displayName;
if (!displayName && typeof slotComponentData?.component === "function") {
slotComponentData.component.displayName = name;
}
} catch (error) {
console.warn(
`Not setting the slot component displayName because ${error}`
);
}
currentSlotComponents.push(slotComponentData);
}
getSlotComponent(slot, name) {
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}
const currentSlotComponents = currentSlot.data[name];
if (!currentSlotComponents) {
throw new Error(`No slot component ${name} in slot ${slot} found`);
}
return currentSlotComponents;
}
getSlotComponents(slot) {
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}
return currentSlot.slots;
}
reorderSlotComponent({
slot,
name,
position,
action,
target
}) {
if (!position && !action) {
throw new Error(`At least a position or action is required as argument`);
}
if (position && action) {
throw new Error(
`You should provide only one of position or action as arguments`
);
}
if ((action == "after" || action == "before") && !target) {
throw new Error(
`No action target set. You should provide the name of a slot component as target when action is 'after' or 'before'.`
);
}
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}
const origin = currentSlot.slots.indexOf(name);
const result = Array.from(currentSlot.slots);
const [removed] = result.splice(origin, 1);
if (action) {
let targetIdx = 0;
if (target) {
targetIdx = currentSlot.slots.indexOf(target);
}
switch (action) {
case "after":
if (targetIdx < origin) {
result.splice(targetIdx + 1, 0, removed);
break;
} else {
result.splice(targetIdx, 0, removed);
break;
}
case "before":
if (targetIdx > origin) {
result.splice(targetIdx - 1, 0, removed);
break;
} else {
result.splice(targetIdx, 0, removed);
break;
}
case "last":
result.push(removed);
break;
case "first":
result.unshift(removed);
break;
default:
break;
}
}
if (position) {
result.splice(position, 0, removed);
}
currentSlot.slots = result;
}
unRegisterSlotComponent(slot, name, position) {
const currentSlot = this._data.slots[slot];
if (!slot || !currentSlot) {
throw new Error(`No slot ${slot} found`);
}
const currentSlotComponents = currentSlot.data[name];
if (!currentSlotComponents) {
throw new Error(`No slot component ${name} in slot ${slot} found`);
}
const result = currentSlotComponents.slice();
result.splice(position, 1);
currentSlot.data[name] = result;
if (result.length === 0) {
const index = currentSlot.slots.indexOf(name);
if (index > -1) {
currentSlot.slots.splice(index, 1);
}
}
}
registerUtility(options) {
const { name, type, method, dependencies = {} } = options;
let depsString = "";
if (!method) {
throw new Error("No method provided");
} else {
depsString = Object.keys(dependencies).sort().map((key) => `${key}:${dependencies[key]}`).join("+");
}
const utilityName = `${depsString ? `|${depsString}` : ""}${name}`;
let utilityType = this._data.utilities[type];
if (!utilityType) {
this._data.utilities[type] = {};
utilityType = this._data.utilities[type];
}
utilityType[utilityName] = { method };
}
getUtility(options) {
const { name, type, dependencies = {} } = options;
if (!name || !type) return {};
let depsString = "";
depsString = Object.keys(dependencies).map((key) => `${key}:${dependencies[key]}`).join("+");
const utilityName = `${depsString ? `|${depsString}` : ""}${name}`;
const utilitiesForType = this._data.utilities[type];
return utilitiesForType?.[utilityName] || {};
}
getUtilities(options) {
const { type, dependencies = {} } = options;
if (!type) return [];
let depsString = "";
depsString = Object.keys(dependencies).map((key) => `${key}:${dependencies[key]}`).join("+");
const utilitiesForType = this._data.utilities[type];
if (!utilitiesForType) return [];
const utilityName = `${depsString ? `|${depsString}` : ""}`;
const utilitiesKeys = Object.keys(utilitiesForType).filter(
(key) => key.startsWith(utilityName)
);
const utilities = utilitiesKeys.map((key) => utilitiesForType[key]);
return utilities;
}
registerRoute(options) {
const route = this._data.routes || [];
route.push(options);
this._data.routes = route;
}
/**
* Registers a widget configuration into the registry.
*
* @template K - A key from the WidgetsConfig interface.
* @param options - An object containing the widget key and its corresponding implementation.
* @param options.key - The name of the widget configuration key (e.g., 'default', 'factory').
* @param options.definition - The actual widget configuration, which must match the expected structure of WidgetsConfig[K].
*
*/
registerWidget(options) {
const emptyDefinition = {};
if (!options || !options.key || !options.definition) {
throw new Error("No widget definition provided");
}
const { key, definition } = options;
if (key === "default") {
throw new Error("Use registerDefaultWidget to set the default widget");
}
const definitionIsObject = Object.keys(definition).length;
if (!definitionIsObject) {
this._data.widgets[key] = definition;
} else {
for (const widgetKey of Object.keys(definition)) {
if (this._data.widgets[key] === void 0)
this._data.widgets[key] = emptyDefinition;
this._data.widgets[key][widgetKey] = definition[widgetKey];
}
}
}
/**
* Registers a default widget configuration into the registry.
*
* @param component - The default widget component to register.
*
*/
registerDefaultWidget(component) {
this._data.widgets.default = component;
}
/**
* Gets a widget configuration from the registry.
*
* @param key - A key from the WidgetsConfig interface.
*/
getWidget(key) {
const widgets = this.widgets;
for (const category of Object.keys(widgets)) {
const group = widgets[category];
if (typeof group === "object" && key in group) {
return group[key];
}
}
return void 0;
}
};
var instance = new Config();
Object.freeze(instance);
var index_default = instance;