@timeax/digital-service-engine 0.2.4 → 0.2.6

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.
@@ -3527,6 +3527,7 @@ function normalise(input, opts = {}) {
3527
3527
  const excludes_for_buttons = toStringArrayMap(
3528
3528
  obj.excludes_for_buttons
3529
3529
  );
3530
+ const orderKinds = toStringMap(obj.orderKinds);
3530
3531
  const notices = toNoticeArray(obj.notices);
3531
3532
  let filters = rawFilters.map((t) => coerceTag(t, constraints));
3532
3533
  const fields = rawFields.map((f) => coerceField(f, defRole));
@@ -3538,6 +3539,7 @@ function normalise(input, opts = {}) {
3538
3539
  filters,
3539
3540
  fields,
3540
3541
  order_for_tags: obj.order_for_tags,
3542
+ ...isNonEmpty(orderKinds) && { orderKinds },
3541
3543
  ...isNonEmpty(includes_for_buttons) && { includes_for_buttons },
3542
3544
  ...isNonEmpty(excludes_for_buttons) && { excludes_for_buttons },
3543
3545
  ...fallbacks && (isNonEmpty(fallbacks.nodes) || isNonEmpty(fallbacks.global)) && {
@@ -3748,6 +3750,15 @@ function normaliseBindId(bind) {
3748
3750
  }
3749
3751
  return void 0;
3750
3752
  }
3753
+ function toStringMap(src) {
3754
+ if (!src || typeof src !== "object") return void 0;
3755
+ const out = {};
3756
+ for (const [k, v] of Object.entries(src)) {
3757
+ if (!k || typeof v !== "string") continue;
3758
+ out[k] = v;
3759
+ }
3760
+ return Object.keys(out).length ? out : void 0;
3761
+ }
3751
3762
  function toStringArrayMap(src) {
3752
3763
  if (!src || typeof src !== "object") return void 0;
3753
3764
  const out = {};
@@ -4566,6 +4577,129 @@ function validateOptionMaps(v) {
4566
4577
  }
4567
4578
  }
4568
4579
 
4580
+ // src/utils/order-kind.ts
4581
+ function normalizeSelectedTriggerKey(key, nodeMap) {
4582
+ if (!key) return void 0;
4583
+ const compositeIdx = key.indexOf("::");
4584
+ if (compositeIdx !== -1) {
4585
+ const fieldId = key.slice(0, compositeIdx).trim();
4586
+ const optionId = key.slice(compositeIdx + 2).trim();
4587
+ if (optionId) {
4588
+ const optionRef = nodeMap.get(optionId);
4589
+ if ((optionRef == null ? void 0 : optionRef.kind) === "option") {
4590
+ return { nodeId: optionRef.id, nodeKind: "option" };
4591
+ }
4592
+ }
4593
+ if (fieldId) {
4594
+ const fieldRef = nodeMap.get(fieldId);
4595
+ if ((fieldRef == null ? void 0 : fieldRef.kind) === "field") {
4596
+ return { nodeId: fieldRef.id, nodeKind: "field" };
4597
+ }
4598
+ }
4599
+ return void 0;
4600
+ }
4601
+ const ref = nodeMap.get(key);
4602
+ if (!ref) return void 0;
4603
+ if (ref.kind !== "field" && ref.kind !== "option") return void 0;
4604
+ return { nodeId: ref.id, nodeKind: ref.kind };
4605
+ }
4606
+ function normalizeSelectedOrderKindTriggers(selectedTriggerKeys, nodeMap) {
4607
+ if (!selectedTriggerKeys) return [];
4608
+ const out = [];
4609
+ const seen = /* @__PURE__ */ new Set();
4610
+ for (const rawKey of selectedTriggerKeys) {
4611
+ const key = String(rawKey != null ? rawKey : "");
4612
+ const normalized = normalizeSelectedTriggerKey(key, nodeMap);
4613
+ if (!normalized) continue;
4614
+ const dedupeKey = `${normalized.nodeKind}:${normalized.nodeId}`;
4615
+ if (seen.has(dedupeKey)) continue;
4616
+ seen.add(dedupeKey);
4617
+ out.push(normalized);
4618
+ }
4619
+ return out;
4620
+ }
4621
+ function resolveOrderKind(params) {
4622
+ var _a, _b;
4623
+ const nodeMap = (_a = params.nodeMap) != null ? _a : buildNodeMap(params.props);
4624
+ const orderKinds = (_b = params.props.orderKinds) != null ? _b : {};
4625
+ const normalizedSelected = normalizeSelectedOrderKindTriggers(
4626
+ params.selectedTriggerKeys,
4627
+ nodeMap
4628
+ );
4629
+ const selectedKindToSource = /* @__PURE__ */ new Map();
4630
+ const selectedNodeIdsForKinds = /* @__PURE__ */ new Map();
4631
+ for (const trigger of normalizedSelected) {
4632
+ const mappedKind = orderKinds[trigger.nodeId];
4633
+ if (typeof mappedKind !== "string") continue;
4634
+ if (!selectedKindToSource.has(mappedKind)) {
4635
+ selectedKindToSource.set(mappedKind, {
4636
+ nodeId: trigger.nodeId,
4637
+ nodeKind: trigger.nodeKind
4638
+ });
4639
+ }
4640
+ if (!selectedNodeIdsForKinds.has(mappedKind)) {
4641
+ selectedNodeIdsForKinds.set(mappedKind, /* @__PURE__ */ new Set());
4642
+ }
4643
+ selectedNodeIdsForKinds.get(mappedKind).add(trigger.nodeId);
4644
+ }
4645
+ const selectedKinds = Array.from(selectedKindToSource.keys());
4646
+ if (selectedKinds.length > 1) {
4647
+ const conflictingNodeIds = Array.from(selectedNodeIdsForKinds.values()).flatMap((ids) => Array.from(ids)).filter((id, idx, arr) => arr.indexOf(id) === idx);
4648
+ return {
4649
+ kind: null,
4650
+ source: null,
4651
+ error: "multiple_order_kinds_selected",
4652
+ conflictingKinds: selectedKinds,
4653
+ conflictingNodeIds
4654
+ };
4655
+ }
4656
+ if (selectedKinds.length === 1) {
4657
+ const selectedKind = selectedKinds[0];
4658
+ return {
4659
+ kind: selectedKind,
4660
+ source: selectedKindToSource.get(selectedKind)
4661
+ };
4662
+ }
4663
+ const activeTagId = params.activeTagId;
4664
+ if (activeTagId) {
4665
+ const tagKind = orderKinds[activeTagId];
4666
+ if (typeof tagKind === "string") {
4667
+ return {
4668
+ kind: tagKind,
4669
+ source: { nodeId: activeTagId, nodeKind: "tag" }
4670
+ };
4671
+ }
4672
+ }
4673
+ return { kind: null, source: null };
4674
+ }
4675
+
4676
+ // src/core/validate/steps/order-kinds.ts
4677
+ function validateOrderKinds(v) {
4678
+ var _a, _b, _c;
4679
+ const selectedTriggerKeys = Array.from((_a = v.selectedKeys) != null ? _a : []);
4680
+ if (!selectedTriggerKeys.length) return;
4681
+ const resolved = resolveOrderKind({
4682
+ props: v.props,
4683
+ selectedTriggerKeys,
4684
+ nodeMap: v.nodeMap
4685
+ });
4686
+ if (resolved.error !== "multiple_order_kinds_selected") return;
4687
+ const conflicts = (_b = resolved.conflictingKinds) != null ? _b : [];
4688
+ const affected = (_c = resolved.conflictingNodeIds) != null ? _c : [];
4689
+ v.errors.push({
4690
+ code: "multiple_order_kinds_selected",
4691
+ severity: "error",
4692
+ message: "Multiple selected triggers resolve to different order kinds. Select triggers that resolve to a single order kind.",
4693
+ details: withAffected(
4694
+ {
4695
+ conflictingKinds: conflicts,
4696
+ conflictingNodeIds: affected
4697
+ },
4698
+ affected
4699
+ )
4700
+ });
4701
+ }
4702
+
4569
4703
  // src/core/validate/steps/service-vs-input.ts
4570
4704
  function validateServiceVsUserInput(v) {
4571
4705
  for (const f of v.fields) {
@@ -5889,6 +6023,7 @@ var BuilderImpl = class {
5889
6023
  const out = {
5890
6024
  filters: this.props.filters.slice(),
5891
6025
  fields,
6026
+ ...this.props.orderKinds ? { orderKinds: this.props.orderKinds } : {},
5892
6027
  ...includes_for_buttons && { includes_for_buttons },
5893
6028
  ...excludes_for_buttons && { excludes_for_buttons },
5894
6029
  schema_version: (_e = this.props.schema_version) != null ? _e : "1.0",
@@ -6221,6 +6356,7 @@ function validate(props, ctx = {}) {
6221
6356
  validateStructure(v);
6222
6357
  validateIdentity(v);
6223
6358
  validateOptionMaps(v);
6359
+ validateOrderKinds(v);
6224
6360
  v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
6225
6361
  const visSim = readVisibilitySimOpts(options);
6226
6362
  validateVisibility(v, visSim);
@@ -6518,7 +6654,7 @@ function createNodeIndex(builder) {
6518
6654
  for (const fieldId of visible) {
6519
6655
  const node = getField(fieldId);
6520
6656
  if (!node) continue;
6521
- const explicit = includes.has(fieldId) || isFieldBoundDirectToTag(fieldId, tagId);
6657
+ const explicit = includes.has(fieldId);
6522
6658
  results.push(explicit ? node : { ...node, isInherited: true });
6523
6659
  }
6524
6660
  return Object.freeze(results);
@@ -8143,6 +8279,88 @@ function normalizeQuantityRule(input) {
8143
8279
  return out;
8144
8280
  }
8145
8281
 
8282
+ // src/react/canvas/editor/editor-order-kinds.ts
8283
+ function normalizeKind(kind) {
8284
+ const next = String(kind != null ? kind : "").trim();
8285
+ if (!next) {
8286
+ throw new Error("setOrderKind: kind must be a non-empty string");
8287
+ }
8288
+ return next;
8289
+ }
8290
+ function assertCanonicalNodeId(ctx, nodeId) {
8291
+ const id = String(nodeId != null ? nodeId : "").trim();
8292
+ if (!id) throw new Error("setOrderKind: nodeId is required");
8293
+ if (id.includes("::")) {
8294
+ throw new Error(
8295
+ "setOrderKind: composite/internal trigger keys are not allowed; use canonical tag/field/option ids"
8296
+ );
8297
+ }
8298
+ if (!ctx.isTagId(id) && !ctx.isFieldId(id) && !ctx.isOptionId(id)) {
8299
+ throw new Error(
8300
+ `setOrderKind: node id '${id}' is not a known tag, field, or option`
8301
+ );
8302
+ }
8303
+ if (ctx.isFieldId(id)) {
8304
+ const node = ctx.getNode(id);
8305
+ if (node.kind !== "field" || !isActualButtonField(node.data)) {
8306
+ throw new Error(
8307
+ `setOrderKind: field '${id}' must be a button field without options`
8308
+ );
8309
+ }
8310
+ }
8311
+ }
8312
+ function setOrderKind(ctx, nodeId, kind) {
8313
+ const id = String(nodeId != null ? nodeId : "").trim();
8314
+ const nextKind = normalizeKind(kind);
8315
+ assertCanonicalNodeId(ctx, id);
8316
+ ctx.exec({
8317
+ name: "setOrderKind",
8318
+ do: () => ctx.patchProps((p) => {
8319
+ if (!p.orderKinds) p.orderKinds = {};
8320
+ p.orderKinds[id] = nextKind;
8321
+ }),
8322
+ undo: () => ctx.undo()
8323
+ });
8324
+ }
8325
+ function deleteOrderKind(ctx, nodeId) {
8326
+ const id = String(nodeId != null ? nodeId : "").trim();
8327
+ if (!id) return;
8328
+ ctx.exec({
8329
+ name: "deleteOrderKind",
8330
+ do: () => ctx.patchProps((p) => {
8331
+ if (!p.orderKinds || !Object.prototype.hasOwnProperty.call(p.orderKinds, id)) {
8332
+ return;
8333
+ }
8334
+ delete p.orderKinds[id];
8335
+ if (!Object.keys(p.orderKinds).length) {
8336
+ delete p.orderKinds;
8337
+ }
8338
+ }),
8339
+ undo: () => ctx.undo()
8340
+ });
8341
+ }
8342
+ function pruneOrderKind(ctx, kind) {
8343
+ const target = normalizeKind(kind);
8344
+ let removedCount = 0;
8345
+ ctx.exec({
8346
+ name: "pruneOrderKind",
8347
+ do: () => ctx.patchProps((p) => {
8348
+ if (!p.orderKinds) return;
8349
+ removedCount = 0;
8350
+ for (const [nodeId, mapped] of Object.entries(p.orderKinds)) {
8351
+ if (mapped !== target) continue;
8352
+ delete p.orderKinds[nodeId];
8353
+ removedCount++;
8354
+ }
8355
+ if (!Object.keys(p.orderKinds).length) {
8356
+ delete p.orderKinds;
8357
+ }
8358
+ }),
8359
+ undo: () => ctx.undo()
8360
+ });
8361
+ return removedCount;
8362
+ }
8363
+
8146
8364
  // src/react/canvas/editor/editor-relations.ts
8147
8365
  function wouldCreateTagCycle(_ctx, p, parentId, childId) {
8148
8366
  var _a, _b;
@@ -8190,7 +8408,9 @@ function include(ctx, receiverId, idOrIds) {
8190
8408
  const ids = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
8191
8409
  if (receiver.kind === "tag" || receiver.kind === "field" && isActualButtonField(receiver.data) || receiver.kind === "option") {
8192
8410
  if (receiver.kind === "tag") {
8193
- const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === receiverId);
8411
+ const t = ((_a = p.filters) != null ? _a : []).find(
8412
+ (x) => x.id === receiverId
8413
+ );
8194
8414
  if (t) {
8195
8415
  const accepted = [];
8196
8416
  const next = new Set((_b = t.includes) != null ? _b : []);
@@ -8232,7 +8452,12 @@ function include(ctx, receiverId, idOrIds) {
8232
8452
  const current = (_f = (_e = p.includes_for_buttons) == null ? void 0 : _e[receiverId]) != null ? _f : [];
8233
8453
  const next = new Set(current);
8234
8454
  for (const id of ids) {
8235
- if (wouldCreateIncludeExcludeCycle(ctx, p, receiverId, id)) {
8455
+ if (wouldCreateIncludeExcludeCycle(
8456
+ ctx,
8457
+ p,
8458
+ receiverId,
8459
+ id
8460
+ )) {
8236
8461
  ctx.emit("editor:error", {
8237
8462
  message: `Cycle detected: ${receiverId} including ${id} would create a cycle.`,
8238
8463
  code: "cycle_detected",
@@ -8248,7 +8473,8 @@ function include(ctx, receiverId, idOrIds) {
8248
8473
  accepted.push(id);
8249
8474
  }
8250
8475
  if (accepted.length > 0 || current.length > 0) {
8251
- if (!p.includes_for_buttons) p.includes_for_buttons = {};
8476
+ if (!p.includes_for_buttons)
8477
+ p.includes_for_buttons = {};
8252
8478
  p.includes_for_buttons[receiverId] = Array.from(next);
8253
8479
  }
8254
8480
  if ((_g = p.excludes_for_buttons) == null ? void 0 : _g[receiverId]) {
@@ -8263,7 +8489,9 @@ function include(ctx, receiverId, idOrIds) {
8263
8489
  if (!p.fields) p.fields = [];
8264
8490
  if (!p.filters) p.filters = [];
8265
8491
  } else {
8266
- throw new Error("Receiver must be a tag, button field, or option");
8492
+ throw new Error(
8493
+ "Receiver must be a tag, button field, or option"
8494
+ );
8267
8495
  }
8268
8496
  }),
8269
8497
  undo: () => ctx.undo()
@@ -8278,7 +8506,9 @@ function exclude(ctx, receiverId, idOrIds) {
8278
8506
  const ids = Array.isArray(idOrIds) ? idOrIds : [idOrIds];
8279
8507
  if (receiver.kind === "tag" || receiver.kind === "field" && isActualButtonField(receiver.data) || receiver.kind === "option") {
8280
8508
  if (receiver.kind === "tag") {
8281
- const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === receiverId);
8509
+ const t = ((_a = p.filters) != null ? _a : []).find(
8510
+ (x) => x.id === receiverId
8511
+ );
8282
8512
  if (t) {
8283
8513
  const accepted = [];
8284
8514
  const next = new Set((_b = t.excludes) != null ? _b : []);
@@ -8320,7 +8550,12 @@ function exclude(ctx, receiverId, idOrIds) {
8320
8550
  const current = (_f = (_e = p.excludes_for_buttons) == null ? void 0 : _e[receiverId]) != null ? _f : [];
8321
8551
  const next = new Set(current);
8322
8552
  for (const id of ids) {
8323
- if (wouldCreateIncludeExcludeCycle(ctx, p, receiverId, id)) {
8553
+ if (wouldCreateIncludeExcludeCycle(
8554
+ ctx,
8555
+ p,
8556
+ receiverId,
8557
+ id
8558
+ )) {
8324
8559
  ctx.emit("editor:error", {
8325
8560
  message: `Cycle detected: ${receiverId} excluding ${id} would create a cycle.`,
8326
8561
  code: "cycle_detected",
@@ -8336,7 +8571,8 @@ function exclude(ctx, receiverId, idOrIds) {
8336
8571
  accepted.push(id);
8337
8572
  }
8338
8573
  if (accepted.length > 0 || current.length > 0) {
8339
- if (!p.excludes_for_buttons) p.excludes_for_buttons = {};
8574
+ if (!p.excludes_for_buttons)
8575
+ p.excludes_for_buttons = {};
8340
8576
  p.excludes_for_buttons[receiverId] = Array.from(next);
8341
8577
  }
8342
8578
  if ((_g = p.includes_for_buttons) == null ? void 0 : _g[receiverId]) {
@@ -8351,7 +8587,9 @@ function exclude(ctx, receiverId, idOrIds) {
8351
8587
  if (!p.fields) p.fields = [];
8352
8588
  if (!p.filters) p.filters = [];
8353
8589
  } else {
8354
- throw new Error("Receiver must be a tag, button field, or option");
8590
+ throw new Error(
8591
+ "Receiver must be a tag, button field, or option"
8592
+ );
8355
8593
  }
8356
8594
  }),
8357
8595
  undo: () => ctx.undo()
@@ -8361,87 +8599,98 @@ function connect(ctx, kind, fromId, toId2) {
8361
8599
  ctx.exec({
8362
8600
  name: `connect:${kind}`,
8363
8601
  do: () => ctx.patchProps((p) => {
8364
- var _a, _b, _c, _d, _e;
8602
+ var _a, _b, _c, _d, _e, _f, _g, _h;
8365
8603
  if (kind === "bind") {
8366
8604
  if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
8367
8605
  if (wouldCreateTagCycle(ctx, p, fromId, toId2)) {
8368
- throw new Error(`bind would create a cycle: ${fromId} ? ${toId2}`);
8606
+ throw new Error(
8607
+ `bind would create a cycle: ${fromId} ? ${toId2}`
8608
+ );
8369
8609
  }
8370
- const child = ((_a = p.filters) != null ? _a : []).find((t) => t.id === toId2);
8610
+ const child = ((_a = p.filters) != null ? _a : []).find(
8611
+ (t) => t.id === toId2
8612
+ );
8371
8613
  if (child) child.bind_id = fromId;
8372
8614
  return;
8373
8615
  }
8374
8616
  if (ctx.isTagId(fromId) && ctx.isFieldId(toId2) || ctx.isFieldId(fromId) && ctx.isTagId(toId2)) {
8375
8617
  const fieldId = ctx.isFieldId(toId2) ? toId2 : fromId;
8376
8618
  const tagId = ctx.isTagId(fromId) ? fromId : toId2;
8377
- const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === fieldId);
8619
+ const f = ((_b = p.fields) != null ? _b : []).find(
8620
+ (x) => x.id === fieldId
8621
+ );
8378
8622
  if (!f) return;
8379
8623
  if (!f.bind_id) {
8380
8624
  f.bind_id = tagId;
8381
8625
  return;
8382
8626
  }
8383
8627
  if (typeof f.bind_id === "string") {
8384
- if (f.bind_id !== tagId) f.bind_id = [f.bind_id, tagId];
8628
+ if (f.bind_id !== tagId) {
8629
+ f.bind_id = [f.bind_id, tagId];
8630
+ }
8385
8631
  return;
8386
8632
  }
8387
- if (!f.bind_id.includes(tagId)) f.bind_id.push(tagId);
8633
+ if (!f.bind_id.includes(tagId)) {
8634
+ f.bind_id.push(tagId);
8635
+ }
8388
8636
  return;
8389
8637
  }
8390
- throw new Error(`bind: unsupported route ${fromId} ? ${toId2}`);
8638
+ throw new Error(
8639
+ `bind: unsupported route ${fromId} ? ${toId2}`
8640
+ );
8391
8641
  }
8392
8642
  if (kind === "include" || kind === "exclude") {
8393
- const key = kind === "include" ? "includes" : "excludes";
8643
+ const tagKey = kind === "include" ? "includes" : "excludes";
8644
+ const mapKey = kind === "include" ? "includes_for_buttons" : "excludes_for_buttons";
8394
8645
  if (ctx.isTagId(fromId) && ctx.isFieldId(toId2)) {
8395
- const t = ((_c = p.filters) != null ? _c : []).find((x) => x.id === fromId);
8646
+ const t = ((_c = p.filters) != null ? _c : []).find(
8647
+ (x) => x.id === fromId
8648
+ );
8396
8649
  if (!t) return;
8397
- const arr = (_d = t[key]) != null ? _d : t[key] = [];
8650
+ const arr = (_d = t[tagKey]) != null ? _d : t[tagKey] = [];
8398
8651
  if (!arr.includes(toId2)) arr.push(toId2);
8399
8652
  return;
8400
8653
  }
8654
+ if (ctx.isFieldId(fromId) && ctx.isFieldId(toId2)) {
8655
+ const source = ((_e = p.fields) != null ? _e : []).find(
8656
+ (x) => x.id === fromId
8657
+ );
8658
+ if (!(source == null ? void 0 : source.button)) {
8659
+ throw new Error(
8660
+ `${kind}: source field must be button=true: ${fromId} ? ${toId2}`
8661
+ );
8662
+ }
8663
+ addMappedField(p, mapKey, fromId, toId2);
8664
+ return;
8665
+ }
8401
8666
  if (ctx.isOptionId(fromId) && ctx.isFieldId(toId2)) {
8402
- const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
8403
- const maps = p[mapKey];
8404
- const next = { ...maps != null ? maps : {} };
8405
- const arr = (_e = next[fromId]) != null ? _e : [];
8406
- if (!arr.includes(toId2)) arr.push(toId2);
8407
- next[fromId] = arr;
8408
- p[mapKey] = next;
8667
+ addMappedField(p, mapKey, fromId, toId2);
8409
8668
  return;
8410
8669
  }
8411
- throw new Error(`${kind}: unsupported route ${fromId} ? ${toId2}`);
8670
+ throw new Error(
8671
+ `${kind}: unsupported route ${fromId} ? ${toId2}`
8672
+ );
8412
8673
  }
8413
8674
  if (kind === "service") {
8414
8675
  ensureServiceExists(ctx.opts, fromId);
8415
8676
  if (toId2.startsWith("t:")) {
8416
- ctx.exec({
8417
- name: "connect:service?tag",
8418
- do: () => ctx.patchProps((next) => {
8419
- var _a2;
8420
- const t = ((_a2 = next.filters) != null ? _a2 : []).find((x) => x.id === toId2);
8421
- if (t) t.service_id = fromId;
8422
- }),
8423
- undo: () => ctx.undo()
8424
- });
8677
+ const t = ((_f = p.filters) != null ? _f : []).find((x) => x.id === toId2);
8678
+ if (t) t.service_id = fromId;
8425
8679
  return;
8426
8680
  }
8427
8681
  if (toId2.startsWith("o:")) {
8428
- ctx.exec({
8429
- name: "connect:service?option",
8430
- do: () => ctx.patchProps((next) => {
8431
- var _a2, _b2;
8432
- for (const f of (_a2 = next.fields) != null ? _a2 : []) {
8433
- const o = (_b2 = f.options) == null ? void 0 : _b2.find((x) => x.id === toId2);
8434
- if (o) {
8435
- o.service_id = fromId;
8436
- return;
8437
- }
8438
- }
8439
- }),
8440
- undo: () => ctx.undo()
8441
- });
8682
+ for (const f of (_g = p.fields) != null ? _g : []) {
8683
+ const o = (_h = f.options) == null ? void 0 : _h.find((x) => x.id === toId2);
8684
+ if (o) {
8685
+ o.service_id = fromId;
8686
+ return;
8687
+ }
8688
+ }
8442
8689
  return;
8443
8690
  }
8444
- throw new Error('service: to must be a tag ("t:*") or option ("o:*")');
8691
+ throw new Error(
8692
+ 'service: to must be a tag ("t:*") or option ("o:*")'
8693
+ );
8445
8694
  }
8446
8695
  throw new Error(`Unknown connect kind: ${kind}`);
8447
8696
  }),
@@ -8452,90 +8701,109 @@ function disconnect(ctx, kind, fromId, toId2) {
8452
8701
  ctx.exec({
8453
8702
  name: `disconnect:${kind}`,
8454
8703
  do: () => ctx.patchProps((p) => {
8455
- var _a, _b, _c, _d, _e, _f, _g, _h;
8704
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
8456
8705
  if (kind === "bind") {
8457
8706
  if (ctx.isTagId(fromId) && ctx.isTagId(toId2)) {
8458
- const child = ((_a = p.filters) != null ? _a : []).find((t) => t.id === toId2);
8459
- if ((child == null ? void 0 : child.bind_id) === fromId) delete child.bind_id;
8707
+ const child = ((_a = p.filters) != null ? _a : []).find(
8708
+ (t) => t.id === toId2
8709
+ );
8710
+ if ((child == null ? void 0 : child.bind_id) === fromId) {
8711
+ delete child.bind_id;
8712
+ }
8460
8713
  return;
8461
8714
  }
8462
8715
  if (ctx.isTagId(fromId) && ctx.isFieldId(toId2) || ctx.isFieldId(fromId) && ctx.isTagId(toId2)) {
8463
8716
  const fieldId = ctx.isFieldId(toId2) ? toId2 : fromId;
8464
8717
  const tagId = ctx.isTagId(fromId) ? fromId : toId2;
8465
- const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === fieldId);
8718
+ const f = ((_b = p.fields) != null ? _b : []).find(
8719
+ (x) => x.id === fieldId
8720
+ );
8466
8721
  if (!(f == null ? void 0 : f.bind_id)) return;
8467
8722
  if (typeof f.bind_id === "string") {
8468
- if (f.bind_id === tagId) delete f.bind_id;
8723
+ if (f.bind_id === tagId) {
8724
+ delete f.bind_id;
8725
+ }
8469
8726
  return;
8470
8727
  }
8471
8728
  f.bind_id = f.bind_id.filter((x) => x !== tagId);
8472
- if (((_c = f.bind_id) == null ? void 0 : _c.length) === 0) delete f.bind_id;
8729
+ if (((_c = f.bind_id) == null ? void 0 : _c.length) === 0) {
8730
+ delete f.bind_id;
8731
+ }
8473
8732
  return;
8474
8733
  }
8475
- throw new Error(`unbind: unsupported route ${fromId} ? ${toId2}`);
8734
+ throw new Error(
8735
+ `unbind: unsupported route ${fromId} ? ${toId2}`
8736
+ );
8476
8737
  }
8477
8738
  if (kind === "include" || kind === "exclude") {
8478
- const key = kind === "include" ? "includes" : "excludes";
8739
+ const tagKey = kind === "include" ? "includes" : "excludes";
8740
+ const mapKey = kind === "include" ? "includes_for_buttons" : "excludes_for_buttons";
8479
8741
  if (ctx.isTagId(fromId) && ctx.isFieldId(toId2)) {
8480
- const t = ((_d = p.filters) != null ? _d : []).find((x) => x.id === fromId);
8742
+ const t = ((_d = p.filters) != null ? _d : []).find(
8743
+ (x) => x.id === fromId
8744
+ );
8481
8745
  if (!t) return;
8482
- t[key] = ((_e = t[key]) != null ? _e : []).filter((x) => x !== toId2);
8483
- if (!((_f = t[key]) == null ? void 0 : _f.length)) delete t[key];
8746
+ t[tagKey] = ((_e = t[tagKey]) != null ? _e : []).filter((x) => x !== toId2);
8747
+ if (!((_f = t[tagKey]) == null ? void 0 : _f.length)) {
8748
+ delete t[tagKey];
8749
+ }
8484
8750
  return;
8485
8751
  }
8486
- if (ctx.isOptionId(fromId) && ctx.isFieldId(toId2)) {
8487
- const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
8752
+ if ((ctx.isFieldId(fromId) || ctx.isOptionId(fromId)) && ctx.isFieldId(toId2)) {
8488
8753
  const maps = p[mapKey];
8489
- if (!maps) return;
8490
- if (maps[fromId]) {
8491
- maps[fromId] = ((_g = maps[fromId]) != null ? _g : []).filter(
8492
- (fid) => fid !== toId2
8493
- );
8494
- if (!((_h = maps[fromId]) == null ? void 0 : _h.length)) delete maps[fromId];
8754
+ if (!(maps == null ? void 0 : maps[fromId])) return;
8755
+ maps[fromId] = maps[fromId].filter(
8756
+ (fid) => fid !== toId2
8757
+ );
8758
+ if (!((_g = maps[fromId]) == null ? void 0 : _g.length)) {
8759
+ delete maps[fromId];
8760
+ }
8761
+ if (!Object.keys(maps).length) {
8762
+ delete p[mapKey];
8495
8763
  }
8496
- if (!Object.keys(maps).length) delete p[mapKey];
8497
8764
  return;
8498
8765
  }
8499
- throw new Error(`${kind}: unsupported route ${fromId} ? ${toId2}`);
8766
+ throw new Error(
8767
+ `${kind}: unsupported route ${fromId} ? ${toId2}`
8768
+ );
8500
8769
  }
8501
8770
  if (kind === "service") {
8502
8771
  ensureServiceExists(ctx.opts, fromId);
8503
8772
  if (toId2.startsWith("t:")) {
8504
- ctx.exec({
8505
- name: "disconnect:service?tag",
8506
- do: () => ctx.patchProps((next) => {
8507
- var _a2;
8508
- const t = ((_a2 = next.filters) != null ? _a2 : []).find((x) => x.id === toId2);
8509
- if (t) delete t.service_id;
8510
- }),
8511
- undo: () => ctx.undo()
8512
- });
8773
+ const t = ((_h = p.filters) != null ? _h : []).find((x) => x.id === toId2);
8774
+ if (t) {
8775
+ delete t.service_id;
8776
+ }
8513
8777
  return;
8514
8778
  }
8515
8779
  if (toId2.startsWith("o:")) {
8516
- ctx.exec({
8517
- name: "disconnect:service?option",
8518
- do: () => ctx.patchProps((next) => {
8519
- var _a2, _b2;
8520
- for (const f of (_a2 = next.fields) != null ? _a2 : []) {
8521
- const o = (_b2 = f.options) == null ? void 0 : _b2.find((x) => x.id === toId2);
8522
- if (o) {
8523
- delete o.service_id;
8524
- return;
8525
- }
8526
- }
8527
- }),
8528
- undo: () => ctx.undo()
8529
- });
8780
+ for (const f of (_i = p.fields) != null ? _i : []) {
8781
+ const o = (_j = f.options) == null ? void 0 : _j.find((x) => x.id === toId2);
8782
+ if (o) {
8783
+ delete o.service_id;
8784
+ return;
8785
+ }
8786
+ }
8530
8787
  return;
8531
8788
  }
8532
- throw new Error('service: to must be a tag ("t:*") or option ("o:*")');
8789
+ throw new Error(
8790
+ 'service: to must be a tag ("t:*") or option ("o:*")'
8791
+ );
8533
8792
  }
8534
8793
  throw new Error(`Unknown disconnect kind: ${kind}`);
8535
8794
  }),
8536
8795
  undo: () => ctx.undo()
8537
8796
  });
8538
8797
  }
8798
+ function addMappedField(p, mapKey, fromId, toId2) {
8799
+ var _a, _b;
8800
+ const maps = (_a = p[mapKey]) != null ? _a : {};
8801
+ const arr = (_b = maps[fromId]) != null ? _b : [];
8802
+ if (!arr.includes(toId2)) {
8803
+ maps[fromId] = [...arr, toId2];
8804
+ }
8805
+ p[mapKey] = maps;
8806
+ }
8539
8807
 
8540
8808
  // src/react/canvas/editor/editor-service-filter.ts
8541
8809
  function filterServicesForVisibleGroup2(ctx, candidates, input) {
@@ -9123,6 +9391,15 @@ var Editor = class {
9123
9391
  clearFieldValidation(id) {
9124
9392
  return clearFieldValidation(this.moduleCtx(), id);
9125
9393
  }
9394
+ setOrderKind(nodeId, kind) {
9395
+ return setOrderKind(this.moduleCtx(), nodeId, kind);
9396
+ }
9397
+ deleteOrderKind(nodeId) {
9398
+ return deleteOrderKind(this.moduleCtx(), nodeId);
9399
+ }
9400
+ pruneKind(kind) {
9401
+ return pruneOrderKind(this.moduleCtx(), kind);
9402
+ }
9126
9403
  getCatalog() {
9127
9404
  return (0, import_lodash_es4.cloneDeep)(this.catalog);
9128
9405
  }