@timeax/digital-service-engine 0.2.3 → 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.
@@ -53,6 +53,7 @@ function normalise(input, opts = {}) {
53
53
  const excludes_for_buttons = toStringArrayMap(
54
54
  obj.excludes_for_buttons
55
55
  );
56
+ const orderKinds = toStringMap(obj.orderKinds);
56
57
  const notices = toNoticeArray(obj.notices);
57
58
  let filters = rawFilters.map((t) => coerceTag(t, constraints));
58
59
  const fields = rawFields.map((f) => coerceField(f, defRole));
@@ -64,6 +65,7 @@ function normalise(input, opts = {}) {
64
65
  filters,
65
66
  fields,
66
67
  order_for_tags: obj.order_for_tags,
68
+ ...isNonEmpty(orderKinds) && { orderKinds },
67
69
  ...isNonEmpty(includes_for_buttons) && { includes_for_buttons },
68
70
  ...isNonEmpty(excludes_for_buttons) && { excludes_for_buttons },
69
71
  ...fallbacks && (isNonEmpty(fallbacks.nodes) || isNonEmpty(fallbacks.global)) && {
@@ -274,6 +276,15 @@ function normaliseBindId(bind) {
274
276
  }
275
277
  return void 0;
276
278
  }
279
+ function toStringMap(src) {
280
+ if (!src || typeof src !== "object") return void 0;
281
+ const out = {};
282
+ for (const [k, v] of Object.entries(src)) {
283
+ if (!k || typeof v !== "string") continue;
284
+ out[k] = v;
285
+ }
286
+ return Object.keys(out).length ? out : void 0;
287
+ }
277
288
  function toStringArrayMap(src) {
278
289
  if (!src || typeof src !== "object") return void 0;
279
290
  const out = {};
@@ -1092,6 +1103,129 @@ function validateOptionMaps(v) {
1092
1103
  }
1093
1104
  }
1094
1105
 
1106
+ // src/utils/order-kind.ts
1107
+ function normalizeSelectedTriggerKey(key, nodeMap) {
1108
+ if (!key) return void 0;
1109
+ const compositeIdx = key.indexOf("::");
1110
+ if (compositeIdx !== -1) {
1111
+ const fieldId = key.slice(0, compositeIdx).trim();
1112
+ const optionId = key.slice(compositeIdx + 2).trim();
1113
+ if (optionId) {
1114
+ const optionRef = nodeMap.get(optionId);
1115
+ if ((optionRef == null ? void 0 : optionRef.kind) === "option") {
1116
+ return { nodeId: optionRef.id, nodeKind: "option" };
1117
+ }
1118
+ }
1119
+ if (fieldId) {
1120
+ const fieldRef = nodeMap.get(fieldId);
1121
+ if ((fieldRef == null ? void 0 : fieldRef.kind) === "field") {
1122
+ return { nodeId: fieldRef.id, nodeKind: "field" };
1123
+ }
1124
+ }
1125
+ return void 0;
1126
+ }
1127
+ const ref = nodeMap.get(key);
1128
+ if (!ref) return void 0;
1129
+ if (ref.kind !== "field" && ref.kind !== "option") return void 0;
1130
+ return { nodeId: ref.id, nodeKind: ref.kind };
1131
+ }
1132
+ function normalizeSelectedOrderKindTriggers(selectedTriggerKeys, nodeMap) {
1133
+ if (!selectedTriggerKeys) return [];
1134
+ const out = [];
1135
+ const seen = /* @__PURE__ */ new Set();
1136
+ for (const rawKey of selectedTriggerKeys) {
1137
+ const key = String(rawKey != null ? rawKey : "");
1138
+ const normalized = normalizeSelectedTriggerKey(key, nodeMap);
1139
+ if (!normalized) continue;
1140
+ const dedupeKey = `${normalized.nodeKind}:${normalized.nodeId}`;
1141
+ if (seen.has(dedupeKey)) continue;
1142
+ seen.add(dedupeKey);
1143
+ out.push(normalized);
1144
+ }
1145
+ return out;
1146
+ }
1147
+ function resolveOrderKind(params) {
1148
+ var _a, _b;
1149
+ const nodeMap = (_a = params.nodeMap) != null ? _a : buildNodeMap(params.props);
1150
+ const orderKinds = (_b = params.props.orderKinds) != null ? _b : {};
1151
+ const normalizedSelected = normalizeSelectedOrderKindTriggers(
1152
+ params.selectedTriggerKeys,
1153
+ nodeMap
1154
+ );
1155
+ const selectedKindToSource = /* @__PURE__ */ new Map();
1156
+ const selectedNodeIdsForKinds = /* @__PURE__ */ new Map();
1157
+ for (const trigger of normalizedSelected) {
1158
+ const mappedKind = orderKinds[trigger.nodeId];
1159
+ if (typeof mappedKind !== "string") continue;
1160
+ if (!selectedKindToSource.has(mappedKind)) {
1161
+ selectedKindToSource.set(mappedKind, {
1162
+ nodeId: trigger.nodeId,
1163
+ nodeKind: trigger.nodeKind
1164
+ });
1165
+ }
1166
+ if (!selectedNodeIdsForKinds.has(mappedKind)) {
1167
+ selectedNodeIdsForKinds.set(mappedKind, /* @__PURE__ */ new Set());
1168
+ }
1169
+ selectedNodeIdsForKinds.get(mappedKind).add(trigger.nodeId);
1170
+ }
1171
+ const selectedKinds = Array.from(selectedKindToSource.keys());
1172
+ if (selectedKinds.length > 1) {
1173
+ const conflictingNodeIds = Array.from(selectedNodeIdsForKinds.values()).flatMap((ids) => Array.from(ids)).filter((id, idx, arr) => arr.indexOf(id) === idx);
1174
+ return {
1175
+ kind: null,
1176
+ source: null,
1177
+ error: "multiple_order_kinds_selected",
1178
+ conflictingKinds: selectedKinds,
1179
+ conflictingNodeIds
1180
+ };
1181
+ }
1182
+ if (selectedKinds.length === 1) {
1183
+ const selectedKind = selectedKinds[0];
1184
+ return {
1185
+ kind: selectedKind,
1186
+ source: selectedKindToSource.get(selectedKind)
1187
+ };
1188
+ }
1189
+ const activeTagId = params.activeTagId;
1190
+ if (activeTagId) {
1191
+ const tagKind = orderKinds[activeTagId];
1192
+ if (typeof tagKind === "string") {
1193
+ return {
1194
+ kind: tagKind,
1195
+ source: { nodeId: activeTagId, nodeKind: "tag" }
1196
+ };
1197
+ }
1198
+ }
1199
+ return { kind: null, source: null };
1200
+ }
1201
+
1202
+ // src/core/validate/steps/order-kinds.ts
1203
+ function validateOrderKinds(v) {
1204
+ var _a, _b, _c;
1205
+ const selectedTriggerKeys = Array.from((_a = v.selectedKeys) != null ? _a : []);
1206
+ if (!selectedTriggerKeys.length) return;
1207
+ const resolved = resolveOrderKind({
1208
+ props: v.props,
1209
+ selectedTriggerKeys,
1210
+ nodeMap: v.nodeMap
1211
+ });
1212
+ if (resolved.error !== "multiple_order_kinds_selected") return;
1213
+ const conflicts = (_b = resolved.conflictingKinds) != null ? _b : [];
1214
+ const affected = (_c = resolved.conflictingNodeIds) != null ? _c : [];
1215
+ v.errors.push({
1216
+ code: "multiple_order_kinds_selected",
1217
+ severity: "error",
1218
+ message: "Multiple selected triggers resolve to different order kinds. Select triggers that resolve to a single order kind.",
1219
+ details: withAffected(
1220
+ {
1221
+ conflictingKinds: conflicts,
1222
+ conflictingNodeIds: affected
1223
+ },
1224
+ affected
1225
+ )
1226
+ });
1227
+ }
1228
+
1095
1229
  // src/core/validate/steps/service-vs-input.ts
1096
1230
  function validateServiceVsUserInput(v) {
1097
1231
  for (const f of v.fields) {
@@ -2420,6 +2554,7 @@ var BuilderImpl = class {
2420
2554
  const out = {
2421
2555
  filters: this.props.filters.slice(),
2422
2556
  fields,
2557
+ ...this.props.orderKinds ? { orderKinds: this.props.orderKinds } : {},
2423
2558
  ...includes_for_buttons && { includes_for_buttons },
2424
2559
  ...excludes_for_buttons && { excludes_for_buttons },
2425
2560
  schema_version: (_e = this.props.schema_version) != null ? _e : "1.0",
@@ -2752,6 +2887,7 @@ function validate(props, ctx = {}) {
2752
2887
  validateStructure(v);
2753
2888
  validateIdentity(v);
2754
2889
  validateOptionMaps(v);
2890
+ validateOrderKinds(v);
2755
2891
  v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
2756
2892
  const visSim = readVisibilitySimOpts(options);
2757
2893
  validateVisibility(v, visSim);
@@ -4152,6 +4288,13 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
4152
4288
  fieldById
4153
4289
  );
4154
4290
  const { min, max } = resolveMinMax(servicesList, services);
4291
+ const maybeNodeMap = typeof builder.getNodeMap === "function" ? builder.getNodeMap() : void 0;
4292
+ const resolvedOrderKind = resolveOrderKind({
4293
+ props,
4294
+ activeTagId: tagId,
4295
+ selectedTriggerKeys: selectedButtonKeys,
4296
+ nodeMap: maybeNodeMap
4297
+ });
4155
4298
  const prunedFallbacks = pruneFallbacksConservative(
4156
4299
  props.fallbacks,
4157
4300
  { tagId, constraints: tagConstraints, serviceMap, servicesList },
@@ -4207,6 +4350,8 @@ function buildOrderSnapshot(props, builder, selection, services, settings = {})
4207
4350
  },
4208
4351
  min,
4209
4352
  max: max != null ? max : min,
4353
+ orderKind: resolvedOrderKind.kind,
4354
+ orderKindSource: resolvedOrderKind.source,
4210
4355
  quantity,
4211
4356
  quantitySource,
4212
4357
  services: servicesList,