@qrvey/widget-configurability 0.0.0-beta.4589 → 0.0.0-beta.4657
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 +53 -0
- package/dist/cjs/index.js +12 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/metadata/customization-metadata.js +241 -0
- package/dist/cjs/metadata/customization-metadata.js.map +1 -0
- package/dist/cjs/metadata/index.js +11 -0
- package/dist/cjs/metadata/index.js.map +1 -0
- package/dist/cjs/metadata/labels/chart-panel.labels.js +56 -0
- package/dist/cjs/metadata/labels/chart-panel.labels.js.map +1 -0
- package/dist/cjs/metadata/labels/dashboard.labels.js +207 -0
- package/dist/cjs/metadata/labels/dashboard.labels.js.map +1 -0
- package/dist/cjs/metadata/metadata.models.js +3 -0
- package/dist/cjs/metadata/metadata.models.js.map +1 -0
- package/dist/cjs/models/remote.models.js +3 -0
- package/dist/cjs/models/remote.models.js.map +1 -0
- package/dist/cjs/models/validation.models.js +3 -0
- package/dist/cjs/models/validation.models.js.map +1 -0
- package/dist/cjs/remote/remote-customization.loader.js +213 -0
- package/dist/cjs/remote/remote-customization.loader.js.map +1 -0
- package/dist/cjs/structural-manager.js +35 -2
- package/dist/cjs/structural-manager.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/utils/defaults.helpers.js +3 -0
- package/dist/cjs/utils/defaults.helpers.js.map +1 -1
- package/dist/cjs/utils/layers.helpers.js +178 -0
- package/dist/cjs/utils/layers.helpers.js.map +1 -0
- package/dist/cjs/utils/logger.helpers.js +10 -0
- package/dist/cjs/utils/logger.helpers.js.map +1 -0
- package/dist/cjs/utils/scope.helpers.js +4 -1
- package/dist/cjs/utils/scope.helpers.js.map +1 -1
- package/dist/cjs/validation/customization.validator.js +366 -0
- package/dist/cjs/validation/customization.validator.js.map +1 -0
- package/dist/esm/index.mjs +846 -28
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/metadata.mjs +2750 -0
- package/dist/esm/metadata.mjs.map +1 -0
- package/dist/types/customization.models-CCSWjfb2.d.ts +47 -0
- package/dist/types/index.d.ts +98 -47
- package/dist/types/metadata.d.ts +59 -0
- package/package.json +7 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -128,6 +128,7 @@ var fontSizeMinMaxValue = /* @__PURE__ */ __name((minSize, maxSize) => (value) =
|
|
|
128
128
|
return `${closestSize}px`;
|
|
129
129
|
}, "fontSizeMinMaxValue");
|
|
130
130
|
var fontColorValue = /* @__PURE__ */ __name((value) => {
|
|
131
|
+
if (typeof value !== "string") return void 0;
|
|
131
132
|
const normalizedColor = value.toLowerCase();
|
|
132
133
|
return normalizedColor;
|
|
133
134
|
}, "fontColorValue");
|
|
@@ -1060,9 +1061,9 @@ __name(checkConditions, "checkConditions");
|
|
|
1060
1061
|
|
|
1061
1062
|
// src/utils/merge.helpers.ts
|
|
1062
1063
|
function mergeDeep(obj1, obj2, settings) {
|
|
1063
|
-
var
|
|
1064
|
+
var _a2, _b;
|
|
1064
1065
|
const defaultSettings = {
|
|
1065
|
-
mergeExistingValues: (
|
|
1066
|
+
mergeExistingValues: (_a2 = settings == null ? void 0 : settings.mergeExistingValues) != null ? _a2 : true,
|
|
1066
1067
|
mergeMissingProperties: (_b = settings == null ? void 0 : settings.mergeMissingProperties) != null ? _b : true
|
|
1067
1068
|
};
|
|
1068
1069
|
if (!isValid(obj1, obj2)) return objectCopy(obj1);
|
|
@@ -1111,6 +1112,164 @@ function isObject(value) {
|
|
|
1111
1112
|
}
|
|
1112
1113
|
__name(isObject, "isObject");
|
|
1113
1114
|
|
|
1115
|
+
// src/utils/layers.helpers.ts
|
|
1116
|
+
var SUBMODULES_KEY = "subModules";
|
|
1117
|
+
var isPlainObject = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]", "isPlainObject");
|
|
1118
|
+
var stringList = /* @__PURE__ */ __name((value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : void 0, "stringList");
|
|
1119
|
+
function normalizeCondition(value) {
|
|
1120
|
+
if (!isPlainObject(value)) return void 0;
|
|
1121
|
+
const { field, operator, value: conditionValue } = value;
|
|
1122
|
+
if (typeof field !== "string") return void 0;
|
|
1123
|
+
if (!allowedOperators.includes(operator)) return void 0;
|
|
1124
|
+
if (typeof conditionValue !== "string" && typeof conditionValue !== "number") return void 0;
|
|
1125
|
+
return {
|
|
1126
|
+
field,
|
|
1127
|
+
operator,
|
|
1128
|
+
value: conditionValue
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
__name(normalizeCondition, "normalizeCondition");
|
|
1132
|
+
function normalizeSubmodules(value) {
|
|
1133
|
+
if (!isPlainObject(value)) return void 0;
|
|
1134
|
+
const result = {};
|
|
1135
|
+
Object.keys(value).forEach((name) => {
|
|
1136
|
+
const submodule = normalizeLayer(value[name]);
|
|
1137
|
+
if (submodule) result[name] = submodule;
|
|
1138
|
+
});
|
|
1139
|
+
return result;
|
|
1140
|
+
}
|
|
1141
|
+
__name(normalizeSubmodules, "normalizeSubmodules");
|
|
1142
|
+
function normalizeLayer(value, allowViews = true) {
|
|
1143
|
+
if (!isPlainObject(value)) return void 0;
|
|
1144
|
+
const layer = {};
|
|
1145
|
+
const remove = stringList(value.remove);
|
|
1146
|
+
const keep = stringList(value.keep);
|
|
1147
|
+
if (remove) layer.remove = remove;
|
|
1148
|
+
if (keep) layer.keep = keep;
|
|
1149
|
+
if (isPlainObject(value.defaults)) layer.defaults = value.defaults;
|
|
1150
|
+
const subModules = normalizeSubmodules(value.subModules);
|
|
1151
|
+
if (subModules) layer.subModules = subModules;
|
|
1152
|
+
if (Array.isArray(value.conditional)) {
|
|
1153
|
+
layer.conditional = value.conditional.flatMap((item) => {
|
|
1154
|
+
const condition = isPlainObject(item) ? normalizeCondition(item.condition) : void 0;
|
|
1155
|
+
const rest = condition ? normalizeLayer(item, false) : void 0;
|
|
1156
|
+
return condition && rest ? [
|
|
1157
|
+
__spreadProps(__spreadValues({}, rest), {
|
|
1158
|
+
condition
|
|
1159
|
+
})
|
|
1160
|
+
] : [];
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
if (allowViews && isPlainObject(value.views)) {
|
|
1164
|
+
const views = value.views;
|
|
1165
|
+
layer.views = {};
|
|
1166
|
+
Object.keys(views).forEach((view) => {
|
|
1167
|
+
const viewLayer = normalizeLayer(views[view], false);
|
|
1168
|
+
if (viewLayer) layer.views[view] = viewLayer;
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
return layer;
|
|
1172
|
+
}
|
|
1173
|
+
__name(normalizeLayer, "normalizeLayer");
|
|
1174
|
+
function mergeDefaults(previous, next) {
|
|
1175
|
+
if (!isPlainObject(next)) return previous;
|
|
1176
|
+
return previous ? mergeDeep(previous, next) : next;
|
|
1177
|
+
}
|
|
1178
|
+
__name(mergeDefaults, "mergeDefaults");
|
|
1179
|
+
function mergeLayerDefaults(layers) {
|
|
1180
|
+
var _a2;
|
|
1181
|
+
const last = (_a2 = layers[layers.length - 1]) != null ? _a2 : {};
|
|
1182
|
+
const viewNames = new Set(layers.flatMap((layer) => {
|
|
1183
|
+
var _a3;
|
|
1184
|
+
return Object.keys((_a3 = layer.views) != null ? _a3 : {});
|
|
1185
|
+
}));
|
|
1186
|
+
const rootDefaults = layers.reduce((merged, layer) => mergeDefaults(merged, layer.defaults), void 0);
|
|
1187
|
+
const views = __spreadValues({}, last.views);
|
|
1188
|
+
viewNames.forEach((view) => {
|
|
1189
|
+
var _a3;
|
|
1190
|
+
const viewDefaults = layers.reduce((merged, layer) => {
|
|
1191
|
+
var _a4, _b;
|
|
1192
|
+
return mergeDefaults(mergeDefaults(merged, layer.defaults), (_b = (_a4 = layer.views) == null ? void 0 : _a4[view]) == null ? void 0 : _b.defaults);
|
|
1193
|
+
}, void 0);
|
|
1194
|
+
if (viewDefaults) {
|
|
1195
|
+
views[view] = __spreadProps(__spreadValues({}, (_a3 = last.views) == null ? void 0 : _a3[view]), {
|
|
1196
|
+
defaults: viewDefaults
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1200
|
+
const effective = __spreadValues({}, last);
|
|
1201
|
+
if (rootDefaults) effective.defaults = rootDefaults;
|
|
1202
|
+
if (viewNames.size) effective.views = views;
|
|
1203
|
+
return effective;
|
|
1204
|
+
}
|
|
1205
|
+
__name(mergeLayerDefaults, "mergeLayerDefaults");
|
|
1206
|
+
var isSubmodulesKey = /* @__PURE__ */ __name((key) => key === SUBMODULES_KEY || key.endsWith(`::${SUBMODULES_KEY}`), "isSubmodulesKey");
|
|
1207
|
+
var asItemObject = /* @__PURE__ */ __name((value) => isPlainObject(value) ? value : {}, "asItemObject");
|
|
1208
|
+
function intersectItem(current, other) {
|
|
1209
|
+
var _a2, _b, _c;
|
|
1210
|
+
const item = asItemObject(current);
|
|
1211
|
+
const otherItem = asItemObject(other);
|
|
1212
|
+
const childMap = item.childMap ? intersectViewMaps(item.childMap, (_a2 = otherItem.childMap) != null ? _a2 : {}) : void 0;
|
|
1213
|
+
const conditions = [
|
|
1214
|
+
...(_b = otherItem.conditions) != null ? _b : [],
|
|
1215
|
+
...(_c = item.conditions) != null ? _c : []
|
|
1216
|
+
];
|
|
1217
|
+
const hasDefaults = !!item.defaults && Object.keys(item.defaults).length > 0;
|
|
1218
|
+
const hasChildMap = !!childMap && Object.keys(childMap).length > 0;
|
|
1219
|
+
if (!hasDefaults && !hasChildMap && !conditions.length) {
|
|
1220
|
+
return isPlainObject(current) ? true : current;
|
|
1221
|
+
}
|
|
1222
|
+
return __spreadValues(__spreadValues(__spreadValues({}, hasDefaults && {
|
|
1223
|
+
defaults: item.defaults
|
|
1224
|
+
}), hasChildMap && {
|
|
1225
|
+
childMap
|
|
1226
|
+
}), conditions.length && {
|
|
1227
|
+
conditions
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
__name(intersectItem, "intersectItem");
|
|
1231
|
+
function intersectViewMaps(current, other) {
|
|
1232
|
+
const result = {};
|
|
1233
|
+
Object.keys(current).forEach((key) => {
|
|
1234
|
+
if (isSubmodulesKey(key)) {
|
|
1235
|
+
result[key] = current[key];
|
|
1236
|
+
} else if (key in other) {
|
|
1237
|
+
result[key] = intersectItem(current[key], other[key]);
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
return result;
|
|
1241
|
+
}
|
|
1242
|
+
__name(intersectViewMaps, "intersectViewMaps");
|
|
1243
|
+
function collectSubmoduleLayers(maps) {
|
|
1244
|
+
const result = {};
|
|
1245
|
+
maps.forEach((map) => {
|
|
1246
|
+
Object.keys(map).filter(isSubmodulesKey).forEach((key) => {
|
|
1247
|
+
const collection = map[key];
|
|
1248
|
+
if (!isPlainObject(collection)) return;
|
|
1249
|
+
Object.keys(collection).forEach((name) => {
|
|
1250
|
+
var _a2, _b;
|
|
1251
|
+
const submodule = collection[name];
|
|
1252
|
+
if (!isPlainObject(submodule)) return;
|
|
1253
|
+
if (!Object.keys(submodule).length) return;
|
|
1254
|
+
result[key] = (_a2 = result[key]) != null ? _a2 : {};
|
|
1255
|
+
result[key][name] = [
|
|
1256
|
+
...(_b = result[key][name]) != null ? _b : [],
|
|
1257
|
+
submodule
|
|
1258
|
+
];
|
|
1259
|
+
});
|
|
1260
|
+
});
|
|
1261
|
+
});
|
|
1262
|
+
return Object.keys(result).length ? result : void 0;
|
|
1263
|
+
}
|
|
1264
|
+
__name(collectSubmoduleLayers, "collectSubmoduleLayers");
|
|
1265
|
+
|
|
1266
|
+
// src/utils/logger.helpers.ts
|
|
1267
|
+
var LOG_PREFIX = "[widget-configurability]";
|
|
1268
|
+
function logWarning(message) {
|
|
1269
|
+
console.warn(`${LOG_PREFIX} ${message}`);
|
|
1270
|
+
}
|
|
1271
|
+
__name(logWarning, "logWarning");
|
|
1272
|
+
|
|
1114
1273
|
// src/utils/structural.helpers.ts
|
|
1115
1274
|
function getWidgetStructure(config, customization, validationMap, options) {
|
|
1116
1275
|
return calculateViewMap(config.baseStructure, customization, validationMap, __spreadProps(__spreadValues({}, options), {
|
|
@@ -1220,8 +1379,8 @@ function canInsertInCustomization(key, customization, validateKeepOption, keepAl
|
|
|
1220
1379
|
}
|
|
1221
1380
|
__name(canInsertInCustomization, "canInsertInCustomization");
|
|
1222
1381
|
function evalInsertKey(key, { viewKeys, viewPrefix = "", hasKeepOption, keepAliases }, customization) {
|
|
1223
|
-
var
|
|
1224
|
-
const customizationView = (
|
|
1382
|
+
var _a2;
|
|
1383
|
+
const customizationView = (_a2 = customization == null ? void 0 : customization.views) == null ? void 0 : _a2[viewPrefix];
|
|
1225
1384
|
const custCanInsert = customization ? canInsertInCustomization(key, customization, hasKeepOption === "root", keepAliases) : {
|
|
1226
1385
|
canInsert: true,
|
|
1227
1386
|
conditionAffect: false
|
|
@@ -1352,9 +1511,9 @@ function getConditionsForKey(key, conditionMaps) {
|
|
|
1352
1511
|
}
|
|
1353
1512
|
__name(getConditionsForKey, "getConditionsForKey");
|
|
1354
1513
|
function calculateConditions(config, customization, view, keepAliases) {
|
|
1355
|
-
var
|
|
1514
|
+
var _a2, _b, _c;
|
|
1356
1515
|
const rootConditionals = customization == null ? void 0 : customization.conditional;
|
|
1357
|
-
const viewConditionals = view ? (_b = (
|
|
1516
|
+
const viewConditionals = view ? (_b = (_a2 = customization == null ? void 0 : customization.views) == null ? void 0 : _a2[view]) == null ? void 0 : _b.conditional : void 0;
|
|
1358
1517
|
if (!rootConditionals && !viewConditionals) return void 0;
|
|
1359
1518
|
const customConditionals = [
|
|
1360
1519
|
...rootConditionals != null ? rootConditionals : [],
|
|
@@ -1370,16 +1529,16 @@ function calculateConditions(config, customization, view, keepAliases) {
|
|
|
1370
1529
|
}
|
|
1371
1530
|
__name(calculateConditions, "calculateConditions");
|
|
1372
1531
|
function calculateSubmodules(config, customization, view) {
|
|
1373
|
-
var
|
|
1374
|
-
const viewSubmodules = view ? (_b = (
|
|
1532
|
+
var _a2, _b;
|
|
1533
|
+
const viewSubmodules = view ? (_b = (_a2 = customization == null ? void 0 : customization.views) == null ? void 0 : _a2[view]) == null ? void 0 : _b.subModules : void 0;
|
|
1375
1534
|
const customRootSubmodules = customization == null ? void 0 : customization.subModules;
|
|
1376
1535
|
const customSubmodules = viewSubmodules ? mergeObjects(customRootSubmodules, viewSubmodules) : customRootSubmodules;
|
|
1377
1536
|
return mergeObjects(config.subModules, customSubmodules);
|
|
1378
1537
|
}
|
|
1379
1538
|
__name(calculateSubmodules, "calculateSubmodules");
|
|
1380
1539
|
function calculateCustomDefaults(customization, view, validationMap, sanitize) {
|
|
1381
|
-
var
|
|
1382
|
-
const viewDefaults = view ? (_b = (
|
|
1540
|
+
var _a2, _b, _c;
|
|
1541
|
+
const viewDefaults = view ? (_b = (_a2 = customization == null ? void 0 : customization.views) == null ? void 0 : _a2[view]) == null ? void 0 : _b.defaults : void 0;
|
|
1383
1542
|
const customRootDefaults = (_c = customization == null ? void 0 : customization.defaults) != null ? _c : {};
|
|
1384
1543
|
const defaultObj = viewDefaults ? mergeObjects(customRootDefaults, viewDefaults) : customRootDefaults;
|
|
1385
1544
|
if (!defaultObj || !validationMap && !sanitize) return defaultObj;
|
|
@@ -1416,7 +1575,7 @@ function mapArrayKeys(configValue, { viewPrefix, pathPrefix }) {
|
|
|
1416
1575
|
}
|
|
1417
1576
|
__name(mapArrayKeys, "mapArrayKeys");
|
|
1418
1577
|
function nodeHasKeepOption(configValue, customization, { viewPrefix, pathPrefix }) {
|
|
1419
|
-
var
|
|
1578
|
+
var _a2;
|
|
1420
1579
|
if (!customization) return;
|
|
1421
1580
|
const nodeKeys = Array.isArray(configValue) ? mapArrayKeys(configValue, {
|
|
1422
1581
|
viewPrefix,
|
|
@@ -1424,7 +1583,7 @@ function nodeHasKeepOption(configValue, customization, { viewPrefix, pathPrefix
|
|
|
1424
1583
|
}) : mapObjKeys(configValue, {
|
|
1425
1584
|
pathPrefix
|
|
1426
1585
|
});
|
|
1427
|
-
const customizationView = viewPrefix ? (
|
|
1586
|
+
const customizationView = viewPrefix ? (_a2 = customization == null ? void 0 : customization.views) == null ? void 0 : _a2[viewPrefix] : void 0;
|
|
1428
1587
|
for (const key of nodeKeys) {
|
|
1429
1588
|
if (keyIsIncludedInKeep(key, customization)) {
|
|
1430
1589
|
return "root";
|
|
@@ -1480,9 +1639,9 @@ __name(calculatePermissionMapArray, "calculatePermissionMapArray");
|
|
|
1480
1639
|
|
|
1481
1640
|
// src/structural-manager.ts
|
|
1482
1641
|
function getWidgetConfig(widget, version) {
|
|
1483
|
-
var
|
|
1642
|
+
var _a2;
|
|
1484
1643
|
const versionSet = version != null ? version : WidgetVersion.latest;
|
|
1485
|
-
const widgetConfigurability = (
|
|
1644
|
+
const widgetConfigurability = (_a2 = widgetConfigs[widget]) == null ? void 0 : _a2[versionSet];
|
|
1486
1645
|
if (!widgetConfigurability) {
|
|
1487
1646
|
throw new Error(`No config found for widget ${widget} and version ${version}`);
|
|
1488
1647
|
}
|
|
@@ -1490,20 +1649,45 @@ function getWidgetConfig(widget, version) {
|
|
|
1490
1649
|
}
|
|
1491
1650
|
__name(getWidgetConfig, "getWidgetConfig");
|
|
1492
1651
|
function buildStructure(widget, customization, version, options) {
|
|
1493
|
-
var
|
|
1652
|
+
var _a2, _b;
|
|
1494
1653
|
const config = getWidgetConfig(widget, version);
|
|
1495
|
-
const validationMap = (
|
|
1654
|
+
const validationMap = (_a2 = options == null ? void 0 : options.validationMap) != null ? _a2 : widgetValidators[widget];
|
|
1655
|
+
const layers = ((_b = options == null ? void 0 : options.layers) != null ? _b : []).map((layer) => normalizeLayer(layer)).filter((layer) => !!layer);
|
|
1656
|
+
if (layers.length) {
|
|
1657
|
+
try {
|
|
1658
|
+
return buildLayeredStructure(config, layers, customization, validationMap, options);
|
|
1659
|
+
} catch (error) {
|
|
1660
|
+
logWarning(`ignoring the ${widget} customization layers: ${error.message}`);
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1496
1663
|
const structureMap = getWidgetStructure(config, customization, validationMap, options);
|
|
1497
1664
|
const rootDefaults = config.baseStructure.views ? void 0 : calculateRootDefaults(config.baseStructure, customization, validationMap, options == null ? void 0 : options.sanitize);
|
|
1498
1665
|
return new WidgetStructureInstance(structureMap, rootDefaults);
|
|
1499
1666
|
}
|
|
1500
1667
|
__name(buildStructure, "buildStructure");
|
|
1668
|
+
function buildLayeredStructure(config, layers, customization, validationMap, options) {
|
|
1669
|
+
const inline = isPlainObject(customization) ? customization : {};
|
|
1670
|
+
const effective = mergeLayerDefaults([
|
|
1671
|
+
...layers,
|
|
1672
|
+
inline
|
|
1673
|
+
]);
|
|
1674
|
+
const engineOptions = {
|
|
1675
|
+
viewConditionals: options == null ? void 0 : options.viewConditionals
|
|
1676
|
+
};
|
|
1677
|
+
const layerMaps = layers.map((layer) => getWidgetStructure(config, layer, void 0, engineOptions));
|
|
1678
|
+
const structureMap = layerMaps.reduce((result, layerMap) => intersectViewMaps(result, layerMap), getWidgetStructure(config, effective, validationMap, options));
|
|
1679
|
+
const rootDefaults = config.baseStructure.views ? void 0 : calculateRootDefaults(config.baseStructure, effective, validationMap, options == null ? void 0 : options.sanitize);
|
|
1680
|
+
return new WidgetStructureInstance(structureMap, rootDefaults, collectSubmoduleLayers(layerMaps));
|
|
1681
|
+
}
|
|
1682
|
+
__name(buildLayeredStructure, "buildLayeredStructure");
|
|
1501
1683
|
var _WidgetStructureInstance = class _WidgetStructureInstance {
|
|
1502
|
-
constructor(viewMap, rootDefaults) {
|
|
1684
|
+
constructor(viewMap, rootDefaults, submoduleLayers) {
|
|
1503
1685
|
__publicField(this, "viewMap");
|
|
1504
1686
|
__publicField(this, "rootDefaults");
|
|
1687
|
+
__publicField(this, "submoduleLayers");
|
|
1505
1688
|
this.viewMap = viewMap;
|
|
1506
1689
|
this.rootDefaults = rootDefaults;
|
|
1690
|
+
this.submoduleLayers = submoduleLayers;
|
|
1507
1691
|
}
|
|
1508
1692
|
getValue(key) {
|
|
1509
1693
|
return this.viewMap[key];
|
|
@@ -1526,6 +1710,14 @@ var _WidgetStructureInstance = class _WidgetStructureInstance {
|
|
|
1526
1710
|
const value = this.getValue(key);
|
|
1527
1711
|
return value == null ? void 0 : value[module2];
|
|
1528
1712
|
}
|
|
1713
|
+
/**
|
|
1714
|
+
* Submodule customizations of the stored layers, to pass as layers when building the embedded widget (structureFromSubmodule).
|
|
1715
|
+
*/
|
|
1716
|
+
getSubmoduleLayers(module2, view) {
|
|
1717
|
+
var _a2, _b;
|
|
1718
|
+
const key = `${view ? view + "::" : ""}subModules`;
|
|
1719
|
+
return (_b = (_a2 = this.submoduleLayers) == null ? void 0 : _a2[key]) == null ? void 0 : _b[module2];
|
|
1720
|
+
}
|
|
1529
1721
|
getDefaults(key) {
|
|
1530
1722
|
const value = this.getValue(key);
|
|
1531
1723
|
if (!value || typeof value === "boolean" || typeof value === "string" || !value.defaults) return void 0;
|
|
@@ -1538,10 +1730,10 @@ var _WidgetStructureInstance = class _WidgetStructureInstance {
|
|
|
1538
1730
|
* Re-roots a resolved section (`design::downloadModal`) as plain JSON another bundle can rebuild a structure from.
|
|
1539
1731
|
*/
|
|
1540
1732
|
scope(prefixKey, options = {}) {
|
|
1541
|
-
var
|
|
1733
|
+
var _a2;
|
|
1542
1734
|
const { widget, version, state } = options;
|
|
1543
1735
|
const present = this.isVisible(prefixKey, state);
|
|
1544
|
-
const sectionPath = (
|
|
1736
|
+
const sectionPath = (_a2 = prefixKey.split(STRUCTURE_VIEW_NAME_SEPARATOR).pop()) != null ? _a2 : prefixKey;
|
|
1545
1737
|
const namespace = options.defaultsNamespace === void 0 ? sectionPath.split(STRUCTURE_SECTION_NAME_SEPARATOR).pop() : options.defaultsNamespace;
|
|
1546
1738
|
const sectionDefaults = present ? this.getDefaults(prefixKey) : void 0;
|
|
1547
1739
|
const defaults = namespace ? sectionDefaults == null ? void 0 : sectionDefaults[namespace] : sectionDefaults;
|
|
@@ -1577,14 +1769,14 @@ __name(_WidgetStructureInstance, "WidgetStructureInstance");
|
|
|
1577
1769
|
var WidgetStructureInstance = _WidgetStructureInstance;
|
|
1578
1770
|
|
|
1579
1771
|
// src/utils/scope.helpers.ts
|
|
1580
|
-
var
|
|
1772
|
+
var isPlainObject2 = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null && !Array.isArray(value), "isPlainObject");
|
|
1581
1773
|
function isWidgetStructureScope(value) {
|
|
1582
|
-
return
|
|
1774
|
+
return isPlainObject2(value) && value.kind === WIDGET_STRUCTURE_SCOPE_KIND;
|
|
1583
1775
|
}
|
|
1584
1776
|
__name(isWidgetStructureScope, "isWidgetStructureScope");
|
|
1585
1777
|
function scopeToCustomization(scope) {
|
|
1586
|
-
var
|
|
1587
|
-
const remove = scope.present ? Object.keys((
|
|
1778
|
+
var _a2;
|
|
1779
|
+
const remove = scope.present ? Object.keys((_a2 = scope.map) != null ? _a2 : {}).filter((key) => scope.map[key] === false) : [
|
|
1588
1780
|
"*"
|
|
1589
1781
|
];
|
|
1590
1782
|
return __spreadValues(__spreadValues({}, remove.length ? {
|
|
@@ -1602,8 +1794,8 @@ function extractCustomization(host, customization, prefixKey, target, options) {
|
|
|
1602
1794
|
}
|
|
1603
1795
|
__name(extractCustomization, "extractCustomization");
|
|
1604
1796
|
function submoduleOf(input, module2, view) {
|
|
1605
|
-
var
|
|
1606
|
-
const root = (
|
|
1797
|
+
var _a2, _b, _c, _d;
|
|
1798
|
+
const root = (_a2 = input.subModules) == null ? void 0 : _a2[module2];
|
|
1607
1799
|
const fromView = view ? (_d = (_c = (_b = input.views) == null ? void 0 : _b[view]) == null ? void 0 : _c.subModules) == null ? void 0 : _d[module2] : void 0;
|
|
1608
1800
|
if (!fromView) return root;
|
|
1609
1801
|
return root ? mergeDeep(root, fromView) : fromView;
|
|
@@ -1612,7 +1804,7 @@ __name(submoduleOf, "submoduleOf");
|
|
|
1612
1804
|
function structureFrom(widget, input, view, version) {
|
|
1613
1805
|
if (input === void 0 || input === null) return void 0;
|
|
1614
1806
|
try {
|
|
1615
|
-
if (!
|
|
1807
|
+
if (!isPlainObject2(input)) {
|
|
1616
1808
|
throw new Error("expected an object");
|
|
1617
1809
|
}
|
|
1618
1810
|
if ("kind" in input) {
|
|
@@ -1638,14 +1830,640 @@ function structureFrom(widget, input, view, version) {
|
|
|
1638
1830
|
}
|
|
1639
1831
|
__name(structureFrom, "structureFrom");
|
|
1640
1832
|
function structureFromSubmodule(parent, module2, view, options) {
|
|
1833
|
+
var _a2;
|
|
1641
1834
|
const widget = Object.keys(WIDGET_SUBMODULE_NAMES).find((key) => WIDGET_SUBMODULE_NAMES[key] === module2);
|
|
1642
1835
|
if (!widget) {
|
|
1643
1836
|
throw new Error(`No widget registered for the submodule ${module2}`);
|
|
1644
1837
|
}
|
|
1645
|
-
|
|
1838
|
+
const layers = parent.getSubmoduleLayers(module2, view);
|
|
1839
|
+
return buildStructure(widget, parent.getSubmodule(module2, view), void 0, layers ? __spreadProps(__spreadValues({}, options), {
|
|
1840
|
+
layers: [
|
|
1841
|
+
...(_a2 = options == null ? void 0 : options.layers) != null ? _a2 : [],
|
|
1842
|
+
...layers
|
|
1843
|
+
]
|
|
1844
|
+
}) : options);
|
|
1646
1845
|
}
|
|
1647
1846
|
__name(structureFromSubmodule, "structureFromSubmodule");
|
|
1648
1847
|
|
|
1848
|
+
// src/validation/customization.validator.ts
|
|
1849
|
+
var ROOT_PROPERTIES = [
|
|
1850
|
+
"remove",
|
|
1851
|
+
"keep",
|
|
1852
|
+
"defaults",
|
|
1853
|
+
"subModules",
|
|
1854
|
+
"conditional",
|
|
1855
|
+
"views"
|
|
1856
|
+
];
|
|
1857
|
+
var VIEW_PROPERTIES = [
|
|
1858
|
+
"remove",
|
|
1859
|
+
"keep",
|
|
1860
|
+
"defaults",
|
|
1861
|
+
"subModules",
|
|
1862
|
+
"conditional"
|
|
1863
|
+
];
|
|
1864
|
+
var CONDITIONAL_PROPERTIES = [
|
|
1865
|
+
"condition",
|
|
1866
|
+
"remove",
|
|
1867
|
+
"keep",
|
|
1868
|
+
"defaults",
|
|
1869
|
+
"subModules"
|
|
1870
|
+
];
|
|
1871
|
+
var CONDITION_PROPERTIES = [
|
|
1872
|
+
"field",
|
|
1873
|
+
"operator",
|
|
1874
|
+
"value"
|
|
1875
|
+
];
|
|
1876
|
+
var KEY_CHARS = /^[A-Za-z0-9_.-]+$/;
|
|
1877
|
+
var ROOT_SCOPE = "";
|
|
1878
|
+
var oneOf = /* @__PURE__ */ __name((values) => (value) => typeof value === "string" && values.includes(value) ? value : void 0, "oneOf");
|
|
1879
|
+
var DX_WRITE_VALIDATOR_MAP = {
|
|
1880
|
+
changeLayout: validateBoolean,
|
|
1881
|
+
removeElement: validateBoolean,
|
|
1882
|
+
dragElement: validateBoolean,
|
|
1883
|
+
resizeElement: validateBoolean,
|
|
1884
|
+
assetListViewMode: oneOf([
|
|
1885
|
+
"card",
|
|
1886
|
+
"table"
|
|
1887
|
+
]),
|
|
1888
|
+
"downloadModal.exportVersion": oneOf([
|
|
1889
|
+
"saved",
|
|
1890
|
+
"unsaved"
|
|
1891
|
+
])
|
|
1892
|
+
};
|
|
1893
|
+
var writeValidators = {
|
|
1894
|
+
[Widget.DASHBOARD]: __spreadValues(__spreadValues({}, widgetValidators[Widget.DASHBOARD]), DX_WRITE_VALIDATOR_MAP)
|
|
1895
|
+
};
|
|
1896
|
+
var keyCache = /* @__PURE__ */ new Map();
|
|
1897
|
+
function structureKeys(config) {
|
|
1898
|
+
const cached = keyCache.get(config);
|
|
1899
|
+
if (cached) return cached;
|
|
1900
|
+
const byView = /* @__PURE__ */ new Map([
|
|
1901
|
+
[
|
|
1902
|
+
ROOT_SCOPE,
|
|
1903
|
+
/* @__PURE__ */ new Set()
|
|
1904
|
+
]
|
|
1905
|
+
]);
|
|
1906
|
+
Object.keys(calculateViewMap(config.baseStructure)).forEach((entry) => {
|
|
1907
|
+
const separator = entry.indexOf(STRUCTURE_VIEW_NAME_SEPARATOR);
|
|
1908
|
+
const view = separator >= 0 ? entry.slice(0, separator) : ROOT_SCOPE;
|
|
1909
|
+
const key = separator >= 0 ? entry.slice(separator + STRUCTURE_VIEW_NAME_SEPARATOR.length) : entry;
|
|
1910
|
+
if (key === "subModules") return;
|
|
1911
|
+
if (!byView.has(view)) byView.set(view, /* @__PURE__ */ new Set());
|
|
1912
|
+
byView.get(view).add(key);
|
|
1913
|
+
byView.get(ROOT_SCOPE).add(key);
|
|
1914
|
+
});
|
|
1915
|
+
keyCache.set(config, byView);
|
|
1916
|
+
return byView;
|
|
1917
|
+
}
|
|
1918
|
+
__name(structureKeys, "structureKeys");
|
|
1919
|
+
function resolveConfig(widget, version) {
|
|
1920
|
+
const versions = widgetConfigs[widget];
|
|
1921
|
+
if (!versions) return void 0;
|
|
1922
|
+
if (!version) return versions[WidgetVersion.latest];
|
|
1923
|
+
const match = Object.keys(versions).find((key) => {
|
|
1924
|
+
var _a2;
|
|
1925
|
+
return key === version || ((_a2 = versions[key]) == null ? void 0 : _a2.version) === version;
|
|
1926
|
+
});
|
|
1927
|
+
return match ? versions[match] : void 0;
|
|
1928
|
+
}
|
|
1929
|
+
__name(resolveConfig, "resolveConfig");
|
|
1930
|
+
function createScope(widget, config) {
|
|
1931
|
+
var _a2, _b;
|
|
1932
|
+
return {
|
|
1933
|
+
widget,
|
|
1934
|
+
config,
|
|
1935
|
+
keys: structureKeys(config),
|
|
1936
|
+
views: Object.keys((_a2 = config.baseStructure.views) != null ? _a2 : {}),
|
|
1937
|
+
subModules: Object.keys((_b = config.baseStructure.subModules) != null ? _b : {})
|
|
1938
|
+
};
|
|
1939
|
+
}
|
|
1940
|
+
__name(createScope, "createScope");
|
|
1941
|
+
function levenshtein(a, b) {
|
|
1942
|
+
const previous = Array.from({
|
|
1943
|
+
length: b.length + 1
|
|
1944
|
+
}, (_, i) => i);
|
|
1945
|
+
for (let i = 1; i <= a.length; i++) {
|
|
1946
|
+
let diagonal = previous[0];
|
|
1947
|
+
previous[0] = i;
|
|
1948
|
+
for (let j = 1; j <= b.length; j++) {
|
|
1949
|
+
const above = previous[j];
|
|
1950
|
+
previous[j] = Math.min(previous[j] + 1, previous[j - 1] + 1, diagonal + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
1951
|
+
diagonal = above;
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
return previous[b.length];
|
|
1955
|
+
}
|
|
1956
|
+
__name(levenshtein, "levenshtein");
|
|
1957
|
+
function suggestKey(key, candidates) {
|
|
1958
|
+
const leaf = key.split(".").pop();
|
|
1959
|
+
let best;
|
|
1960
|
+
let bestDistance = Math.max(2, Math.floor(key.length * 0.3)) + 1;
|
|
1961
|
+
for (const candidate of candidates) {
|
|
1962
|
+
if (candidate.split(".").pop() === leaf && candidate !== key) return candidate;
|
|
1963
|
+
const distance = levenshtein(key.toLowerCase(), candidate.toLowerCase());
|
|
1964
|
+
if (distance < bestDistance) {
|
|
1965
|
+
best = candidate;
|
|
1966
|
+
bestDistance = distance;
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
return best;
|
|
1970
|
+
}
|
|
1971
|
+
__name(suggestKey, "suggestKey");
|
|
1972
|
+
function formatCustomizationPath(path) {
|
|
1973
|
+
return path.reduce((result, part) => typeof part === "number" ? `${result}[${part}]` : result ? `${result}.${part}` : part, "");
|
|
1974
|
+
}
|
|
1975
|
+
__name(formatCustomizationPath, "formatCustomizationPath");
|
|
1976
|
+
var _a;
|
|
1977
|
+
var Collector = (_a = class {
|
|
1978
|
+
constructor() {
|
|
1979
|
+
__publicField(this, "errors", []);
|
|
1980
|
+
}
|
|
1981
|
+
add(path, code, message, suggestion) {
|
|
1982
|
+
this.errors.push(__spreadValues({
|
|
1983
|
+
path,
|
|
1984
|
+
code,
|
|
1985
|
+
severity: "error",
|
|
1986
|
+
message
|
|
1987
|
+
}, suggestion && {
|
|
1988
|
+
suggestion
|
|
1989
|
+
}));
|
|
1990
|
+
}
|
|
1991
|
+
}, __name(_a, "Collector"), _a);
|
|
1992
|
+
var describeScope = /* @__PURE__ */ __name((scope, view) => {
|
|
1993
|
+
const owner = scope.widget === Widget.DASHBOARD ? "" : ` of the ${scope.widget}`;
|
|
1994
|
+
if (view !== ROOT_SCOPE) return `in the ${view} view${owner}`;
|
|
1995
|
+
return scope.views.length ? `in any view${owner}` : `in the ${scope.widget} structure`;
|
|
1996
|
+
}, "describeScope");
|
|
1997
|
+
function patternError(pattern) {
|
|
1998
|
+
if (!pattern.trim()) return "Empty key";
|
|
1999
|
+
if (!pattern.includes("*")) {
|
|
2000
|
+
return KEY_CHARS.test(pattern) && !pattern.includes("..") ? void 0 : `Key '${pattern}' contains characters that are not allowed`;
|
|
2001
|
+
}
|
|
2002
|
+
if (pattern === "*") return void 0;
|
|
2003
|
+
const inner = pattern.replace(/^\*/, "").replace(/\*$/, "");
|
|
2004
|
+
if (!inner || inner.includes("*") || !KEY_CHARS.test(inner) || inner.includes("..")) {
|
|
2005
|
+
return `Pattern '${pattern}' is not a valid wildcard; use *text, text* or *text*`;
|
|
2006
|
+
}
|
|
2007
|
+
return void 0;
|
|
2008
|
+
}
|
|
2009
|
+
__name(patternError, "patternError");
|
|
2010
|
+
function validateKeyList(collector, value, path, scope, view) {
|
|
2011
|
+
var _a2;
|
|
2012
|
+
if (!Array.isArray(value)) {
|
|
2013
|
+
collector.add(path, "INVALID_TYPE", `'${path[path.length - 1]}' must be an array of keys`);
|
|
2014
|
+
return;
|
|
2015
|
+
}
|
|
2016
|
+
const keys = (_a2 = scope.keys.get(view)) != null ? _a2 : /* @__PURE__ */ new Set();
|
|
2017
|
+
value.forEach((item, index) => {
|
|
2018
|
+
const itemPath = [
|
|
2019
|
+
...path,
|
|
2020
|
+
index
|
|
2021
|
+
];
|
|
2022
|
+
if (typeof item !== "string") {
|
|
2023
|
+
collector.add(itemPath, "INVALID_TYPE", "Each key must be a string");
|
|
2024
|
+
return;
|
|
2025
|
+
}
|
|
2026
|
+
const invalid = patternError(item);
|
|
2027
|
+
if (invalid) {
|
|
2028
|
+
collector.add(itemPath, "INVALID_PATTERN", invalid);
|
|
2029
|
+
} else if (!item.includes("*") && !keys.has(item)) {
|
|
2030
|
+
collector.add(itemPath, "UNKNOWN_KEY", `Key '${item}' does not exist ${describeScope(scope, view)}`, suggestKey(item, keys));
|
|
2031
|
+
}
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
__name(validateKeyList, "validateKeyList");
|
|
2035
|
+
function safeValidate(validator, value) {
|
|
2036
|
+
try {
|
|
2037
|
+
return validator(value);
|
|
2038
|
+
} catch (e) {
|
|
2039
|
+
return void 0;
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
__name(safeValidate, "safeValidate");
|
|
2043
|
+
function validateDefaultsObject(collector, value, path, validators) {
|
|
2044
|
+
if (!isPlainObject(value)) {
|
|
2045
|
+
collector.add(path, "INVALID_TYPE", "'defaults' must be an object");
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
2048
|
+
const walk = /* @__PURE__ */ __name((node, parents) => {
|
|
2049
|
+
Object.keys(node).forEach((key) => {
|
|
2050
|
+
const keyPath = [
|
|
2051
|
+
...parents,
|
|
2052
|
+
key
|
|
2053
|
+
];
|
|
2054
|
+
const current = node[key];
|
|
2055
|
+
const validator = validators == null ? void 0 : validators[keyPath.join(".")];
|
|
2056
|
+
if (isPlainObject(current)) {
|
|
2057
|
+
walk(current, keyPath);
|
|
2058
|
+
} else if (validator && current !== void 0 && safeValidate(validator, current) === void 0) {
|
|
2059
|
+
collector.add([
|
|
2060
|
+
...path,
|
|
2061
|
+
...keyPath
|
|
2062
|
+
], "INVALID_DEFAULT", `Default '${keyPath.join(".")}' does not accept the value ${JSON.stringify(current)}`);
|
|
2063
|
+
}
|
|
2064
|
+
});
|
|
2065
|
+
}, "walk");
|
|
2066
|
+
walk(value, []);
|
|
2067
|
+
}
|
|
2068
|
+
__name(validateDefaultsObject, "validateDefaultsObject");
|
|
2069
|
+
function validateProperties(collector, value, path, allowed) {
|
|
2070
|
+
Object.keys(value).filter((key) => !allowed.includes(key)).forEach((key) => collector.add([
|
|
2071
|
+
...path,
|
|
2072
|
+
key
|
|
2073
|
+
], "UNKNOWN_PROPERTY", `Property '${key}' is not part of the customization grammar; valid properties: ${allowed.join(", ")}`));
|
|
2074
|
+
}
|
|
2075
|
+
__name(validateProperties, "validateProperties");
|
|
2076
|
+
function validateCondition(collector, value, path) {
|
|
2077
|
+
if (!isPlainObject(value)) {
|
|
2078
|
+
collector.add(path, "INVALID_CONDITION", "A conditional needs a 'condition' object with field, operator and value");
|
|
2079
|
+
return;
|
|
2080
|
+
}
|
|
2081
|
+
validateProperties(collector, value, path, CONDITION_PROPERTIES);
|
|
2082
|
+
if (typeof value.field !== "string" || !value.field) {
|
|
2083
|
+
collector.add([
|
|
2084
|
+
...path,
|
|
2085
|
+
"field"
|
|
2086
|
+
], "INVALID_CONDITION", "The condition 'field' must be a non-empty string");
|
|
2087
|
+
}
|
|
2088
|
+
if (!allowedOperators.includes(value.operator)) {
|
|
2089
|
+
collector.add([
|
|
2090
|
+
...path,
|
|
2091
|
+
"operator"
|
|
2092
|
+
], "INVALID_CONDITION", `Unknown operator ${JSON.stringify(value.operator)}; valid operators: ${allowedOperators.join(", ")}`);
|
|
2093
|
+
}
|
|
2094
|
+
if (typeof value.value !== "string" && typeof value.value !== "number") {
|
|
2095
|
+
collector.add([
|
|
2096
|
+
...path,
|
|
2097
|
+
"value"
|
|
2098
|
+
], "INVALID_CONDITION", "The condition 'value' must be a string or a number");
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
__name(validateCondition, "validateCondition");
|
|
2102
|
+
function validateBlock(collector, value, path, scope, view, allowed) {
|
|
2103
|
+
if (!isPlainObject(value)) {
|
|
2104
|
+
collector.add(path, "INVALID_TYPE", "A customization must be an object");
|
|
2105
|
+
return;
|
|
2106
|
+
}
|
|
2107
|
+
validateProperties(collector, value, path, allowed);
|
|
2108
|
+
const has = /* @__PURE__ */ __name((property) => property in value && allowed.includes(property), "has");
|
|
2109
|
+
if ("remove" in value) validateKeyList(collector, value.remove, [
|
|
2110
|
+
...path,
|
|
2111
|
+
"remove"
|
|
2112
|
+
], scope, view);
|
|
2113
|
+
if ("keep" in value) validateKeyList(collector, value.keep, [
|
|
2114
|
+
...path,
|
|
2115
|
+
"keep"
|
|
2116
|
+
], scope, view);
|
|
2117
|
+
if ("defaults" in value) {
|
|
2118
|
+
validateDefaultsObject(collector, value.defaults, [
|
|
2119
|
+
...path,
|
|
2120
|
+
"defaults"
|
|
2121
|
+
], writeValidators[scope.widget]);
|
|
2122
|
+
}
|
|
2123
|
+
if ("subModules" in value) validateSubmodules(collector, value.subModules, [
|
|
2124
|
+
...path,
|
|
2125
|
+
"subModules"
|
|
2126
|
+
], scope);
|
|
2127
|
+
if (has("conditional")) {
|
|
2128
|
+
if (!Array.isArray(value.conditional)) {
|
|
2129
|
+
collector.add([
|
|
2130
|
+
...path,
|
|
2131
|
+
"conditional"
|
|
2132
|
+
], "INVALID_TYPE", "'conditional' must be an array");
|
|
2133
|
+
} else {
|
|
2134
|
+
value.conditional.forEach((item, index) => {
|
|
2135
|
+
const itemPath = [
|
|
2136
|
+
...path,
|
|
2137
|
+
"conditional",
|
|
2138
|
+
index
|
|
2139
|
+
];
|
|
2140
|
+
if (!isPlainObject(item)) {
|
|
2141
|
+
collector.add(itemPath, "INVALID_CONDITION", "Each conditional must be an object");
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2144
|
+
validateCondition(collector, item.condition, [
|
|
2145
|
+
...itemPath,
|
|
2146
|
+
"condition"
|
|
2147
|
+
]);
|
|
2148
|
+
validateBlock(collector, item, itemPath, scope, view, CONDITIONAL_PROPERTIES);
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
if (has("views")) validateViews(collector, value.views, [
|
|
2153
|
+
...path,
|
|
2154
|
+
"views"
|
|
2155
|
+
], scope);
|
|
2156
|
+
}
|
|
2157
|
+
__name(validateBlock, "validateBlock");
|
|
2158
|
+
function validateViews(collector, value, path, scope) {
|
|
2159
|
+
if (!isPlainObject(value)) {
|
|
2160
|
+
collector.add(path, "INVALID_TYPE", "'views' must be an object");
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2163
|
+
Object.keys(value).forEach((view) => {
|
|
2164
|
+
if (!scope.views.includes(view)) {
|
|
2165
|
+
const valid = scope.views.length ? `valid views: ${scope.views.join(", ")}` : `the ${scope.widget} widget has no views`;
|
|
2166
|
+
collector.add([
|
|
2167
|
+
...path,
|
|
2168
|
+
view
|
|
2169
|
+
], "UNKNOWN_VIEW", `View '${view}' does not exist; ${valid}`);
|
|
2170
|
+
return;
|
|
2171
|
+
}
|
|
2172
|
+
validateBlock(collector, value[view], [
|
|
2173
|
+
...path,
|
|
2174
|
+
view
|
|
2175
|
+
], scope, view, VIEW_PROPERTIES);
|
|
2176
|
+
});
|
|
2177
|
+
}
|
|
2178
|
+
__name(validateViews, "validateViews");
|
|
2179
|
+
function validateSubmodules(collector, value, path, scope) {
|
|
2180
|
+
if (!isPlainObject(value)) {
|
|
2181
|
+
collector.add(path, "INVALID_TYPE", "'subModules' must be an object");
|
|
2182
|
+
return;
|
|
2183
|
+
}
|
|
2184
|
+
Object.keys(value).forEach((name) => {
|
|
2185
|
+
const subPath = [
|
|
2186
|
+
...path,
|
|
2187
|
+
name
|
|
2188
|
+
];
|
|
2189
|
+
if (!scope.subModules.includes(name)) {
|
|
2190
|
+
const valid = scope.subModules.length ? `valid submodules: ${scope.subModules.join(", ")}` : `the ${scope.widget} widget has no submodules`;
|
|
2191
|
+
collector.add(subPath, "UNKNOWN_SUBMODULE", `Submodule '${name}' does not exist; ${valid}`);
|
|
2192
|
+
return;
|
|
2193
|
+
}
|
|
2194
|
+
const widget = Object.keys(WIDGET_SUBMODULE_NAMES).find((key) => WIDGET_SUBMODULE_NAMES[key] === name);
|
|
2195
|
+
const config = widget ? resolveConfig(widget) : void 0;
|
|
2196
|
+
if (!widget || !config) {
|
|
2197
|
+
if (!isPlainObject(value[name])) {
|
|
2198
|
+
collector.add(subPath, "INVALID_TYPE", "A customization must be an object");
|
|
2199
|
+
}
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2202
|
+
validateBlock(collector, value[name], subPath, createScope(widget, config), ROOT_SCOPE, ROOT_PROPERTIES);
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
__name(validateSubmodules, "validateSubmodules");
|
|
2206
|
+
function isEmptyCustomization(value) {
|
|
2207
|
+
if (!isPlainObject(value)) return true;
|
|
2208
|
+
const hasItems = /* @__PURE__ */ __name((list) => Array.isArray(list) && list.length > 0, "hasItems");
|
|
2209
|
+
if (hasItems(value.remove) || hasItems(value.keep)) return false;
|
|
2210
|
+
if (isPlainObject(value.defaults) && Object.keys(value.defaults).length) return false;
|
|
2211
|
+
const nested = [
|
|
2212
|
+
...Array.isArray(value.conditional) ? value.conditional : [],
|
|
2213
|
+
...isPlainObject(value.views) ? Object.values(value.views) : [],
|
|
2214
|
+
...isPlainObject(value.subModules) ? Object.values(value.subModules) : []
|
|
2215
|
+
];
|
|
2216
|
+
return nested.every(isEmptyCustomization);
|
|
2217
|
+
}
|
|
2218
|
+
__name(isEmptyCustomization, "isEmptyCustomization");
|
|
2219
|
+
function validateCustomization(widget, customization, options = {}) {
|
|
2220
|
+
const collector = new Collector();
|
|
2221
|
+
if (!widgetConfigs[widget]) {
|
|
2222
|
+
collector.add([], "UNKNOWN_WIDGET", `Widget '${widget}' has no customization structure`);
|
|
2223
|
+
return {
|
|
2224
|
+
valid: false,
|
|
2225
|
+
errors: collector.errors
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
const config = resolveConfig(widget, options.version);
|
|
2229
|
+
if (!config) {
|
|
2230
|
+
collector.add([], "UNKNOWN_VERSION", `Structure version '${options.version}' does not exist for widget '${widget}'`);
|
|
2231
|
+
return {
|
|
2232
|
+
valid: false,
|
|
2233
|
+
errors: collector.errors
|
|
2234
|
+
};
|
|
2235
|
+
}
|
|
2236
|
+
validateBlock(collector, customization, [], createScope(widget, config), ROOT_SCOPE, ROOT_PROPERTIES);
|
|
2237
|
+
if (!collector.errors.length && !options.allowEmpty && isEmptyCustomization(customization)) {
|
|
2238
|
+
collector.add([], "EMPTY_CUSTOMIZATION", "The customization has no rules: add a remove, keep or defaults entry");
|
|
2239
|
+
}
|
|
2240
|
+
return {
|
|
2241
|
+
valid: collector.errors.length === 0,
|
|
2242
|
+
errors: collector.errors
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
__name(validateCustomization, "validateCustomization");
|
|
2246
|
+
|
|
2247
|
+
// src/remote/remote-customization.loader.ts
|
|
2248
|
+
var CUSTOMIZATIONS_API_PATH = "/api/admin/v5/customizations/widgets";
|
|
2249
|
+
var DEFAULT_CUSTOMIZATION_ID = "default";
|
|
2250
|
+
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
2251
|
+
var WIDGET_PATTERN = /^[a-z][a-z0-9-]{0,99}$/;
|
|
2252
|
+
var CONTEXT_PATTERN = /^[a-z][a-z0-9-]{0,99}$/;
|
|
2253
|
+
var CUSTOMIZATION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,99}$/;
|
|
2254
|
+
var TIMEOUT = Symbol("timeout");
|
|
2255
|
+
var requestCache = /* @__PURE__ */ new Map();
|
|
2256
|
+
function clearRemoteCustomizationCache() {
|
|
2257
|
+
requestCache.clear();
|
|
2258
|
+
}
|
|
2259
|
+
__name(clearRemoteCustomizationCache, "clearRemoteCustomizationCache");
|
|
2260
|
+
var isValidCustomizationId = /* @__PURE__ */ __name((value) => typeof value === "string" && CUSTOMIZATION_ID_PATTERN.test(value), "isValidCustomizationId");
|
|
2261
|
+
function baseUrl({ apiDomain, domain }) {
|
|
2262
|
+
return `${(apiDomain || domain || "").replace(/\/+$/, "")}${CUSTOMIZATIONS_API_PATH}`;
|
|
2263
|
+
}
|
|
2264
|
+
__name(baseUrl, "baseUrl");
|
|
2265
|
+
function buildHeaders({ apiKey, qvToken }) {
|
|
2266
|
+
const headers = {
|
|
2267
|
+
Accept: "application/json"
|
|
2268
|
+
};
|
|
2269
|
+
if (qvToken) headers.Authorization = `Bearer ${qvToken}`;
|
|
2270
|
+
if (apiKey) headers["x-api-key"] = apiKey;
|
|
2271
|
+
return headers;
|
|
2272
|
+
}
|
|
2273
|
+
__name(buildHeaders, "buildHeaders");
|
|
2274
|
+
var isDefinition = /* @__PURE__ */ __name((body) => isPlainObject(body) && isPlainObject(body.customization), "isDefinition");
|
|
2275
|
+
async function request(url, options) {
|
|
2276
|
+
var _a2, _b;
|
|
2277
|
+
const fetchFn = (_a2 = options.fetchFn) != null ? _a2 : globalThis.fetch;
|
|
2278
|
+
if (typeof fetchFn !== "function") {
|
|
2279
|
+
return {
|
|
2280
|
+
kind: "error",
|
|
2281
|
+
error: {
|
|
2282
|
+
code: "NETWORK",
|
|
2283
|
+
message: "fetch is not available"
|
|
2284
|
+
}
|
|
2285
|
+
};
|
|
2286
|
+
}
|
|
2287
|
+
const timeoutMs = (_b = options.timeoutMs) != null ? _b : DEFAULT_TIMEOUT_MS;
|
|
2288
|
+
const controller = typeof AbortController === "function" ? new AbortController() : void 0;
|
|
2289
|
+
let timer;
|
|
2290
|
+
const timeout = new Promise((_, reject) => {
|
|
2291
|
+
timer = setTimeout(() => {
|
|
2292
|
+
controller == null ? void 0 : controller.abort();
|
|
2293
|
+
reject(TIMEOUT);
|
|
2294
|
+
}, timeoutMs);
|
|
2295
|
+
});
|
|
2296
|
+
timeout.catch(() => void 0);
|
|
2297
|
+
try {
|
|
2298
|
+
const response = await Promise.race([
|
|
2299
|
+
fetchFn(url, {
|
|
2300
|
+
method: "GET",
|
|
2301
|
+
headers: buildHeaders(options),
|
|
2302
|
+
signal: controller == null ? void 0 : controller.signal
|
|
2303
|
+
}),
|
|
2304
|
+
timeout
|
|
2305
|
+
]);
|
|
2306
|
+
if (response.status === 404) return {
|
|
2307
|
+
kind: "not-found"
|
|
2308
|
+
};
|
|
2309
|
+
if (!response.ok) {
|
|
2310
|
+
return {
|
|
2311
|
+
kind: "error",
|
|
2312
|
+
error: {
|
|
2313
|
+
code: "HTTP",
|
|
2314
|
+
status: response.status,
|
|
2315
|
+
message: `Request failed with status ${response.status}`
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
}
|
|
2319
|
+
const body = await Promise.race([
|
|
2320
|
+
response.json(),
|
|
2321
|
+
timeout
|
|
2322
|
+
]).catch((error) => {
|
|
2323
|
+
if (error === TIMEOUT) throw error;
|
|
2324
|
+
return void 0;
|
|
2325
|
+
});
|
|
2326
|
+
if (!isDefinition(body)) {
|
|
2327
|
+
return {
|
|
2328
|
+
kind: "error",
|
|
2329
|
+
error: {
|
|
2330
|
+
code: "INVALID_RESPONSE",
|
|
2331
|
+
message: "The response is not a customization definition"
|
|
2332
|
+
}
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
return {
|
|
2336
|
+
kind: "found",
|
|
2337
|
+
definition: body
|
|
2338
|
+
};
|
|
2339
|
+
} catch (error) {
|
|
2340
|
+
return error === TIMEOUT ? {
|
|
2341
|
+
kind: "error",
|
|
2342
|
+
error: {
|
|
2343
|
+
code: "TIMEOUT",
|
|
2344
|
+
message: `No response after ${timeoutMs} ms`
|
|
2345
|
+
}
|
|
2346
|
+
} : {
|
|
2347
|
+
kind: "error",
|
|
2348
|
+
error: {
|
|
2349
|
+
code: "NETWORK",
|
|
2350
|
+
message: "The customization could not be requested"
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
} finally {
|
|
2354
|
+
clearTimeout(timer);
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
__name(request, "request");
|
|
2358
|
+
function cachedRequest(url, options) {
|
|
2359
|
+
const useCache = options.cache !== false;
|
|
2360
|
+
const cached = useCache ? requestCache.get(url) : void 0;
|
|
2361
|
+
if (cached) return cached;
|
|
2362
|
+
const pending = request(url, options).then((result) => {
|
|
2363
|
+
if (result.kind === "error") requestCache.delete(url);
|
|
2364
|
+
return result;
|
|
2365
|
+
});
|
|
2366
|
+
if (useCache) requestCache.set(url, pending);
|
|
2367
|
+
return pending;
|
|
2368
|
+
}
|
|
2369
|
+
__name(cachedRequest, "cachedRequest");
|
|
2370
|
+
var definitionUrl = /* @__PURE__ */ __name((options, id) => `${baseUrl(options)}/${encodeURIComponent(options.widget)}/${encodeURIComponent(id)}`, "definitionUrl");
|
|
2371
|
+
var contextUrl = /* @__PURE__ */ __name((options, context) => `${baseUrl(options)}/${encodeURIComponent(options.widget)}?context=${encodeURIComponent(context)}`, "contextUrl");
|
|
2372
|
+
async function loadDefault(options, foundStatus, explicit) {
|
|
2373
|
+
const result = await cachedRequest(definitionUrl(options, DEFAULT_CUSTOMIZATION_ID), options);
|
|
2374
|
+
if (result.kind === "found") return {
|
|
2375
|
+
status: foundStatus,
|
|
2376
|
+
definition: result.definition
|
|
2377
|
+
};
|
|
2378
|
+
if (result.kind === "not-found") {
|
|
2379
|
+
logWarning(`the ${DEFAULT_CUSTOMIZATION_ID} ${options.widget} customization was not found; no remote layer`);
|
|
2380
|
+
return {
|
|
2381
|
+
status: "none"
|
|
2382
|
+
};
|
|
2383
|
+
}
|
|
2384
|
+
if (!explicit) {
|
|
2385
|
+
logWarning(`the ${DEFAULT_CUSTOMIZATION_ID} ${options.widget} customization could not be read (${result.error.code}); no remote layer`);
|
|
2386
|
+
return {
|
|
2387
|
+
status: "none",
|
|
2388
|
+
error: result.error
|
|
2389
|
+
};
|
|
2390
|
+
}
|
|
2391
|
+
return {
|
|
2392
|
+
status: "error",
|
|
2393
|
+
error: result.error
|
|
2394
|
+
};
|
|
2395
|
+
}
|
|
2396
|
+
__name(loadDefault, "loadDefault");
|
|
2397
|
+
async function loadRemoteCustomization(options) {
|
|
2398
|
+
if (typeof (options == null ? void 0 : options.widget) !== "string" || !WIDGET_PATTERN.test(options.widget)) {
|
|
2399
|
+
return {
|
|
2400
|
+
status: "error",
|
|
2401
|
+
error: {
|
|
2402
|
+
code: "INVALID_INPUT",
|
|
2403
|
+
message: "Invalid widget"
|
|
2404
|
+
}
|
|
2405
|
+
};
|
|
2406
|
+
}
|
|
2407
|
+
if (!options.domain && !options.apiDomain) {
|
|
2408
|
+
return {
|
|
2409
|
+
status: "error",
|
|
2410
|
+
error: {
|
|
2411
|
+
code: "INVALID_INPUT",
|
|
2412
|
+
message: "A domain is required"
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
}
|
|
2416
|
+
const { customizationId, context } = options;
|
|
2417
|
+
if (customizationId !== void 0 && customizationId !== null && customizationId !== "") {
|
|
2418
|
+
if (!isValidCustomizationId(customizationId)) {
|
|
2419
|
+
logWarning(`invalid customizationId; using ${DEFAULT_CUSTOMIZATION_ID}`);
|
|
2420
|
+
return loadDefault(options, "fallback", true);
|
|
2421
|
+
}
|
|
2422
|
+
const result = await cachedRequest(definitionUrl(options, customizationId), options);
|
|
2423
|
+
if (result.kind === "found") return {
|
|
2424
|
+
status: "found",
|
|
2425
|
+
definition: result.definition
|
|
2426
|
+
};
|
|
2427
|
+
if (result.kind === "error") return {
|
|
2428
|
+
status: "error",
|
|
2429
|
+
error: result.error
|
|
2430
|
+
};
|
|
2431
|
+
logWarning(`customization '${customizationId}' not found; using ${DEFAULT_CUSTOMIZATION_ID}`);
|
|
2432
|
+
return customizationId === DEFAULT_CUSTOMIZATION_ID ? {
|
|
2433
|
+
status: "none"
|
|
2434
|
+
} : loadDefault(options, "fallback", true);
|
|
2435
|
+
}
|
|
2436
|
+
if (context) {
|
|
2437
|
+
if (!CONTEXT_PATTERN.test(context)) {
|
|
2438
|
+
return {
|
|
2439
|
+
status: "error",
|
|
2440
|
+
error: {
|
|
2441
|
+
code: "INVALID_INPUT",
|
|
2442
|
+
message: "Invalid context"
|
|
2443
|
+
}
|
|
2444
|
+
};
|
|
2445
|
+
}
|
|
2446
|
+
const result = await cachedRequest(contextUrl(options, context), options);
|
|
2447
|
+
if (result.kind === "found") return {
|
|
2448
|
+
status: "found",
|
|
2449
|
+
definition: result.definition
|
|
2450
|
+
};
|
|
2451
|
+
if (result.kind === "error") return {
|
|
2452
|
+
status: "error",
|
|
2453
|
+
error: result.error
|
|
2454
|
+
};
|
|
2455
|
+
return loadDefault(options, "fallback", true);
|
|
2456
|
+
}
|
|
2457
|
+
return loadDefault(options, "found", false);
|
|
2458
|
+
}
|
|
2459
|
+
__name(loadRemoteCustomization, "loadRemoteCustomization");
|
|
2460
|
+
function remoteCustomizationLayers(result) {
|
|
2461
|
+
return (result == null ? void 0 : result.definition) ? [
|
|
2462
|
+
result.definition.customization
|
|
2463
|
+
] : [];
|
|
2464
|
+
}
|
|
2465
|
+
__name(remoteCustomizationLayers, "remoteCustomizationLayers");
|
|
2466
|
+
|
|
1649
2467
|
// src/doc/dashboard.structure.doc.ts
|
|
1650
2468
|
var dashboard_structure_doc_exports = {};
|
|
1651
2469
|
__export(dashboard_structure_doc_exports, {
|
|
@@ -2262,6 +3080,6 @@ _ts_decorate([
|
|
|
2262
3080
|
_ts_metadata("design:type", typeof SubModulesDto === "undefined" ? Object : SubModulesDto)
|
|
2263
3081
|
], BaseDashboardV1StructureDto.prototype, "subModules", void 0);
|
|
2264
3082
|
|
|
2265
|
-
export { DOWNLOAD_MODAL_V1_DEFAULTS, DOWNLOAD_MODAL_V1_KEYS, DOWNLOAD_MODAL_VALIDATOR_MAP, DX_VALIDATOR_MAP, dashboard_structure_doc_exports as DashboardDoc, WIDGET_STRUCTURE_SCOPE_FORMAT, WIDGET_STRUCTURE_SCOPE_KIND, WIDGET_SUBMODULE_NAMES, Widget, WidgetStructureInstance, WidgetVersion, buildStructure, calculateRootDefaults, calculateViewMap, checkConditions, evaluateCondition, extractCustomization, getWidgetConfig, getWidgetStructure, hostKeepInheritance, isWidgetStructureScope, scopeToCustomization, structureFrom, structureFromSubmodule, validateBoolean, validateDefaults };
|
|
3083
|
+
export { CUSTOMIZATIONS_API_PATH, DEFAULT_CUSTOMIZATION_ID, DOWNLOAD_MODAL_V1_DEFAULTS, DOWNLOAD_MODAL_V1_KEYS, DOWNLOAD_MODAL_VALIDATOR_MAP, DX_VALIDATOR_MAP, dashboard_structure_doc_exports as DashboardDoc, WIDGET_STRUCTURE_SCOPE_FORMAT, WIDGET_STRUCTURE_SCOPE_KIND, WIDGET_SUBMODULE_NAMES, Widget, WidgetStructureInstance, WidgetVersion, buildStructure, calculateRootDefaults, calculateViewMap, checkConditions, clearRemoteCustomizationCache, evaluateCondition, extractCustomization, formatCustomizationPath, getWidgetConfig, getWidgetStructure, hostKeepInheritance, isEmptyCustomization, isValidCustomizationId, isWidgetStructureScope, loadRemoteCustomization, remoteCustomizationLayers, scopeToCustomization, structureFrom, structureFromSubmodule, validateBoolean, validateCustomization, validateDefaults };
|
|
2266
3084
|
//# sourceMappingURL=index.mjs.map
|
|
2267
3085
|
//# sourceMappingURL=index.mjs.map
|