adminizer 4.7.0-build.224 → 5.0.0-build.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +2 -1
- package/assets/add-De0wyF0A.js +1 -0
- package/assets/add-group-CMWybgIR.js +1 -0
- package/assets/add-user-BxP23daH.js +1 -0
- package/assets/app-CtWuWD5N.css +1 -0
- package/assets/app-layout-GYMU2HO1.js +1 -0
- package/assets/app.js +45 -50
- package/assets/catalog-tImW1BnS.js +6 -0
- package/assets/controls/chunks/_commonjsHelpers-C6fGbg64.js +6 -0
- package/assets/controls/chunks/index-CjiZ2FIa.js +93 -0
- package/assets/controls/chunks/jsx-runtime-jIxVPx5o.js +31 -0
- package/assets/controls/chunks/use-appearance-CFLOwiSX.js +38 -0
- package/assets/controls/chunks/use-window-size-BXgBKW65.js +19 -0
- package/assets/controls/chunks/vanilla-picker-Dg97NL4h.js +529 -0
- package/assets/controls/ckeditor.es.js +83683 -0
- package/assets/controls/handsontable.css +1 -0
- package/assets/controls/handsontable.es.js +70585 -0
- package/assets/controls/jsoneditor.css +1 -0
- package/assets/controls/jsoneditor.es.js +42082 -0
- package/assets/controls/leaflet.css +1 -0
- package/assets/controls/leaflet.es.js +10299 -0
- package/assets/controls/monaco.es.js +618 -0
- package/assets/controls/toast-ui.css +1 -0
- package/assets/controls/toast-ui.es.js +41797 -0
- package/assets/dashboard-CQ4atH3N.js +3 -0
- package/assets/debounce-BMmXVQ06.js +1 -0
- package/assets/history-BileQPEi.js +1 -0
- package/assets/init-user-8aUohVDq.js +1 -0
- package/assets/list-Pz_5mfSq.js +4 -0
- package/assets/login-CO4laf6m.js +1 -0
- package/assets/manifest.json +66 -602
- package/assets/media-manager-BDbpSSjH.js +6 -0
- package/assets/media-manager-BZPjl98I.css +1 -0
- package/assets/module-CQiOdgZN.js +1 -0
- package/assets/notification-BIyv1smE.js +20 -0
- package/assets/register-DBYIMXGQ.js +1 -0
- package/assets/ru-rYKdQbWF.js +1 -0
- package/assets/use-appearance-_EbbjHTh.js +1 -0
- package/assets/user-filters-list-Aq8CvCeh.js +1 -0
- package/assets/welcome-DxhWYzUL.js +1 -0
- package/controllers/add.d.ts +1 -1
- package/controllers/addGroup.js +3 -3
- package/controllers/addUser.js +3 -3
- package/controllers/catalog/Catalog.d.ts +1 -1
- package/controllers/catalog/Catalog.js +2 -1
- package/controllers/catalog/FrontendCatalogAdapter.d.ts +2 -12
- package/controllers/catalog/FrontendCatalogAdapter.js +3 -16
- package/controllers/catalog/FrontentCatalogAdapter.d.ts +2 -12
- package/controllers/catalog/FrontentCatalogAdapter.js +0 -16
- package/controllers/edit.js +6 -11
- package/controllers/editGroup.d.ts +1 -1
- package/controllers/editGroup.js +3 -3
- package/controllers/editUser.d.ts +1 -1
- package/controllers/editUser.js +3 -3
- package/controllers/feed.js +1 -1
- package/controllers/filter-fields/columns.js +1 -1
- package/controllers/filter-fields/getAllUserFilters.js +2 -2
- package/controllers/filter-fields/groups.js +2 -2
- package/controllers/filter-fields/savedFilters.js +1 -1
- package/controllers/history-actions/HistoryController.js +1 -1
- package/controllers/initUser.js +2 -2
- package/controllers/list.d.ts +1 -1
- package/controllers/login.d.ts +1 -1
- package/controllers/login.js +3 -3
- package/controllers/media-manager/ThumbController.js +2 -2
- package/controllers/media-manager/mediaManagerApi.js +13 -15
- package/controllers/register.d.ts +1 -1
- package/controllers/register.js +5 -5
- package/controllers/remove.d.ts +1 -1
- package/controllers/userApiKey.js +2 -2
- package/controllers/view.d.ts +1 -1
- package/controllers/view.js +5 -5
- package/controllers/widgets/Action.js +5 -2
- package/controllers/widgets/filterInfo.js +1 -1
- package/files/favicon.png +0 -0
- package/helpers/accessRightsHelper.d.ts +6 -4
- package/helpers/accessRightsHelper.js +13 -0
- package/helpers/diffHelpers.js +1 -1
- package/helpers/fieldsHelper.d.ts +1 -1
- package/helpers/fieldsHelper.js +8 -4
- package/helpers/filterDatetimeHelper.d.ts +1 -1
- package/helpers/inertiaAddHelper.d.ts +6 -5
- package/helpers/inertiaAddHelper.js +45 -37
- package/helpers/inertiaAutHelper.js +5 -5
- package/helpers/inertiaGroupHelper.d.ts +4 -4
- package/helpers/inertiaMenuHelper.js +1 -1
- package/helpers/inertiaUserHelper.d.ts +3 -3
- package/helpers/inertiaUserHelper.js +1 -1
- package/helpers/menuHelper.d.ts +2 -2
- package/index.d.ts +19 -6
- package/index.js +19 -6
- package/interfaces/adminpanelConfig.d.ts +10 -33
- package/interfaces/global.d.ts +10 -15
- package/interfaces/listQueryBuilder.d.ts +1 -1
- package/lib/Adminizer.d.ts +25 -2
- package/lib/Adminizer.js +124 -50
- package/lib/DataAccessor.d.ts +9 -5
- package/lib/DataAccessor.js +89 -42
- package/lib/access-rights/AccessRightsHandler.d.ts +17 -0
- package/lib/access-rights/AccessRightsHandler.js +63 -0
- package/lib/ai-assistant/AbstractAiModelService.d.ts +5 -8
- package/lib/ai-assistant/AbstractAiModelService.js +3 -14
- package/lib/ai-assistant/AiAssistantHandler.d.ts +2 -2
- package/lib/app-manager/AdminizerApp.d.ts +228 -0
- package/lib/app-manager/AdminizerApp.js +17 -0
- package/lib/app-manager/AppManager.d.ts +18 -0
- package/lib/app-manager/AppManager.js +537 -0
- package/lib/app-manager/AssetHandler.d.ts +17 -0
- package/lib/app-manager/AssetHandler.js +67 -0
- package/lib/app-manager/ConfigLayerHandler.d.ts +18 -0
- package/lib/app-manager/ConfigLayerHandler.js +119 -0
- package/lib/app-manager/ControllerHandler.d.ts +25 -0
- package/lib/app-manager/ControllerHandler.js +140 -0
- package/lib/catalog/AbstractCatalog.d.ts +28 -19
- package/lib/catalog/AbstractCatalog.js +41 -10
- package/lib/catalog/CatalogHandler.d.ts +13 -0
- package/lib/catalog/CatalogHandler.js +48 -2
- package/lib/catalog/CatalogTemplateComponentHandler.d.ts +23 -0
- package/lib/catalog/CatalogTemplateComponentHandler.js +59 -0
- package/lib/controls/Control.d.ts +17 -0
- package/lib/controls/Control.js +1 -0
- package/lib/controls/ControlsHandler.d.ts +5 -6
- package/lib/controls/ControlsHandler.js +0 -13
- package/lib/controls/codeEditor/MonacoEditor.d.ts +3 -4
- package/lib/controls/codeEditor/MonacoEditor.js +13 -8
- package/lib/controls/geojsoneditor/GeoEditor.d.ts +3 -4
- package/lib/controls/geojsoneditor/GeoEditor.js +14 -9
- package/lib/controls/jsoneditor/JsonEditor.d.ts +5 -6
- package/lib/controls/jsoneditor/JsonEditor.js +14 -13
- package/lib/controls/markdown/ToastUiEditor.d.ts +5 -6
- package/lib/controls/markdown/ToastUiEditor.js +14 -13
- package/lib/controls/table/Handsontable.d.ts +5 -6
- package/lib/controls/table/Handsontable.js +14 -13
- package/lib/controls/wysiwyg/CKeditor.d.ts +5 -6
- package/lib/controls/wysiwyg/CKeditor.js +14 -13
- package/lib/filters/ConditionValidator.d.ts +1 -1
- package/lib/filters/FilterService.d.ts +18 -18
- package/lib/filters/FilterService.js +11 -11
- package/lib/history-actions/AbstractHistoryAdapter.d.ts +14 -14
- package/lib/history-actions/AbstractHistoryAdapter.js +5 -6
- package/lib/history-actions/DefaultHistoryAdapter.d.ts +7 -7
- package/lib/history-actions/DefaultHistoryAdapter.js +2 -2
- package/lib/list-query-builder/ListQueryBuilder.d.ts +1 -1
- package/lib/media-manager/AbstractMediaManager.d.ts +14 -3
- package/lib/media-manager/AbstractMediaManager.js +16 -5
- package/lib/media-manager/MediaManagerHandler.d.ts +3 -0
- package/lib/media-manager/MediaManagerHandler.js +30 -5
- package/lib/media-manager/Thumb.js +7 -13
- package/lib/media-manager/helpers/MediaManagerHelper.d.ts +6 -4
- package/lib/media-manager/helpers/MediaManagerHelper.js +18 -18
- package/lib/model/AbstractModel.d.ts +9 -5
- package/lib/model/AbstractModel.js +9 -13
- package/lib/model/InternalModelAccessFactory.js +9 -10
- package/lib/model/ModelHandler.d.ts +45 -7
- package/lib/model/ModelHandler.js +168 -11
- package/lib/model/adapter/sequelize.d.ts +2 -4
- package/lib/model/adapter/sequelize.js +16 -193
- package/lib/model/adapter/typeorm.d.ts +2 -4
- package/lib/model/adapter/typeorm.js +2 -35
- package/lib/notifications/AbstractNotificationService.d.ts +9 -9
- package/lib/notifications/AbstractNotificationService.js +8 -8
- package/lib/notifications/GeneralNotificationService.js +1 -1
- package/lib/notifications/SystemNotificationService.js +1 -1
- package/lib/ui-i18n/uiTranslationKeys.d.ts +1 -1
- package/lib/ui-i18n/uiTranslationKeys.js +1 -0
- package/lib/widgets/abstractCustom.d.ts +5 -2
- package/lib/widgets/abstractCustom.js +4 -0
- package/lib/widgets/widgetHandler.d.ts +5 -2
- package/lib/widgets/widgetHandler.js +60 -14
- package/models/{FilterAP.d.ts → Filter.d.ts} +4 -70
- package/models/Filter.js +1 -0
- package/models/FilterColumn.d.ts +10 -0
- package/models/FilterColumn.js +1 -0
- package/models/Group.d.ts +8 -0
- package/models/Group.js +1 -0
- package/models/HistoryActions.d.ts +14 -0
- package/models/HistoryActions.js +1 -0
- package/models/MediaManagerAP.d.ts +2 -54
- package/models/MediaManagerAP.js +1 -51
- package/models/MediaManagerAssociationsAP.d.ts +1 -35
- package/models/MediaManagerAssociationsAP.js +1 -33
- package/models/MediaManagerMetaAP.d.ts +2 -30
- package/models/MediaManagerMetaAP.js +1 -27
- package/models/Notification.d.ts +13 -0
- package/models/Notification.js +1 -0
- package/models/User.d.ts +23 -0
- package/models/User.js +1 -0
- package/models/UserNotification.d.ts +7 -0
- package/models/UserNotification.js +1 -0
- package/package.json +25 -30
- package/services/FeedService.d.ts +5 -5
- package/services/FeedService.js +1 -1
- package/system/Router.js +2 -10
- package/system/bindAccessRights.js +1 -1
- package/system/bindAuthorization.js +2 -2
- package/system/bindControls.js +7 -6
- package/system/bindDashboardWidgets.js +3 -2
- package/system/bindDev.js +1 -1
- package/system/bindHistory.d.ts +1 -1
- package/system/bindHistory.js +1 -1
- package/system/bindInertia.js +0 -6
- package/system/bindMediaManager.js +4 -17
- package/system/bindNotifications.d.ts +1 -1
- package/system/bindNotifications.js +1 -1
- package/system/bindReqFunctions.d.ts +1 -0
- package/system/bindReqFunctions.js +20 -3
- package/system/buildInternalModelAccess.js +2 -15
- package/system/defaults.js +5 -10
- package/system/systemModelContracts.d.ts +22 -0
- package/system/systemModelContracts.js +155 -0
- package/system/validateSystemModels.d.ts +2 -0
- package/system/validateSystemModels.js +101 -0
- package/translations/ar.json +2 -1
- package/translations/cn.json +2 -1
- package/translations/de.json +2 -1
- package/translations/en.json +1 -0
- package/translations/es.json +2 -1
- package/translations/fr.json +2 -1
- package/translations/hi.json +2 -1
- package/translations/jp.json +2 -1
- package/translations/ko.json +2 -1
- package/translations/pt.json +2 -1
- package/translations/ru.json +2 -1
- package/translations/ua.json +2 -1
- package/translations/uz.json +2 -1
- package/translations/vi.json +2 -1
- package/assets/RelationDialogStack-DhThUMep.js +0 -20
- package/assets/add-group-L8lMigab.js +0 -1
- package/assets/add-group-form-o7F6t6qW.js +0 -1
- package/assets/add-user-BE4-TNJw.js +0 -1
- package/assets/add-user-form-BP_8TjxN.js +0 -1
- package/assets/add-w398ZkhF.js +0 -1
- package/assets/app-C7J5ccrI.css +0 -1
- package/assets/app-layout-Bg455MIY.js +0 -1
- package/assets/app-shell-BT2kF0We.js +0 -1
- package/assets/app-sidebar-CZfPUXck.js +0 -1
- package/assets/app-sidebar-header-UVcKhNm6.js +0 -1
- package/assets/breadcrumbs-CrqIBT84.js +0 -1
- package/assets/catalog-btkCCwiv.js +0 -6
- package/assets/dashboard-Bvasc1cr.js +0 -3
- package/assets/date-picker-kxQWOxHk.js +0 -1
- package/assets/del-modal-C39LR5aQ.js +0 -1
- package/assets/dynamic-controls-DyPP5sTC.js +0 -1
- package/assets/geo-json-CGNQFl6J.js +0 -1
- package/assets/handsontable-Dv59QFH5.js +0 -336
- package/assets/history-DwKR8MPu.js +0 -1
- package/assets/home-BrtAkCRj.js +0 -2
- package/assets/icon-DpUVVHmK.js +0 -1
- package/assets/init-user-8PiKR1zX.js +0 -1
- package/assets/input-error-Cbt-Y3Fj.js +0 -1
- package/assets/jsoneditor-CiPXPMho.js +0 -3869
- package/assets/list-DGsL_qii.js +0 -4
- package/assets/login-Br_FcBU_.js +0 -1
- package/assets/material-icon-DOkM71fv.js +0 -1
- package/assets/module-EgfgIEhF.js +0 -1
- package/assets/monaco-ompgKQ3_.js +0 -11
- package/assets/nav-footer-DzLwfBAE.js +0 -1
- package/assets/nav-main-CSEbjYgs.js +0 -1
- package/assets/nav-user-DJ0hfhfH.js +0 -1
- package/assets/notification-B19ZLro7.js +0 -20
- package/assets/pagination-render-8GvJxq55.js +0 -1
- package/assets/register-CZzIeT2G.js +0 -1
- package/assets/ru-1NdRIQNV.js +0 -1
- package/assets/theme-switcher-CBbEj1u-.js +0 -1
- package/assets/toast-editor-DwVqd1rz.js +0 -668
- package/assets/user-filters-list-7Im79QyS.js +0 -1
- package/assets/user-info-YiU17Mmy.js +0 -1
- package/assets/user-menu-content-gdpNF5-8.js +0 -1
- package/assets/vanilla-picker-B3LgXoKV.js +0 -2
- package/assets/vendor-l0sNRNKZ.js +0 -1
- package/assets/welcome-nT0eFWHb.js +0 -1
- package/controllers/navigation/edit.d.ts +0 -1
- package/controllers/navigation/edit.js +0 -8
- package/lib/ai-assistant/DummyAiModelService.d.ts +0 -8
- package/lib/ai-assistant/DummyAiModelService.js +0 -14
- package/lib/ai-assistant/OpenAiModelService.d.ts +0 -24
- package/lib/ai-assistant/OpenAiModelService.js +0 -184
- package/lib/catalog/Navigation.d.ts +0 -49
- package/lib/catalog/Navigation.js +0 -492
- package/lib/controls/AbstractControls.d.ts +0 -30
- package/lib/controls/AbstractControls.js +0 -14
- package/lib/media-manager/DefaultMediaManager.d.ts +0 -20
- package/lib/media-manager/DefaultMediaManager.js +0 -127
- package/lib/media-manager/Items.d.ts +0 -50
- package/lib/media-manager/Items.js +0 -296
- package/models/FilterAP.js +0 -68
- package/models/FilterColumnAP.d.ts +0 -32
- package/models/FilterColumnAP.js +0 -21
- package/models/GroupAP.d.ts +0 -31
- package/models/GroupAP.js +0 -22
- package/models/HistoryActionsAP.d.ts +0 -56
- package/models/HistoryActionsAP.js +0 -42
- package/models/NavigationAP.d.ts +0 -22
- package/models/NavigationAP.js +0 -16
- package/models/NotificationAP.d.ts +0 -44
- package/models/NotificationAP.js +0 -30
- package/models/UserAP.d.ts +0 -81
- package/models/UserAP.js +0 -57
- package/models/UserNotificationAP.d.ts +0 -26
- package/models/UserNotificationAP.js +0 -18
- package/system/bindAiAssistant.d.ts +0 -2
- package/system/bindAiAssistant.js +0 -30
- package/system/bindModels.d.ts +0 -2
- package/system/bindModels.js +0 -48
- package/system/bindNavigation.d.ts +0 -2
- package/system/bindNavigation.js +0 -38
- /package/assets/{RelationDialogStack-B00Ot5qS.css → controls/ckeditor.css} +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
function cloneConfigValue(value) {
|
|
2
|
+
if (Array.isArray(value)) {
|
|
3
|
+
return value.map((item) => cloneConfigValue(item));
|
|
4
|
+
}
|
|
5
|
+
if (isPlainObject(value)) {
|
|
6
|
+
const cloned = {};
|
|
7
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
8
|
+
cloned[key] = cloneConfigValue(nestedValue);
|
|
9
|
+
}
|
|
10
|
+
return cloned;
|
|
11
|
+
}
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function isPlainObject(value) {
|
|
15
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const prototype = Object.getPrototypeOf(value);
|
|
19
|
+
return prototype === Object.prototype || prototype === null;
|
|
20
|
+
}
|
|
21
|
+
function hasStringId(value) {
|
|
22
|
+
return isPlainObject(value) && typeof value.id === "string";
|
|
23
|
+
}
|
|
24
|
+
function mergeArrays(base, patch) {
|
|
25
|
+
if (!patch.length) {
|
|
26
|
+
return cloneConfigValue(base);
|
|
27
|
+
}
|
|
28
|
+
const shouldMergeById = patch.every(hasStringId);
|
|
29
|
+
if (!shouldMergeById) {
|
|
30
|
+
return [...cloneConfigValue(base), ...cloneConfigValue(patch)];
|
|
31
|
+
}
|
|
32
|
+
const merged = cloneConfigValue(base);
|
|
33
|
+
for (const patchItem of patch) {
|
|
34
|
+
const index = merged.findIndex((item) => hasStringId(item) && item.id === patchItem.id);
|
|
35
|
+
if (index === -1) {
|
|
36
|
+
merged.push(cloneConfigValue(patchItem));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
merged[index] = mergeConfigValues(merged[index], patchItem);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return merged;
|
|
43
|
+
}
|
|
44
|
+
function mergeConfigValues(base, patch) {
|
|
45
|
+
if (patch === undefined) {
|
|
46
|
+
return cloneConfigValue(base);
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(patch)) {
|
|
49
|
+
return mergeArrays(Array.isArray(base) ? base : [], patch);
|
|
50
|
+
}
|
|
51
|
+
if (isPlainObject(patch)) {
|
|
52
|
+
const merged = isPlainObject(base) ? cloneConfigValue(base) : {};
|
|
53
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
54
|
+
merged[key] = mergeConfigValues(merged[key], value);
|
|
55
|
+
}
|
|
56
|
+
return merged;
|
|
57
|
+
}
|
|
58
|
+
return patch;
|
|
59
|
+
}
|
|
60
|
+
export class ConfigLayerHandler {
|
|
61
|
+
adminizer;
|
|
62
|
+
baseConfig;
|
|
63
|
+
layers = new Map();
|
|
64
|
+
constructor(adminizer) {
|
|
65
|
+
this.adminizer = adminizer;
|
|
66
|
+
}
|
|
67
|
+
register(appName, layerId, patch) {
|
|
68
|
+
const id = this.getLayerId(appName, layerId);
|
|
69
|
+
if (this.layers.has(id)) {
|
|
70
|
+
throw new Error(`Config layer "${id}" is already registered`);
|
|
71
|
+
}
|
|
72
|
+
if (!this.adminizer.config) {
|
|
73
|
+
throw new Error("Adminizer config must be initialized before registering app config layers");
|
|
74
|
+
}
|
|
75
|
+
if (!this.baseConfig) {
|
|
76
|
+
this.baseConfig = cloneConfigValue(this.adminizer.config);
|
|
77
|
+
}
|
|
78
|
+
this.layers.set(id, {
|
|
79
|
+
id,
|
|
80
|
+
appName,
|
|
81
|
+
patch: cloneConfigValue(patch),
|
|
82
|
+
});
|
|
83
|
+
this.rebuildConfig();
|
|
84
|
+
this.adminizer.emitter.emit("app:config:registered", {
|
|
85
|
+
appName,
|
|
86
|
+
resourceId: id,
|
|
87
|
+
});
|
|
88
|
+
return id;
|
|
89
|
+
}
|
|
90
|
+
unregister(id) {
|
|
91
|
+
const layer = this.layers.get(id);
|
|
92
|
+
if (!layer) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.layers.delete(id);
|
|
96
|
+
this.rebuildConfig();
|
|
97
|
+
this.adminizer.emitter.emit("app:config:unregistered", {
|
|
98
|
+
appName: layer.appName,
|
|
99
|
+
resourceId: id,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
getByApp(appName) {
|
|
103
|
+
return Array.from(this.layers.values()).filter((layer) => layer.appName === appName);
|
|
104
|
+
}
|
|
105
|
+
rebuildConfig() {
|
|
106
|
+
if (!this.baseConfig) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const rebuilt = Array.from(this.layers.values()).reduce((config, layer) => mergeConfigValues(config, layer.patch), cloneConfigValue(this.baseConfig));
|
|
110
|
+
const targetConfig = this.adminizer.config;
|
|
111
|
+
for (const key of Object.keys(targetConfig)) {
|
|
112
|
+
delete targetConfig[key];
|
|
113
|
+
}
|
|
114
|
+
Object.assign(this.adminizer.config, rebuilt);
|
|
115
|
+
}
|
|
116
|
+
getLayerId(appName, layerId) {
|
|
117
|
+
return `${appName}:${layerId}`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Adminizer } from "../Adminizer";
|
|
2
|
+
import type { AppController, AppControllerMethod } from "./AdminizerApp";
|
|
3
|
+
interface ControllerRecord {
|
|
4
|
+
id: string;
|
|
5
|
+
appName: string;
|
|
6
|
+
method: AppControllerMethod;
|
|
7
|
+
path: string;
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare class ControllerHandler {
|
|
11
|
+
private adminizer;
|
|
12
|
+
private controllers;
|
|
13
|
+
constructor(adminizer: Adminizer);
|
|
14
|
+
register(appName: string, controller: AppController): string;
|
|
15
|
+
disable(id: string): void;
|
|
16
|
+
enable(id: string): void;
|
|
17
|
+
unregister(id: string): void;
|
|
18
|
+
getByApp(appName: string): ControllerRecord[];
|
|
19
|
+
private getControllerId;
|
|
20
|
+
private resolveRoute;
|
|
21
|
+
private resolvePolicies;
|
|
22
|
+
private bindRoute;
|
|
23
|
+
private removeRoute;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { bindWithMiddlewares } from "../../system/routePolicies.js";
|
|
2
|
+
import { requireAdmin, requireAnyPermission, requireAuthAPI, requireAuthEnabled, requireAuthUI, requirePermission, } from "../../policies/authPolicies.js";
|
|
3
|
+
export class ControllerHandler {
|
|
4
|
+
adminizer;
|
|
5
|
+
controllers = new Map();
|
|
6
|
+
constructor(adminizer) {
|
|
7
|
+
this.adminizer = adminizer;
|
|
8
|
+
}
|
|
9
|
+
register(appName, controller) {
|
|
10
|
+
const id = this.getControllerId(appName, controller);
|
|
11
|
+
if (this.controllers.has(id)) {
|
|
12
|
+
throw new Error(`Controller "${id}" is already registered`);
|
|
13
|
+
}
|
|
14
|
+
const fullPath = this.resolveRoute(controller.route);
|
|
15
|
+
const record = {
|
|
16
|
+
id,
|
|
17
|
+
appName,
|
|
18
|
+
method: controller.method,
|
|
19
|
+
path: fullPath,
|
|
20
|
+
enabled: true,
|
|
21
|
+
};
|
|
22
|
+
const middleware = bindWithMiddlewares(this.adminizer, this.adminizer.config.middlewares ?? [], (req, res, next) => {
|
|
23
|
+
if (!record.enabled) {
|
|
24
|
+
return next();
|
|
25
|
+
}
|
|
26
|
+
req.runtime = this.adminizer.appManager.createRuntime(appName);
|
|
27
|
+
return controller.middleware(req, res, next);
|
|
28
|
+
}, this.resolvePolicies(controller.policies));
|
|
29
|
+
this.bindRoute(controller.method, fullPath, middleware);
|
|
30
|
+
this.controllers.set(id, record);
|
|
31
|
+
this.adminizer.emitter.emit("app:controller:registered", {
|
|
32
|
+
appName,
|
|
33
|
+
resourceId: id,
|
|
34
|
+
route: fullPath,
|
|
35
|
+
method: controller.method,
|
|
36
|
+
policies: controller.policies ?? [],
|
|
37
|
+
});
|
|
38
|
+
return fullPath;
|
|
39
|
+
}
|
|
40
|
+
disable(id) {
|
|
41
|
+
const record = this.controllers.get(id);
|
|
42
|
+
if (!record) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
record.enabled = false;
|
|
46
|
+
this.adminizer.emitter.emit("app:controller:disabled", {
|
|
47
|
+
appName: record.appName,
|
|
48
|
+
resourceId: id,
|
|
49
|
+
route: record.path,
|
|
50
|
+
method: record.method,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
enable(id) {
|
|
54
|
+
const record = this.controllers.get(id);
|
|
55
|
+
if (!record) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
record.enabled = true;
|
|
59
|
+
this.adminizer.emitter.emit("app:controller:enabled", {
|
|
60
|
+
appName: record.appName,
|
|
61
|
+
resourceId: id,
|
|
62
|
+
route: record.path,
|
|
63
|
+
method: record.method,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
unregister(id) {
|
|
67
|
+
const record = this.controllers.get(id);
|
|
68
|
+
if (!record) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
this.removeRoute(record.path, record.method);
|
|
72
|
+
this.controllers.delete(id);
|
|
73
|
+
this.adminizer.emitter.emit("app:controller:unregistered", {
|
|
74
|
+
appName: record.appName,
|
|
75
|
+
resourceId: id,
|
|
76
|
+
route: record.path,
|
|
77
|
+
method: record.method,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
getByApp(appName) {
|
|
81
|
+
return Array.from(this.controllers.values()).filter((record) => record.appName === appName);
|
|
82
|
+
}
|
|
83
|
+
getControllerId(appName, controller) {
|
|
84
|
+
return `${appName}:${controller.id ?? `${controller.method}:${controller.route}`}`;
|
|
85
|
+
}
|
|
86
|
+
resolveRoute(route) {
|
|
87
|
+
const routePrefix = this.adminizer.config.routePrefix.replace(/\/+$/, "");
|
|
88
|
+
const routePath = route.startsWith("/") ? route : `/${route}`;
|
|
89
|
+
return `${routePrefix}${routePath}`;
|
|
90
|
+
}
|
|
91
|
+
resolvePolicies(policies = []) {
|
|
92
|
+
return policies.map((policy) => {
|
|
93
|
+
switch (policy.type) {
|
|
94
|
+
case "auth":
|
|
95
|
+
return policy.mode === "api" ? requireAuthAPI() : requireAuthUI();
|
|
96
|
+
case "auth-enabled":
|
|
97
|
+
return requireAuthEnabled();
|
|
98
|
+
case "admin":
|
|
99
|
+
return requireAdmin({ mode: policy.mode });
|
|
100
|
+
case "permission":
|
|
101
|
+
return requirePermission(policy.token, { mode: policy.mode });
|
|
102
|
+
case "any-permission":
|
|
103
|
+
return requireAnyPermission(policy.tokens, { mode: policy.mode });
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
bindRoute(method, route, middleware) {
|
|
108
|
+
switch (method) {
|
|
109
|
+
case "get":
|
|
110
|
+
this.adminizer.app.get(route, middleware);
|
|
111
|
+
break;
|
|
112
|
+
case "post":
|
|
113
|
+
this.adminizer.app.post(route, middleware);
|
|
114
|
+
break;
|
|
115
|
+
case "put":
|
|
116
|
+
this.adminizer.app.put(route, middleware);
|
|
117
|
+
break;
|
|
118
|
+
case "patch":
|
|
119
|
+
this.adminizer.app.patch(route, middleware);
|
|
120
|
+
break;
|
|
121
|
+
case "delete":
|
|
122
|
+
this.adminizer.app.delete(route, middleware);
|
|
123
|
+
break;
|
|
124
|
+
case "all":
|
|
125
|
+
this.adminizer.app.all(route, middleware);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
removeRoute(path, method) {
|
|
130
|
+
const app = this.adminizer.app;
|
|
131
|
+
const router = app.router ?? app._router;
|
|
132
|
+
if (!Array.isArray(router?.stack)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const index = router.stack.findIndex((layer) => layer.route?.path === path && layer.route?.methods?.[method]);
|
|
136
|
+
if (index !== -1) {
|
|
137
|
+
router.stack.splice(index, 1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Adminizer } from "../Adminizer";
|
|
2
|
-
|
|
2
|
+
export interface CatalogStorageServices {
|
|
3
|
+
}
|
|
3
4
|
/**
|
|
4
5
|
* Interface `Item` describes the data that the UI will operate on
|
|
5
6
|
* This is a common interface for all data that is linked to the catalog
|
|
@@ -8,7 +9,7 @@ import { StorageServices } from "./Navigation";
|
|
|
8
9
|
export interface Item {
|
|
9
10
|
id: string | number;
|
|
10
11
|
name: string;
|
|
11
|
-
parentId: string | number;
|
|
12
|
+
parentId: string | number | null;
|
|
12
13
|
/**
|
|
13
14
|
*
|
|
14
15
|
*/
|
|
@@ -21,11 +22,15 @@ export interface Item {
|
|
|
21
22
|
export type _Item_ = {
|
|
22
23
|
[key: string]: boolean | string | number | object;
|
|
23
24
|
};
|
|
25
|
+
export interface CatalogTemplate<TData = any> {
|
|
26
|
+
type: string;
|
|
27
|
+
data: TData;
|
|
28
|
+
}
|
|
24
29
|
/**
|
|
25
30
|
* General Item structure that will be available for all elements, including groups
|
|
26
31
|
*/
|
|
27
32
|
export declare abstract class BaseItem<T extends Item> {
|
|
28
|
-
storageServices?:
|
|
33
|
+
storageServices?: CatalogStorageServices;
|
|
29
34
|
abstract readonly type: string;
|
|
30
35
|
/**
|
|
31
36
|
* Used for infer T
|
|
@@ -91,10 +96,7 @@ export declare abstract class BaseItem<T extends Item> {
|
|
|
91
96
|
* get add template
|
|
92
97
|
* @param req
|
|
93
98
|
*/
|
|
94
|
-
abstract getAddTemplate(req: ReqType): Promise<
|
|
95
|
-
type: 'component' | 'navigation.group' | 'navigation.link' | 'model' | 'model.link';
|
|
96
|
-
data: any;
|
|
97
|
-
}>;
|
|
99
|
+
abstract getAddTemplate(req: ReqType): Promise<CatalogTemplate>;
|
|
98
100
|
/**
|
|
99
101
|
* get edit template
|
|
100
102
|
* @param id
|
|
@@ -102,10 +104,7 @@ export declare abstract class BaseItem<T extends Item> {
|
|
|
102
104
|
* @param req
|
|
103
105
|
* @param modelId
|
|
104
106
|
*/
|
|
105
|
-
abstract getEditTemplate(id: string | number, catalogId: string, req: ReqType, modelId?: string | number): Promise<
|
|
106
|
-
type: 'component' | 'navigation.group' | 'navigation.link' | 'model' | 'model.link';
|
|
107
|
-
data: any;
|
|
108
|
-
}>;
|
|
107
|
+
abstract getEditTemplate(id: string | number, catalogId: string, req: ReqType, modelId?: string | number): Promise<CatalogTemplate>;
|
|
109
108
|
_getChilds(parentId: string | number, catalogId: string, req?: ReqType): Promise<Item[]>;
|
|
110
109
|
abstract getChilds(parentId: string | number, catalogId: string, req?: ReqType): Promise<Item[]>;
|
|
111
110
|
abstract search(s: string, catalogId: string, req?: ReqType): Promise<T[]>;
|
|
@@ -205,7 +204,22 @@ export declare abstract class AbstractCatalog {
|
|
|
205
204
|
* if pass null as parentId this root
|
|
206
205
|
*/
|
|
207
206
|
getChilds(parentId: string | number, byItemType?: string, req?: ReqType): Promise<Item[]>;
|
|
207
|
+
/**
|
|
208
|
+
* Registers the catalog access right through the legacy Adminizer API.
|
|
209
|
+
*
|
|
210
|
+
* @deprecated Starting with Adminizer v6, register access rights through
|
|
211
|
+
* `ctx.accessRight(...)` in the app's `setup` method.
|
|
212
|
+
* @param adminizer Adminizer instance used for legacy access-right registration.
|
|
213
|
+
*/
|
|
208
214
|
private _bindAccessRight;
|
|
215
|
+
/**
|
|
216
|
+
* @deprecated The `adminizer` parameter is deprecated and will be removed in
|
|
217
|
+
* Adminizer v6. Register the catalog through `AppManager` using
|
|
218
|
+
* `ctx.catalog(...)`, and register its access rights using
|
|
219
|
+
* `ctx.accessRight(...)`.
|
|
220
|
+
* @param adminizer Adminizer instance used by the legacy registration flow.
|
|
221
|
+
* @param items Catalog item types.
|
|
222
|
+
*/
|
|
209
223
|
protected constructor(adminizer: Adminizer, items: BaseItem<any>[]);
|
|
210
224
|
setId(id: string): void;
|
|
211
225
|
/**
|
|
@@ -214,6 +228,7 @@ export declare abstract class AbstractCatalog {
|
|
|
214
228
|
*/
|
|
215
229
|
getIdList(): Promise<string[]>;
|
|
216
230
|
getItemType(type: string): BaseItem<Item>;
|
|
231
|
+
private requireItemType;
|
|
217
232
|
getGroupType(): BaseItem<Item>;
|
|
218
233
|
additemTypes<T extends BaseItem<any>>(itemType: T): void;
|
|
219
234
|
/**
|
|
@@ -231,19 +246,13 @@ export declare abstract class AbstractCatalog {
|
|
|
231
246
|
* @param req
|
|
232
247
|
* @param modelId
|
|
233
248
|
*/
|
|
234
|
-
getEditTemplate(item: Item, id: string | number, req: ReqType, modelId?: string | number): Promise<
|
|
235
|
-
type: "component" | "navigation.group" | "navigation.link" | "model" | "model.link";
|
|
236
|
-
data: any;
|
|
237
|
-
}>;
|
|
249
|
+
getEditTemplate(item: Item, id: string | number, req: ReqType, modelId?: string | number): Promise<CatalogTemplate<any>>;
|
|
238
250
|
/**
|
|
239
251
|
* Get add template from an item type
|
|
240
252
|
* @param item
|
|
241
253
|
* @param req
|
|
242
254
|
*/
|
|
243
|
-
getAddTemplate(item: Item, req: ReqType): Promise<
|
|
244
|
-
type: "component" | "navigation.group" | "navigation.link" | "model" | "model.link";
|
|
245
|
-
data: any;
|
|
246
|
-
}>;
|
|
255
|
+
getAddTemplate(item: Item, req: ReqType): Promise<CatalogTemplate<any>>;
|
|
247
256
|
addActionHandler(actionHandler: ActionHandler): void;
|
|
248
257
|
/**
|
|
249
258
|
* Method for getting group elements
|
|
@@ -98,6 +98,13 @@ export class AbstractCatalog {
|
|
|
98
98
|
return result.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Registers the catalog access right through the legacy Adminizer API.
|
|
103
|
+
*
|
|
104
|
+
* @deprecated Starting with Adminizer v6, register access rights through
|
|
105
|
+
* `ctx.accessRight(...)` in the app's `setup` method.
|
|
106
|
+
* @param adminizer Adminizer instance used for legacy access-right registration.
|
|
107
|
+
*/
|
|
101
108
|
_bindAccessRight(adminizer) {
|
|
102
109
|
setTimeout(() => {
|
|
103
110
|
const postfix = this.id ? `${this.slug}-${this.id}` : `${this.slug}`;
|
|
@@ -109,6 +116,14 @@ export class AbstractCatalog {
|
|
|
109
116
|
});
|
|
110
117
|
}, 100);
|
|
111
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* @deprecated The `adminizer` parameter is deprecated and will be removed in
|
|
121
|
+
* Adminizer v6. Register the catalog through `AppManager` using
|
|
122
|
+
* `ctx.catalog(...)`, and register its access rights using
|
|
123
|
+
* `ctx.accessRight(...)`.
|
|
124
|
+
* @param adminizer Adminizer instance used by the legacy registration flow.
|
|
125
|
+
* @param items Catalog item types.
|
|
126
|
+
*/
|
|
112
127
|
constructor(adminizer, items) {
|
|
113
128
|
for (const item of items) {
|
|
114
129
|
this.additemTypes(item);
|
|
@@ -128,6 +143,13 @@ export class AbstractCatalog {
|
|
|
128
143
|
getItemType(type) {
|
|
129
144
|
return this.itemTypes.find((it) => it.type === type);
|
|
130
145
|
}
|
|
146
|
+
requireItemType(type) {
|
|
147
|
+
const itemType = this.getItemType(type);
|
|
148
|
+
if (!itemType) {
|
|
149
|
+
throw new Error(`Catalog item type \`${String(type)}\` was not found in catalog \`${this.slug}\``);
|
|
150
|
+
}
|
|
151
|
+
return itemType;
|
|
152
|
+
}
|
|
131
153
|
getGroupType() {
|
|
132
154
|
return this.itemTypes.find((it) => it.isGroup === true);
|
|
133
155
|
}
|
|
@@ -142,13 +164,13 @@ export class AbstractCatalog {
|
|
|
142
164
|
* Get an element
|
|
143
165
|
*/
|
|
144
166
|
async find(item, req) {
|
|
145
|
-
return await this.
|
|
167
|
+
return await this.requireItemType(item.type)._find(item.id, this.id, req);
|
|
146
168
|
}
|
|
147
169
|
/**
|
|
148
170
|
* Removing an element
|
|
149
171
|
*/
|
|
150
172
|
async deleteItem(type, id, req) {
|
|
151
|
-
await this.
|
|
173
|
+
await this.requireItemType(type).deleteItem(id, this.id, req);
|
|
152
174
|
}
|
|
153
175
|
/**
|
|
154
176
|
* Get edit template from an item type
|
|
@@ -158,7 +180,7 @@ export class AbstractCatalog {
|
|
|
158
180
|
* @param modelId
|
|
159
181
|
*/
|
|
160
182
|
getEditTemplate(item, id, req, modelId) {
|
|
161
|
-
return this.
|
|
183
|
+
return this.requireItemType(item.type).getEditTemplate(id, this.id, req, modelId);
|
|
162
184
|
}
|
|
163
185
|
/**
|
|
164
186
|
* Get add template from an item type
|
|
@@ -166,7 +188,7 @@ export class AbstractCatalog {
|
|
|
166
188
|
* @param req
|
|
167
189
|
*/
|
|
168
190
|
getAddTemplate(item, req) {
|
|
169
|
-
return this.
|
|
191
|
+
return this.requireItemType(item.type).getAddTemplate(req);
|
|
170
192
|
}
|
|
171
193
|
addActionHandler(actionHandler) {
|
|
172
194
|
if (actionHandler.selectedItemTypes.length > 0) {
|
|
@@ -232,12 +254,18 @@ export class AbstractCatalog {
|
|
|
232
254
|
* @param req
|
|
233
255
|
*/
|
|
234
256
|
async createItem(data, req) {
|
|
235
|
-
const
|
|
236
|
-
|
|
257
|
+
const result = await this.requireItemType(data.type).create(data, this.id, req);
|
|
258
|
+
if (!result) {
|
|
259
|
+
throw new Error(`Catalog item type \`${data.type}\` did not return created item`);
|
|
260
|
+
}
|
|
261
|
+
return result;
|
|
237
262
|
}
|
|
238
263
|
async updateItem(id, type, data, req) {
|
|
239
|
-
const
|
|
240
|
-
|
|
264
|
+
const result = await this.requireItemType(type).update(id, data, this.id, req);
|
|
265
|
+
if (!result) {
|
|
266
|
+
throw new Error(`Catalog item type \`${type}\` did not return updated item`);
|
|
267
|
+
}
|
|
268
|
+
return result;
|
|
241
269
|
}
|
|
242
270
|
/**
|
|
243
271
|
* To update all items in the tree after updating the model
|
|
@@ -247,8 +275,11 @@ export class AbstractCatalog {
|
|
|
247
275
|
* @param req
|
|
248
276
|
*/
|
|
249
277
|
async updateModelItems(modelId, type, data, req) {
|
|
250
|
-
const
|
|
251
|
-
|
|
278
|
+
const result = await this.requireItemType(type).updateModelItems(modelId, data, this.id, req);
|
|
279
|
+
if (!result) {
|
|
280
|
+
throw new Error(`Catalog item type \`${type}\` did not return updated model item`);
|
|
281
|
+
}
|
|
282
|
+
return result;
|
|
252
283
|
}
|
|
253
284
|
/**
|
|
254
285
|
* Method for getting group elements
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { AbstractCatalog } from "./AbstractCatalog";
|
|
2
|
+
export interface CatalogRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
appName: string;
|
|
5
|
+
catalog: AbstractCatalog;
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
}
|
|
2
8
|
export declare class CatalogHandler {
|
|
3
9
|
private catalog;
|
|
10
|
+
private records;
|
|
4
11
|
add(catalog: AbstractCatalog): AbstractCatalog;
|
|
5
12
|
getAll(): AbstractCatalog[];
|
|
6
13
|
getCatalog(slug: string): AbstractCatalog;
|
|
14
|
+
register(appName: string, catalog: AbstractCatalog): string;
|
|
15
|
+
unregister(id: string): void;
|
|
16
|
+
disable(id: string): void;
|
|
17
|
+
enable(id: string): void;
|
|
18
|
+
getByApp(appName: string): CatalogRecord[];
|
|
19
|
+
private getRecordId;
|
|
7
20
|
}
|
|
@@ -1,13 +1,59 @@
|
|
|
1
1
|
export class CatalogHandler {
|
|
2
2
|
catalog = [];
|
|
3
|
+
records = new Map();
|
|
3
4
|
add(catalog) {
|
|
4
5
|
this.catalog.push(catalog);
|
|
5
6
|
return catalog;
|
|
6
7
|
}
|
|
7
8
|
getAll() {
|
|
8
|
-
return
|
|
9
|
+
return [
|
|
10
|
+
...this.catalog,
|
|
11
|
+
...Array.from(this.records.values())
|
|
12
|
+
.filter((record) => record.enabled)
|
|
13
|
+
.map((record) => record.catalog)
|
|
14
|
+
];
|
|
9
15
|
}
|
|
10
16
|
getCatalog(slug) {
|
|
11
|
-
return this.
|
|
17
|
+
return this.getAll().find((catalog) => catalog.slug === slug);
|
|
18
|
+
}
|
|
19
|
+
register(appName, catalog) {
|
|
20
|
+
const id = this.getRecordId(appName, catalog);
|
|
21
|
+
if (this.records.has(id)) {
|
|
22
|
+
throw new Error(`Catalog "${id}" is already registered`);
|
|
23
|
+
}
|
|
24
|
+
const existingCatalog = this.getCatalog(catalog.slug);
|
|
25
|
+
if (existingCatalog) {
|
|
26
|
+
throw new Error(`Catalog with slug "${catalog.slug}" is already registered`);
|
|
27
|
+
}
|
|
28
|
+
this.records.set(id, {
|
|
29
|
+
id,
|
|
30
|
+
appName,
|
|
31
|
+
catalog,
|
|
32
|
+
enabled: true,
|
|
33
|
+
});
|
|
34
|
+
return id;
|
|
35
|
+
}
|
|
36
|
+
unregister(id) {
|
|
37
|
+
this.records.delete(id);
|
|
38
|
+
}
|
|
39
|
+
disable(id) {
|
|
40
|
+
const record = this.records.get(id);
|
|
41
|
+
if (!record) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
record.enabled = false;
|
|
45
|
+
}
|
|
46
|
+
enable(id) {
|
|
47
|
+
const record = this.records.get(id);
|
|
48
|
+
if (!record) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
record.enabled = true;
|
|
52
|
+
}
|
|
53
|
+
getByApp(appName) {
|
|
54
|
+
return Array.from(this.records.values()).filter((record) => record.appName === appName);
|
|
55
|
+
}
|
|
56
|
+
getRecordId(appName, catalog) {
|
|
57
|
+
return `${appName}:${catalog.slug}`;
|
|
12
58
|
}
|
|
13
59
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface CatalogTemplateComponentResource {
|
|
2
|
+
id: string;
|
|
3
|
+
type: string;
|
|
4
|
+
component: string;
|
|
5
|
+
exportName?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CatalogTemplateComponentRecord extends CatalogTemplateComponentResource {
|
|
8
|
+
id: string;
|
|
9
|
+
appName: string;
|
|
10
|
+
catalog: string;
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class CatalogTemplateComponentHandler {
|
|
14
|
+
private records;
|
|
15
|
+
register(appName: string, catalog: string, resource: CatalogTemplateComponentResource): string;
|
|
16
|
+
unregister(id: string): void;
|
|
17
|
+
disable(id: string): void;
|
|
18
|
+
enable(id: string): void;
|
|
19
|
+
getAll(): CatalogTemplateComponentRecord[];
|
|
20
|
+
getByApp(appName: string): CatalogTemplateComponentRecord[];
|
|
21
|
+
getByCatalog(catalog: string): CatalogTemplateComponentRecord[];
|
|
22
|
+
getByType(type: string, catalog: string): CatalogTemplateComponentRecord | undefined;
|
|
23
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function normalizeType(type) {
|
|
2
|
+
return type.toLowerCase();
|
|
3
|
+
}
|
|
4
|
+
function normalizeCatalog(catalog) {
|
|
5
|
+
return catalog.toLowerCase();
|
|
6
|
+
}
|
|
7
|
+
export class CatalogTemplateComponentHandler {
|
|
8
|
+
records = new Map();
|
|
9
|
+
register(appName, catalog, resource) {
|
|
10
|
+
const normalizedCatalog = normalizeCatalog(catalog);
|
|
11
|
+
const id = `${appName}:${normalizedCatalog}:${resource.id}`;
|
|
12
|
+
if (this.records.has(id)) {
|
|
13
|
+
throw new Error(`Catalog template component "${id}" is already registered`);
|
|
14
|
+
}
|
|
15
|
+
const existing = this.getByType(resource.type, normalizedCatalog);
|
|
16
|
+
if (existing) {
|
|
17
|
+
throw new Error(`Catalog template component for type "${resource.type}" is already registered in catalog "${normalizedCatalog}"`);
|
|
18
|
+
}
|
|
19
|
+
this.records.set(id, {
|
|
20
|
+
...resource,
|
|
21
|
+
id,
|
|
22
|
+
appName,
|
|
23
|
+
type: normalizeType(resource.type),
|
|
24
|
+
catalog: normalizedCatalog,
|
|
25
|
+
enabled: true,
|
|
26
|
+
});
|
|
27
|
+
return id;
|
|
28
|
+
}
|
|
29
|
+
unregister(id) {
|
|
30
|
+
this.records.delete(id);
|
|
31
|
+
}
|
|
32
|
+
disable(id) {
|
|
33
|
+
const record = this.records.get(id);
|
|
34
|
+
if (record) {
|
|
35
|
+
record.enabled = false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
enable(id) {
|
|
39
|
+
const record = this.records.get(id);
|
|
40
|
+
if (record) {
|
|
41
|
+
record.enabled = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
getAll() {
|
|
45
|
+
return Array.from(this.records.values()).filter((record) => record.enabled);
|
|
46
|
+
}
|
|
47
|
+
getByApp(appName) {
|
|
48
|
+
return Array.from(this.records.values()).filter((record) => record.appName === appName);
|
|
49
|
+
}
|
|
50
|
+
getByCatalog(catalog) {
|
|
51
|
+
const normalizedCatalog = normalizeCatalog(catalog);
|
|
52
|
+
return this.getAll().filter((record) => record.catalog === normalizedCatalog);
|
|
53
|
+
}
|
|
54
|
+
getByType(type, catalog) {
|
|
55
|
+
const normalizedType = normalizeType(type);
|
|
56
|
+
const normalizedCatalog = normalizeCatalog(catalog);
|
|
57
|
+
return this.getAll().find((record) => record.type === normalizedType && record.catalog === normalizedCatalog);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ControlType = 'wysiwyg' | 'jsonEditor' | 'geoJson' | 'markdown' | 'table' | 'codeEditor';
|
|
2
|
+
export interface Path {
|
|
3
|
+
jsPath: {
|
|
4
|
+
dev: string;
|
|
5
|
+
production: string;
|
|
6
|
+
};
|
|
7
|
+
cssPath: string;
|
|
8
|
+
}
|
|
9
|
+
export type Config = Record<string, string | string[] | object | number | boolean>;
|
|
10
|
+
export interface Control {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly type: ControlType;
|
|
13
|
+
getConfig(): Config | undefined;
|
|
14
|
+
getJsPath(): string | undefined;
|
|
15
|
+
getCssPath(): string | undefined;
|
|
16
|
+
getName(): string;
|
|
17
|
+
}
|