@timeax/digital-service-engine 0.2.4 → 0.2.5
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/dist/core/index.cjs +145 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +8 -1
- package/dist/core/index.d.ts +8 -1
- package/dist/core/index.js +145 -0
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +236 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +11 -1
- package/dist/react/index.d.ts +11 -1
- package/dist/react/index.js +236 -0
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.d.cts +9 -2
- package/dist/schema/index.d.ts +9 -2
- package/dist/workspace/index.cjs +227 -0
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +5 -1
- package/dist/workspace/index.d.ts +5 -1
- package/dist/workspace/index.js +227 -0
- package/dist/workspace/index.js.map +1 -1
- package/package.json +6 -5
- package/schema/editor-snapshot.schema.json +6 -0
- package/schema/order-snapshot.schema.json +667 -0
- package/schema/service-props.schema.json +6 -0
package/dist/core/index.d.cts
CHANGED
|
@@ -66,6 +66,10 @@ type SnapshotContext = {
|
|
|
66
66
|
requireConstraintFit: boolean;
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
|
+
type OrderKindSource = {
|
|
70
|
+
nodeId: string;
|
|
71
|
+
nodeKind: "tag" | "field" | "option";
|
|
72
|
+
};
|
|
69
73
|
type OrderSnapshot = {
|
|
70
74
|
version: "1";
|
|
71
75
|
mode: "prod" | "dev";
|
|
@@ -92,6 +96,8 @@ type OrderSnapshot = {
|
|
|
92
96
|
};
|
|
93
97
|
min: number;
|
|
94
98
|
max: number;
|
|
99
|
+
orderKind?: string | null;
|
|
100
|
+
orderKindSource?: OrderKindSource | null;
|
|
95
101
|
services: Array<string | number>;
|
|
96
102
|
serviceMap: Record<string, Array<string | number>>;
|
|
97
103
|
fallbacks?: ServiceFallbacks;
|
|
@@ -169,7 +175,7 @@ type NodeRef = {
|
|
|
169
175
|
};
|
|
170
176
|
type NodeMap = Map<string, NodeRef>;
|
|
171
177
|
|
|
172
|
-
type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern";
|
|
178
|
+
type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern" | "multiple_order_kinds_selected";
|
|
173
179
|
type ValidationError = {
|
|
174
180
|
code: ValidationCode;
|
|
175
181
|
message: string;
|
|
@@ -450,6 +456,7 @@ type Tag = {
|
|
|
450
456
|
};
|
|
451
457
|
type ServiceProps = {
|
|
452
458
|
order_for_tags?: Record<string, string[]>;
|
|
459
|
+
orderKinds?: Record<string, string>;
|
|
453
460
|
filters: Tag[];
|
|
454
461
|
fields: Field[];
|
|
455
462
|
includes_for_buttons?: Record<string, string[]>;
|
package/dist/core/index.d.ts
CHANGED
|
@@ -66,6 +66,10 @@ type SnapshotContext = {
|
|
|
66
66
|
requireConstraintFit: boolean;
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
|
+
type OrderKindSource = {
|
|
70
|
+
nodeId: string;
|
|
71
|
+
nodeKind: "tag" | "field" | "option";
|
|
72
|
+
};
|
|
69
73
|
type OrderSnapshot = {
|
|
70
74
|
version: "1";
|
|
71
75
|
mode: "prod" | "dev";
|
|
@@ -92,6 +96,8 @@ type OrderSnapshot = {
|
|
|
92
96
|
};
|
|
93
97
|
min: number;
|
|
94
98
|
max: number;
|
|
99
|
+
orderKind?: string | null;
|
|
100
|
+
orderKindSource?: OrderKindSource | null;
|
|
95
101
|
services: Array<string | number>;
|
|
96
102
|
serviceMap: Record<string, Array<string | number>>;
|
|
97
103
|
fallbacks?: ServiceFallbacks;
|
|
@@ -169,7 +175,7 @@ type NodeRef = {
|
|
|
169
175
|
};
|
|
170
176
|
type NodeMap = Map<string, NodeRef>;
|
|
171
177
|
|
|
172
|
-
type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern";
|
|
178
|
+
type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern" | "multiple_order_kinds_selected";
|
|
173
179
|
type ValidationError = {
|
|
174
180
|
code: ValidationCode;
|
|
175
181
|
message: string;
|
|
@@ -450,6 +456,7 @@ type Tag = {
|
|
|
450
456
|
};
|
|
451
457
|
type ServiceProps = {
|
|
452
458
|
order_for_tags?: Record<string, string[]>;
|
|
459
|
+
orderKinds?: Record<string, string>;
|
|
453
460
|
filters: Tag[];
|
|
454
461
|
fields: Field[];
|
|
455
462
|
includes_for_buttons?: Record<string, string[]>;
|
package/dist/core/index.js
CHANGED
|
@@ -13,6 +13,7 @@ function normalise(input, opts = {}) {
|
|
|
13
13
|
const excludes_for_buttons = toStringArrayMap(
|
|
14
14
|
obj.excludes_for_buttons
|
|
15
15
|
);
|
|
16
|
+
const orderKinds = toStringMap(obj.orderKinds);
|
|
16
17
|
const notices = toNoticeArray(obj.notices);
|
|
17
18
|
let filters = rawFilters.map((t) => coerceTag(t, constraints));
|
|
18
19
|
const fields = rawFields.map((f) => coerceField(f, defRole));
|
|
@@ -24,6 +25,7 @@ function normalise(input, opts = {}) {
|
|
|
24
25
|
filters,
|
|
25
26
|
fields,
|
|
26
27
|
order_for_tags: obj.order_for_tags,
|
|
28
|
+
...isNonEmpty(orderKinds) && { orderKinds },
|
|
27
29
|
...isNonEmpty(includes_for_buttons) && { includes_for_buttons },
|
|
28
30
|
...isNonEmpty(excludes_for_buttons) && { excludes_for_buttons },
|
|
29
31
|
...fallbacks && (isNonEmpty(fallbacks.nodes) || isNonEmpty(fallbacks.global)) && {
|
|
@@ -234,6 +236,15 @@ function normaliseBindId(bind) {
|
|
|
234
236
|
}
|
|
235
237
|
return void 0;
|
|
236
238
|
}
|
|
239
|
+
function toStringMap(src) {
|
|
240
|
+
if (!src || typeof src !== "object") return void 0;
|
|
241
|
+
const out = {};
|
|
242
|
+
for (const [k, v] of Object.entries(src)) {
|
|
243
|
+
if (!k || typeof v !== "string") continue;
|
|
244
|
+
out[k] = v;
|
|
245
|
+
}
|
|
246
|
+
return Object.keys(out).length ? out : void 0;
|
|
247
|
+
}
|
|
237
248
|
function toStringArrayMap(src) {
|
|
238
249
|
if (!src || typeof src !== "object") return void 0;
|
|
239
250
|
const out = {};
|
|
@@ -1052,6 +1063,129 @@ function validateOptionMaps(v) {
|
|
|
1052
1063
|
}
|
|
1053
1064
|
}
|
|
1054
1065
|
|
|
1066
|
+
// src/utils/order-kind.ts
|
|
1067
|
+
function normalizeSelectedTriggerKey(key, nodeMap) {
|
|
1068
|
+
if (!key) return void 0;
|
|
1069
|
+
const compositeIdx = key.indexOf("::");
|
|
1070
|
+
if (compositeIdx !== -1) {
|
|
1071
|
+
const fieldId = key.slice(0, compositeIdx).trim();
|
|
1072
|
+
const optionId = key.slice(compositeIdx + 2).trim();
|
|
1073
|
+
if (optionId) {
|
|
1074
|
+
const optionRef = nodeMap.get(optionId);
|
|
1075
|
+
if ((optionRef == null ? void 0 : optionRef.kind) === "option") {
|
|
1076
|
+
return { nodeId: optionRef.id, nodeKind: "option" };
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
if (fieldId) {
|
|
1080
|
+
const fieldRef = nodeMap.get(fieldId);
|
|
1081
|
+
if ((fieldRef == null ? void 0 : fieldRef.kind) === "field") {
|
|
1082
|
+
return { nodeId: fieldRef.id, nodeKind: "field" };
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
return void 0;
|
|
1086
|
+
}
|
|
1087
|
+
const ref = nodeMap.get(key);
|
|
1088
|
+
if (!ref) return void 0;
|
|
1089
|
+
if (ref.kind !== "field" && ref.kind !== "option") return void 0;
|
|
1090
|
+
return { nodeId: ref.id, nodeKind: ref.kind };
|
|
1091
|
+
}
|
|
1092
|
+
function normalizeSelectedOrderKindTriggers(selectedTriggerKeys, nodeMap) {
|
|
1093
|
+
if (!selectedTriggerKeys) return [];
|
|
1094
|
+
const out = [];
|
|
1095
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1096
|
+
for (const rawKey of selectedTriggerKeys) {
|
|
1097
|
+
const key = String(rawKey != null ? rawKey : "");
|
|
1098
|
+
const normalized = normalizeSelectedTriggerKey(key, nodeMap);
|
|
1099
|
+
if (!normalized) continue;
|
|
1100
|
+
const dedupeKey = `${normalized.nodeKind}:${normalized.nodeId}`;
|
|
1101
|
+
if (seen.has(dedupeKey)) continue;
|
|
1102
|
+
seen.add(dedupeKey);
|
|
1103
|
+
out.push(normalized);
|
|
1104
|
+
}
|
|
1105
|
+
return out;
|
|
1106
|
+
}
|
|
1107
|
+
function resolveOrderKind(params) {
|
|
1108
|
+
var _a, _b;
|
|
1109
|
+
const nodeMap = (_a = params.nodeMap) != null ? _a : buildNodeMap(params.props);
|
|
1110
|
+
const orderKinds = (_b = params.props.orderKinds) != null ? _b : {};
|
|
1111
|
+
const normalizedSelected = normalizeSelectedOrderKindTriggers(
|
|
1112
|
+
params.selectedTriggerKeys,
|
|
1113
|
+
nodeMap
|
|
1114
|
+
);
|
|
1115
|
+
const selectedKindToSource = /* @__PURE__ */ new Map();
|
|
1116
|
+
const selectedNodeIdsForKinds = /* @__PURE__ */ new Map();
|
|
1117
|
+
for (const trigger of normalizedSelected) {
|
|
1118
|
+
const mappedKind = orderKinds[trigger.nodeId];
|
|
1119
|
+
if (typeof mappedKind !== "string") continue;
|
|
1120
|
+
if (!selectedKindToSource.has(mappedKind)) {
|
|
1121
|
+
selectedKindToSource.set(mappedKind, {
|
|
1122
|
+
nodeId: trigger.nodeId,
|
|
1123
|
+
nodeKind: trigger.nodeKind
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
if (!selectedNodeIdsForKinds.has(mappedKind)) {
|
|
1127
|
+
selectedNodeIdsForKinds.set(mappedKind, /* @__PURE__ */ new Set());
|
|
1128
|
+
}
|
|
1129
|
+
selectedNodeIdsForKinds.get(mappedKind).add(trigger.nodeId);
|
|
1130
|
+
}
|
|
1131
|
+
const selectedKinds = Array.from(selectedKindToSource.keys());
|
|
1132
|
+
if (selectedKinds.length > 1) {
|
|
1133
|
+
const conflictingNodeIds = Array.from(selectedNodeIdsForKinds.values()).flatMap((ids) => Array.from(ids)).filter((id, idx, arr) => arr.indexOf(id) === idx);
|
|
1134
|
+
return {
|
|
1135
|
+
kind: null,
|
|
1136
|
+
source: null,
|
|
1137
|
+
error: "multiple_order_kinds_selected",
|
|
1138
|
+
conflictingKinds: selectedKinds,
|
|
1139
|
+
conflictingNodeIds
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
if (selectedKinds.length === 1) {
|
|
1143
|
+
const selectedKind = selectedKinds[0];
|
|
1144
|
+
return {
|
|
1145
|
+
kind: selectedKind,
|
|
1146
|
+
source: selectedKindToSource.get(selectedKind)
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
const activeTagId = params.activeTagId;
|
|
1150
|
+
if (activeTagId) {
|
|
1151
|
+
const tagKind = orderKinds[activeTagId];
|
|
1152
|
+
if (typeof tagKind === "string") {
|
|
1153
|
+
return {
|
|
1154
|
+
kind: tagKind,
|
|
1155
|
+
source: { nodeId: activeTagId, nodeKind: "tag" }
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
return { kind: null, source: null };
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// src/core/validate/steps/order-kinds.ts
|
|
1163
|
+
function validateOrderKinds(v) {
|
|
1164
|
+
var _a, _b, _c;
|
|
1165
|
+
const selectedTriggerKeys = Array.from((_a = v.selectedKeys) != null ? _a : []);
|
|
1166
|
+
if (!selectedTriggerKeys.length) return;
|
|
1167
|
+
const resolved = resolveOrderKind({
|
|
1168
|
+
props: v.props,
|
|
1169
|
+
selectedTriggerKeys,
|
|
1170
|
+
nodeMap: v.nodeMap
|
|
1171
|
+
});
|
|
1172
|
+
if (resolved.error !== "multiple_order_kinds_selected") return;
|
|
1173
|
+
const conflicts = (_b = resolved.conflictingKinds) != null ? _b : [];
|
|
1174
|
+
const affected = (_c = resolved.conflictingNodeIds) != null ? _c : [];
|
|
1175
|
+
v.errors.push({
|
|
1176
|
+
code: "multiple_order_kinds_selected",
|
|
1177
|
+
severity: "error",
|
|
1178
|
+
message: "Multiple selected triggers resolve to different order kinds. Select triggers that resolve to a single order kind.",
|
|
1179
|
+
details: withAffected(
|
|
1180
|
+
{
|
|
1181
|
+
conflictingKinds: conflicts,
|
|
1182
|
+
conflictingNodeIds: affected
|
|
1183
|
+
},
|
|
1184
|
+
affected
|
|
1185
|
+
)
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1055
1189
|
// src/core/validate/steps/service-vs-input.ts
|
|
1056
1190
|
function validateServiceVsUserInput(v) {
|
|
1057
1191
|
for (const f of v.fields) {
|
|
@@ -2380,6 +2514,7 @@ var BuilderImpl = class {
|
|
|
2380
2514
|
const out = {
|
|
2381
2515
|
filters: this.props.filters.slice(),
|
|
2382
2516
|
fields,
|
|
2517
|
+
...this.props.orderKinds ? { orderKinds: this.props.orderKinds } : {},
|
|
2383
2518
|
...includes_for_buttons && { includes_for_buttons },
|
|
2384
2519
|
...excludes_for_buttons && { excludes_for_buttons },
|
|
2385
2520
|
schema_version: (_e = this.props.schema_version) != null ? _e : "1.0",
|
|
@@ -2712,6 +2847,7 @@ function validate(props, ctx = {}) {
|
|
|
2712
2847
|
validateStructure(v);
|
|
2713
2848
|
validateIdentity(v);
|
|
2714
2849
|
validateOptionMaps(v);
|
|
2850
|
+
validateOrderKinds(v);
|
|
2715
2851
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
2716
2852
|
const visSim = readVisibilitySimOpts(options);
|
|
2717
2853
|
validateVisibility(v, visSim);
|
|
@@ -4112,6 +4248,13 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
4112
4248
|
fieldById
|
|
4113
4249
|
);
|
|
4114
4250
|
const { min, max } = resolveMinMax(servicesList, services);
|
|
4251
|
+
const maybeNodeMap = typeof builder.getNodeMap === "function" ? builder.getNodeMap() : void 0;
|
|
4252
|
+
const resolvedOrderKind = resolveOrderKind({
|
|
4253
|
+
props,
|
|
4254
|
+
activeTagId: tagId,
|
|
4255
|
+
selectedTriggerKeys: selectedButtonKeys,
|
|
4256
|
+
nodeMap: maybeNodeMap
|
|
4257
|
+
});
|
|
4115
4258
|
const prunedFallbacks = pruneFallbacksConservative(
|
|
4116
4259
|
props.fallbacks,
|
|
4117
4260
|
{ tagId, constraints: tagConstraints, serviceMap, servicesList },
|
|
@@ -4167,6 +4310,8 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
|
|
|
4167
4310
|
},
|
|
4168
4311
|
min,
|
|
4169
4312
|
max: max != null ? max : min,
|
|
4313
|
+
orderKind: resolvedOrderKind.kind,
|
|
4314
|
+
orderKindSource: resolvedOrderKind.source,
|
|
4170
4315
|
quantity,
|
|
4171
4316
|
quantitySource,
|
|
4172
4317
|
services: servicesList,
|