@timeax/digital-service-engine 0.0.1 → 0.0.2
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 +1097 -193
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +189 -51
- package/dist/core/index.d.ts +189 -51
- package/dist/core/index.js +1095 -193
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +8313 -2542
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +401 -141
- package/dist/react/index.d.ts +401 -141
- package/dist/react/index.js +8471 -2709
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.d.cts +122 -54
- package/dist/schema/index.d.ts +122 -54
- package/dist/workspace/index.cjs +448 -239
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +54 -50
- package/dist/workspace/index.d.ts +54 -50
- package/dist/workspace/index.js +448 -239
- package/dist/workspace/index.js.map +1 -1
- package/package.json +15 -6
- package/schema/editor-snapshot.schema.json +121 -209
- package/schema/service-props.schema.json +121 -209
package/dist/workspace/index.cjs
CHANGED
|
@@ -3260,11 +3260,6 @@ function hasAnyServiceOption(f) {
|
|
|
3260
3260
|
var _a;
|
|
3261
3261
|
return ((_a = f.options) != null ? _a : []).some((o) => isFiniteNumber(o.service_id));
|
|
3262
3262
|
}
|
|
3263
|
-
function isBoundTo(f, tagId) {
|
|
3264
|
-
const b = f.bind_id;
|
|
3265
|
-
if (!b) return false;
|
|
3266
|
-
return Array.isArray(b) ? b.includes(tagId) : b === tagId;
|
|
3267
|
-
}
|
|
3268
3263
|
function getByPath(obj, path) {
|
|
3269
3264
|
if (!path) return void 0;
|
|
3270
3265
|
const parts = path.split(".");
|
|
@@ -3350,33 +3345,217 @@ function withAffected(details, ids) {
|
|
|
3350
3345
|
return { ...details != null ? details : {}, affectedIds: ids };
|
|
3351
3346
|
}
|
|
3352
3347
|
|
|
3348
|
+
// src/core/node-map.ts
|
|
3349
|
+
function buildNodeMap(props) {
|
|
3350
|
+
var _a, _b, _c;
|
|
3351
|
+
const map = /* @__PURE__ */ new Map();
|
|
3352
|
+
for (const t of (_a = props.filters) != null ? _a : []) {
|
|
3353
|
+
if (!map.has(t.id)) map.set(t.id, { kind: "tag", id: t.id, node: t });
|
|
3354
|
+
}
|
|
3355
|
+
for (const f of (_b = props.fields) != null ? _b : []) {
|
|
3356
|
+
if (!map.has(f.id)) map.set(f.id, { kind: "field", id: f.id, node: f });
|
|
3357
|
+
for (const o of (_c = f.options) != null ? _c : []) {
|
|
3358
|
+
if (!map.has(o.id))
|
|
3359
|
+
map.set(o.id, {
|
|
3360
|
+
kind: "option",
|
|
3361
|
+
id: o.id,
|
|
3362
|
+
node: o,
|
|
3363
|
+
fieldId: f.id
|
|
3364
|
+
});
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
return map;
|
|
3368
|
+
}
|
|
3369
|
+
function resolveTrigger(trigger, nodeMap) {
|
|
3370
|
+
const idx = trigger.indexOf("::");
|
|
3371
|
+
if (idx !== -1) {
|
|
3372
|
+
const fieldId = trigger.slice(0, idx);
|
|
3373
|
+
const optionId = trigger.slice(idx + 2);
|
|
3374
|
+
return { kind: "composite", triggerKey: trigger, fieldId, optionId };
|
|
3375
|
+
}
|
|
3376
|
+
const direct = nodeMap.get(trigger);
|
|
3377
|
+
if (!direct) return void 0;
|
|
3378
|
+
if (direct.kind === "option") {
|
|
3379
|
+
return {
|
|
3380
|
+
kind: "option",
|
|
3381
|
+
triggerKey: trigger,
|
|
3382
|
+
id: direct.id,
|
|
3383
|
+
fieldId: direct.fieldId
|
|
3384
|
+
};
|
|
3385
|
+
}
|
|
3386
|
+
return { kind: direct.kind, triggerKey: trigger, id: direct.id };
|
|
3387
|
+
}
|
|
3388
|
+
|
|
3389
|
+
// src/core/visibility.ts
|
|
3390
|
+
function visibleFieldIdsUnder(props, tagId, opts = {}) {
|
|
3391
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3392
|
+
const tags = (_a = props.filters) != null ? _a : [];
|
|
3393
|
+
const fields = (_b = props.fields) != null ? _b : [];
|
|
3394
|
+
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
3395
|
+
const tag = tagById.get(tagId);
|
|
3396
|
+
if (!tag) return [];
|
|
3397
|
+
const nodeMap = buildNodeMap(props);
|
|
3398
|
+
const lineageDepth = /* @__PURE__ */ new Map();
|
|
3399
|
+
{
|
|
3400
|
+
const guard = /* @__PURE__ */ new Set();
|
|
3401
|
+
let cur = tag;
|
|
3402
|
+
let d = 0;
|
|
3403
|
+
while (cur && !guard.has(cur.id)) {
|
|
3404
|
+
lineageDepth.set(cur.id, d++);
|
|
3405
|
+
guard.add(cur.id);
|
|
3406
|
+
const parentId = cur.bind_id;
|
|
3407
|
+
cur = parentId ? tagById.get(parentId) : void 0;
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
3411
|
+
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
3412
|
+
const ownerDepthForField = (f) => {
|
|
3413
|
+
const b = f.bind_id;
|
|
3414
|
+
if (!b) return void 0;
|
|
3415
|
+
if (typeof b === "string") return lineageDepth.get(b);
|
|
3416
|
+
let best = void 0;
|
|
3417
|
+
for (const id of b) {
|
|
3418
|
+
const d = lineageDepth.get(id);
|
|
3419
|
+
if (d == null) continue;
|
|
3420
|
+
if (best == null || d < best) best = d;
|
|
3421
|
+
}
|
|
3422
|
+
return best;
|
|
3423
|
+
};
|
|
3424
|
+
const ownerDepthForTriggerKey = (triggerKey) => {
|
|
3425
|
+
const t = resolveTrigger(triggerKey, nodeMap);
|
|
3426
|
+
if (!t) return void 0;
|
|
3427
|
+
if (t.kind === "composite") {
|
|
3428
|
+
const f = fieldById.get(t.fieldId);
|
|
3429
|
+
if (!f) return void 0;
|
|
3430
|
+
return ownerDepthForField(f);
|
|
3431
|
+
}
|
|
3432
|
+
if (t.kind === "field") {
|
|
3433
|
+
const f = fieldById.get(t.id);
|
|
3434
|
+
if (!f || f.button !== true) return void 0;
|
|
3435
|
+
return ownerDepthForField(f);
|
|
3436
|
+
}
|
|
3437
|
+
if (t.kind === "option") {
|
|
3438
|
+
const f = t.fieldId ? fieldById.get(t.fieldId) : void 0;
|
|
3439
|
+
if (!f) return void 0;
|
|
3440
|
+
return ownerDepthForField(f);
|
|
3441
|
+
}
|
|
3442
|
+
return void 0;
|
|
3443
|
+
};
|
|
3444
|
+
const tagInclude = new Set((_c = tag.includes) != null ? _c : []);
|
|
3445
|
+
const tagExclude = new Set((_d = tag.excludes) != null ? _d : []);
|
|
3446
|
+
const selected = (_e = opts.selectedKeys) != null ? _e : /* @__PURE__ */ new Set();
|
|
3447
|
+
const incMap = (_f = props.includes_for_buttons) != null ? _f : {};
|
|
3448
|
+
const excMap = (_g = props.excludes_for_buttons) != null ? _g : {};
|
|
3449
|
+
const relevantTriggersInOrder = [];
|
|
3450
|
+
for (const key of selected) {
|
|
3451
|
+
const d = ownerDepthForTriggerKey(key);
|
|
3452
|
+
if (d == null) continue;
|
|
3453
|
+
relevantTriggersInOrder.push(key);
|
|
3454
|
+
}
|
|
3455
|
+
const visible = /* @__PURE__ */ new Set();
|
|
3456
|
+
const isBoundToLineage = (f) => {
|
|
3457
|
+
const b = f.bind_id;
|
|
3458
|
+
if (!b) return false;
|
|
3459
|
+
if (typeof b === "string") return isTagInLineage(b);
|
|
3460
|
+
for (const id of b) if (isTagInLineage(id)) return true;
|
|
3461
|
+
return false;
|
|
3462
|
+
};
|
|
3463
|
+
for (const f of fields) {
|
|
3464
|
+
if (isBoundToLineage(f)) visible.add(f.id);
|
|
3465
|
+
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
3466
|
+
}
|
|
3467
|
+
for (const id of tagExclude) visible.delete(id);
|
|
3468
|
+
const decide = /* @__PURE__ */ new Map();
|
|
3469
|
+
const applyDecision = (fieldId, next) => {
|
|
3470
|
+
const prev = decide.get(fieldId);
|
|
3471
|
+
if (!prev) return void decide.set(fieldId, next);
|
|
3472
|
+
if (next.depth < prev.depth) return void decide.set(fieldId, next);
|
|
3473
|
+
if (next.depth > prev.depth) return;
|
|
3474
|
+
if (prev.kind === "include" && next.kind === "exclude") {
|
|
3475
|
+
decide.set(fieldId, next);
|
|
3476
|
+
}
|
|
3477
|
+
};
|
|
3478
|
+
const revealedOrder = [];
|
|
3479
|
+
const revealedSeen = /* @__PURE__ */ new Set();
|
|
3480
|
+
for (const triggerKey of relevantTriggersInOrder) {
|
|
3481
|
+
const depth = ownerDepthForTriggerKey(triggerKey);
|
|
3482
|
+
if (depth == null) continue;
|
|
3483
|
+
for (const id of (_h = incMap[triggerKey]) != null ? _h : []) {
|
|
3484
|
+
applyDecision(id, { depth, kind: "include" });
|
|
3485
|
+
if (!revealedSeen.has(id)) {
|
|
3486
|
+
revealedSeen.add(id);
|
|
3487
|
+
revealedOrder.push(id);
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
for (const id of (_i = excMap[triggerKey]) != null ? _i : []) {
|
|
3491
|
+
applyDecision(id, { depth, kind: "exclude" });
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
for (const [fid, d] of decide) {
|
|
3495
|
+
if (d.kind === "include") visible.add(fid);
|
|
3496
|
+
else visible.delete(fid);
|
|
3497
|
+
}
|
|
3498
|
+
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
3499
|
+
const order = (_j = props.order_for_tags) == null ? void 0 : _j[tagId];
|
|
3500
|
+
if (order && order.length) {
|
|
3501
|
+
const ordered = order.filter((fid) => visible.has(fid));
|
|
3502
|
+
const orderedSet = new Set(ordered);
|
|
3503
|
+
const rest2 = base.filter((fid) => !orderedSet.has(fid));
|
|
3504
|
+
return [...ordered, ...rest2];
|
|
3505
|
+
}
|
|
3506
|
+
const promoted = revealedOrder.filter((fid) => visible.has(fid));
|
|
3507
|
+
const promotedSet = new Set(promoted);
|
|
3508
|
+
const rest = base.filter((fid) => !promotedSet.has(fid));
|
|
3509
|
+
return [...promoted, ...rest];
|
|
3510
|
+
}
|
|
3511
|
+
function visibleFieldsUnder(props, tagId, opts = {}) {
|
|
3512
|
+
var _a;
|
|
3513
|
+
const ids = visibleFieldIdsUnder(props, tagId, opts);
|
|
3514
|
+
const fieldById = new Map(((_a = props.fields) != null ? _a : []).map((f) => [f.id, f]));
|
|
3515
|
+
return ids.map((id) => fieldById.get(id)).filter(Boolean);
|
|
3516
|
+
}
|
|
3517
|
+
|
|
3353
3518
|
// src/core/validate/steps/visibility.ts
|
|
3354
3519
|
function createFieldsVisibleUnder(v) {
|
|
3355
3520
|
return (tagId) => {
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
const excludesTag = new Set((_b = tag == null ? void 0 : tag.excludes) != null ? _b : []);
|
|
3360
|
-
const incForOpt = (_c = v.props.includes_for_buttons) != null ? _c : {};
|
|
3361
|
-
const excForOpt = (_d = v.props.excludes_for_buttons) != null ? _d : {};
|
|
3362
|
-
const includesOpt = /* @__PURE__ */ new Set();
|
|
3363
|
-
const excludesOpt = /* @__PURE__ */ new Set();
|
|
3364
|
-
for (const key of v.selectedKeys) {
|
|
3365
|
-
for (const id of (_e = incForOpt[key]) != null ? _e : []) includesOpt.add(id);
|
|
3366
|
-
for (const id of (_f = excForOpt[key]) != null ? _f : []) excludesOpt.add(id);
|
|
3367
|
-
}
|
|
3368
|
-
const merged = /* @__PURE__ */ new Map();
|
|
3369
|
-
for (const f of v.fields) {
|
|
3370
|
-
if (isBoundTo(f, tagId)) merged.set(f.id, f);
|
|
3371
|
-
if (includesTag.has(f.id)) merged.set(f.id, f);
|
|
3372
|
-
if (includesOpt.has(f.id)) merged.set(f.id, f);
|
|
3373
|
-
}
|
|
3374
|
-
for (const id of excludesTag) merged.delete(id);
|
|
3375
|
-
for (const id of excludesOpt) merged.delete(id);
|
|
3376
|
-
return Array.from(merged.values());
|
|
3521
|
+
return visibleFieldsUnder(v.props, tagId, {
|
|
3522
|
+
selectedKeys: v.selectedKeys
|
|
3523
|
+
});
|
|
3377
3524
|
};
|
|
3378
3525
|
}
|
|
3379
|
-
function
|
|
3526
|
+
function stableKeyOfSelection(keys) {
|
|
3527
|
+
return Array.from(keys).sort().join("|");
|
|
3528
|
+
}
|
|
3529
|
+
function resolveRootTags(tags) {
|
|
3530
|
+
const roots = tags.filter((t) => !t.bind_id);
|
|
3531
|
+
return roots.length ? roots : tags.slice(0, 1);
|
|
3532
|
+
}
|
|
3533
|
+
function isEffectfulTrigger(v, trigger) {
|
|
3534
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3535
|
+
const inc = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3536
|
+
const exc = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3537
|
+
return ((_d = (_c = inc[trigger]) == null ? void 0 : _c.length) != null ? _d : 0) > 0 || ((_f = (_e = exc[trigger]) == null ? void 0 : _e.length) != null ? _f : 0) > 0;
|
|
3538
|
+
}
|
|
3539
|
+
function collectSelectableTriggersInContext(v, tagId, selectedKeys, onlyEffectful) {
|
|
3540
|
+
var _a;
|
|
3541
|
+
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
3542
|
+
selectedKeys
|
|
3543
|
+
});
|
|
3544
|
+
const triggers = [];
|
|
3545
|
+
for (const f of visible) {
|
|
3546
|
+
if (f.button === true) {
|
|
3547
|
+
const t = f.id;
|
|
3548
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3549
|
+
}
|
|
3550
|
+
for (const o of (_a = f.options) != null ? _a : []) {
|
|
3551
|
+
const t = `${f.id}::${o.id}`;
|
|
3552
|
+
if (!onlyEffectful || isEffectfulTrigger(v, t)) triggers.push(t);
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
triggers.sort();
|
|
3556
|
+
return triggers;
|
|
3557
|
+
}
|
|
3558
|
+
function runVisibilityRulesOnce(v) {
|
|
3380
3559
|
var _a, _b, _c, _d, _e;
|
|
3381
3560
|
for (const t of v.tags) {
|
|
3382
3561
|
const visible = v.fieldsVisibleUnder(t.id);
|
|
@@ -3451,12 +3630,85 @@ function validateVisibility(v) {
|
|
|
3451
3630
|
}
|
|
3452
3631
|
}
|
|
3453
3632
|
}
|
|
3633
|
+
function dedupeErrorsInPlace(v, startIndex) {
|
|
3634
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3635
|
+
const keyOfErr = (e) => {
|
|
3636
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
3637
|
+
const tagId = (_e = (_d = (_a = e == null ? void 0 : e.details) == null ? void 0 : _a.tagId) != null ? _d : (_c = (_b = e == null ? void 0 : e.details) == null ? void 0 : _b.affected) == null ? void 0 : _c.tagId) != null ? _e : "";
|
|
3638
|
+
const other = (_g = (_f = e == null ? void 0 : e.details) == null ? void 0 : _f.other) != null ? _g : "";
|
|
3639
|
+
return `${(_h = e == null ? void 0 : e.code) != null ? _h : ""}::${(_i = e == null ? void 0 : e.nodeId) != null ? _i : ""}::${tagId}::${other}::${(_j = e == null ? void 0 : e.message) != null ? _j : ""}`;
|
|
3640
|
+
};
|
|
3641
|
+
const kept = [];
|
|
3642
|
+
for (let i = startIndex; i < v.errors.length; i++) {
|
|
3643
|
+
const e = v.errors[i];
|
|
3644
|
+
const k = keyOfErr(e);
|
|
3645
|
+
if (seen.has(k)) continue;
|
|
3646
|
+
seen.add(k);
|
|
3647
|
+
kept.push(e);
|
|
3648
|
+
}
|
|
3649
|
+
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
3650
|
+
}
|
|
3651
|
+
function validateVisibility(v, options = {}) {
|
|
3652
|
+
var _a, _b, _c;
|
|
3653
|
+
const simulate = options.simulate === true;
|
|
3654
|
+
if (!simulate) {
|
|
3655
|
+
runVisibilityRulesOnce(v);
|
|
3656
|
+
return;
|
|
3657
|
+
}
|
|
3658
|
+
const maxStates = Math.max(1, (_a = options.maxStates) != null ? _a : 500);
|
|
3659
|
+
const maxDepth = Math.max(0, (_b = options.maxDepth) != null ? _b : 6);
|
|
3660
|
+
const onlyEffectful = options.onlyEffectfulTriggers !== false;
|
|
3661
|
+
const roots = resolveRootTags(v.tags);
|
|
3662
|
+
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
3663
|
+
const originalSelected = new Set((_c = v.selectedKeys) != null ? _c : []);
|
|
3664
|
+
const errorsStart = v.errors.length;
|
|
3665
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3666
|
+
const stack = [];
|
|
3667
|
+
for (const rt of rootTags) {
|
|
3668
|
+
stack.push({
|
|
3669
|
+
rootTagId: rt.id,
|
|
3670
|
+
selected: new Set(originalSelected),
|
|
3671
|
+
depth: 0
|
|
3672
|
+
});
|
|
3673
|
+
}
|
|
3674
|
+
let validatedStates = 0;
|
|
3675
|
+
while (stack.length) {
|
|
3676
|
+
if (validatedStates >= maxStates) break;
|
|
3677
|
+
const state = stack.pop();
|
|
3678
|
+
const sig = stableKeyOfSelection(state.selected);
|
|
3679
|
+
if (visited.has(sig)) continue;
|
|
3680
|
+
visited.add(sig);
|
|
3681
|
+
v.selectedKeys = state.selected;
|
|
3682
|
+
validatedStates++;
|
|
3683
|
+
runVisibilityRulesOnce(v);
|
|
3684
|
+
if (state.depth >= maxDepth) continue;
|
|
3685
|
+
const triggers = collectSelectableTriggersInContext(
|
|
3686
|
+
v,
|
|
3687
|
+
state.rootTagId,
|
|
3688
|
+
state.selected,
|
|
3689
|
+
onlyEffectful
|
|
3690
|
+
);
|
|
3691
|
+
for (let i = triggers.length - 1; i >= 0; i--) {
|
|
3692
|
+
const trig = triggers[i];
|
|
3693
|
+
if (state.selected.has(trig)) continue;
|
|
3694
|
+
const next = new Set(state.selected);
|
|
3695
|
+
next.add(trig);
|
|
3696
|
+
stack.push({
|
|
3697
|
+
rootTagId: state.rootTagId,
|
|
3698
|
+
selected: next,
|
|
3699
|
+
depth: state.depth + 1
|
|
3700
|
+
});
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
v.selectedKeys = originalSelected;
|
|
3704
|
+
dedupeErrorsInPlace(v, errorsStart);
|
|
3705
|
+
}
|
|
3454
3706
|
|
|
3455
3707
|
// src/core/validate/steps/structure.ts
|
|
3456
3708
|
function validateStructure(v) {
|
|
3457
3709
|
const tags = v.tags;
|
|
3458
3710
|
const fields = v.fields;
|
|
3459
|
-
if (!tags.some((t) => t.id === "root")) {
|
|
3711
|
+
if (!tags.some((t) => t.id === "t:root")) {
|
|
3460
3712
|
v.errors.push({
|
|
3461
3713
|
code: "root_missing",
|
|
3462
3714
|
severity: "error",
|
|
@@ -3646,58 +3898,91 @@ function validateIdentity(v) {
|
|
|
3646
3898
|
}
|
|
3647
3899
|
|
|
3648
3900
|
// src/core/validate/steps/option-maps.ts
|
|
3901
|
+
function parseFieldOptionKey(key) {
|
|
3902
|
+
const idx = key.indexOf("::");
|
|
3903
|
+
if (idx === -1) return null;
|
|
3904
|
+
const fieldId = key.slice(0, idx).trim();
|
|
3905
|
+
const optionId = key.slice(idx + 2).trim();
|
|
3906
|
+
if (!fieldId || !optionId) return null;
|
|
3907
|
+
return { fieldId, optionId };
|
|
3908
|
+
}
|
|
3909
|
+
function hasOption(v, fid, oid) {
|
|
3910
|
+
var _a;
|
|
3911
|
+
const f = v.fieldById.get(fid);
|
|
3912
|
+
if (!f) return false;
|
|
3913
|
+
return !!((_a = f.options) != null ? _a : []).find((o) => o.id === oid);
|
|
3914
|
+
}
|
|
3649
3915
|
function validateOptionMaps(v) {
|
|
3650
3916
|
var _a, _b;
|
|
3651
3917
|
const incMap = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
3652
3918
|
const excMap = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
3653
|
-
const
|
|
3654
|
-
|
|
3655
|
-
const
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3919
|
+
const badKeyMessage = (key) => `Invalid trigger-map key "${key}". Expected a known node id (option or button-field), or "fieldId::optionId" pointing to an existing option.`;
|
|
3920
|
+
const validateTriggerKey = (key) => {
|
|
3921
|
+
const ref = v.nodeMap.get(key);
|
|
3922
|
+
if (ref) {
|
|
3923
|
+
if (ref.kind === "option") {
|
|
3924
|
+
return {
|
|
3925
|
+
ok: true,
|
|
3926
|
+
nodeId: ref.fieldId,
|
|
3927
|
+
affected: [ref.fieldId, ref.id]
|
|
3928
|
+
};
|
|
3929
|
+
}
|
|
3930
|
+
if (ref.kind === "field") {
|
|
3931
|
+
const isButton = ref.node.button === true;
|
|
3932
|
+
if (!isButton)
|
|
3933
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3934
|
+
return { ok: true, nodeId: ref.id, affected: [ref.id] };
|
|
3935
|
+
}
|
|
3936
|
+
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
3937
|
+
}
|
|
3938
|
+
const p = parseFieldOptionKey(key);
|
|
3939
|
+
if (!p) return { ok: false };
|
|
3940
|
+
if (!hasOption(v, p.fieldId, p.optionId))
|
|
3941
|
+
return {
|
|
3942
|
+
ok: false,
|
|
3943
|
+
nodeId: p.fieldId,
|
|
3944
|
+
affected: [p.fieldId, p.optionId]
|
|
3945
|
+
};
|
|
3946
|
+
return {
|
|
3947
|
+
ok: true,
|
|
3948
|
+
nodeId: p.fieldId,
|
|
3949
|
+
affected: [p.fieldId, p.optionId]
|
|
3950
|
+
};
|
|
3665
3951
|
};
|
|
3666
|
-
const badKeyMessage = (key) => `Invalid option-map key "${key}". Expected "fieldId::optionId" pointing to an existing option.`;
|
|
3667
3952
|
for (const k of Object.keys(incMap)) {
|
|
3668
|
-
const
|
|
3669
|
-
if (!
|
|
3953
|
+
const r = validateTriggerKey(k);
|
|
3954
|
+
if (!r.ok) {
|
|
3670
3955
|
v.errors.push({
|
|
3671
3956
|
code: "bad_option_key",
|
|
3672
3957
|
severity: "error",
|
|
3673
3958
|
message: badKeyMessage(k),
|
|
3674
|
-
|
|
3959
|
+
nodeId: r.nodeId,
|
|
3960
|
+
details: withAffected({ key: k }, r.affected)
|
|
3675
3961
|
});
|
|
3676
3962
|
}
|
|
3677
3963
|
}
|
|
3678
3964
|
for (const k of Object.keys(excMap)) {
|
|
3679
|
-
const
|
|
3680
|
-
if (!
|
|
3965
|
+
const r = validateTriggerKey(k);
|
|
3966
|
+
if (!r.ok) {
|
|
3681
3967
|
v.errors.push({
|
|
3682
3968
|
code: "bad_option_key",
|
|
3683
3969
|
severity: "error",
|
|
3684
3970
|
message: badKeyMessage(k),
|
|
3685
|
-
|
|
3971
|
+
nodeId: r.nodeId,
|
|
3972
|
+
details: withAffected({ key: k }, r.affected)
|
|
3686
3973
|
});
|
|
3687
3974
|
}
|
|
3688
3975
|
}
|
|
3689
3976
|
for (const k of Object.keys(incMap)) {
|
|
3690
|
-
if (k in excMap)
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
});
|
|
3700
|
-
}
|
|
3977
|
+
if (!(k in excMap)) continue;
|
|
3978
|
+
const r = validateTriggerKey(k);
|
|
3979
|
+
v.errors.push({
|
|
3980
|
+
code: "option_include_exclude_conflict",
|
|
3981
|
+
severity: "error",
|
|
3982
|
+
message: `Trigger-map key "${k}" appears in both includes_for_buttons and excludes_for_buttons.`,
|
|
3983
|
+
nodeId: r.nodeId,
|
|
3984
|
+
details: withAffected({ key: k }, r.affected)
|
|
3985
|
+
});
|
|
3701
3986
|
}
|
|
3702
3987
|
}
|
|
3703
3988
|
|
|
@@ -4602,8 +4887,23 @@ function applyPolicies(errors, props, serviceMap, policies, fieldsVisibleUnder,
|
|
|
4602
4887
|
}
|
|
4603
4888
|
|
|
4604
4889
|
// src/core/validate/index.ts
|
|
4890
|
+
function readVisibilitySimOpts(ctx) {
|
|
4891
|
+
const c = ctx;
|
|
4892
|
+
const simulate = c.simulateVisibility === true || c.visibilitySimulate === true || c.simulate === true;
|
|
4893
|
+
const maxStates = typeof c.maxVisibilityStates === "number" ? c.maxVisibilityStates : typeof c.visibilityMaxStates === "number" ? c.visibilityMaxStates : typeof c.maxStates === "number" ? c.maxStates : void 0;
|
|
4894
|
+
const maxDepth = typeof c.maxVisibilityDepth === "number" ? c.maxVisibilityDepth : typeof c.visibilityMaxDepth === "number" ? c.visibilityMaxDepth : typeof c.maxDepth === "number" ? c.maxDepth : void 0;
|
|
4895
|
+
const simulateAllRoots = c.simulateAllRoots === true || c.visibilitySimulateAllRoots === true;
|
|
4896
|
+
const onlyEffectfulTriggers = c.onlyEffectfulTriggers === false ? false : c.visibilityOnlyEffectfulTriggers !== false;
|
|
4897
|
+
return {
|
|
4898
|
+
simulate,
|
|
4899
|
+
maxStates,
|
|
4900
|
+
maxDepth,
|
|
4901
|
+
simulateAllRoots,
|
|
4902
|
+
onlyEffectfulTriggers
|
|
4903
|
+
};
|
|
4904
|
+
}
|
|
4605
4905
|
function validate(props, ctx = {}) {
|
|
4606
|
-
var _a, _b;
|
|
4906
|
+
var _a, _b, _c;
|
|
4607
4907
|
const errors = [];
|
|
4608
4908
|
const serviceMap = (_a = ctx.serviceMap) != null ? _a : {};
|
|
4609
4909
|
const selectedKeys = new Set(
|
|
@@ -4617,6 +4917,7 @@ function validate(props, ctx = {}) {
|
|
|
4617
4917
|
for (const f of fields) fieldById.set(f.id, f);
|
|
4618
4918
|
const v = {
|
|
4619
4919
|
props,
|
|
4920
|
+
nodeMap: (_c = ctx.nodeMap) != null ? _c : buildNodeMap(props),
|
|
4620
4921
|
options: ctx,
|
|
4621
4922
|
errors,
|
|
4622
4923
|
serviceMap,
|
|
@@ -4631,7 +4932,8 @@ function validate(props, ctx = {}) {
|
|
|
4631
4932
|
validateIdentity(v);
|
|
4632
4933
|
validateOptionMaps(v);
|
|
4633
4934
|
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
4634
|
-
|
|
4935
|
+
const visSim = readVisibilitySimOpts(ctx);
|
|
4936
|
+
validateVisibility(v, visSim);
|
|
4635
4937
|
applyPolicies(
|
|
4636
4938
|
v.errors,
|
|
4637
4939
|
v.props,
|
|
@@ -4667,11 +4969,21 @@ var BuilderImpl = class {
|
|
|
4667
4969
|
this.optionOwnerById = /* @__PURE__ */ new Map();
|
|
4668
4970
|
this.history = [];
|
|
4669
4971
|
this.future = [];
|
|
4972
|
+
this._nodemap = null;
|
|
4670
4973
|
var _a;
|
|
4671
4974
|
this.options = { ...opts };
|
|
4672
4975
|
this.historyLimit = (_a = opts.historyLimit) != null ? _a : 50;
|
|
4673
4976
|
}
|
|
4674
4977
|
/* ───── lifecycle ─────────────────────────────────────────────────────── */
|
|
4978
|
+
isTagId(id) {
|
|
4979
|
+
return this.tagById.has(id);
|
|
4980
|
+
}
|
|
4981
|
+
isFieldId(id) {
|
|
4982
|
+
return this.fieldById.has(id);
|
|
4983
|
+
}
|
|
4984
|
+
isOptionId(id) {
|
|
4985
|
+
return this.optionOwnerById.has(id);
|
|
4986
|
+
}
|
|
4675
4987
|
load(raw) {
|
|
4676
4988
|
const next = normalise(raw, {
|
|
4677
4989
|
defaultPricingRole: "base",
|
|
@@ -4891,129 +5203,16 @@ var BuilderImpl = class {
|
|
|
4891
5203
|
return validate(this.props, this.options);
|
|
4892
5204
|
}
|
|
4893
5205
|
visibleFields(tagId, selectedKeys) {
|
|
4894
|
-
var _a
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
let cur = tag;
|
|
4905
|
-
let d = 0;
|
|
4906
|
-
while (cur && !guard.has(cur.id)) {
|
|
4907
|
-
lineageDepth.set(cur.id, d++);
|
|
4908
|
-
guard.add(cur.id);
|
|
4909
|
-
const parentId = cur.bind_id;
|
|
4910
|
-
cur = parentId ? tagById.get(parentId) : void 0;
|
|
4911
|
-
}
|
|
4912
|
-
}
|
|
4913
|
-
const isTagInLineage = (id) => lineageDepth.has(id);
|
|
4914
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
4915
|
-
const optionOwnerFieldId = /* @__PURE__ */ new Map();
|
|
4916
|
-
for (const f of fields) {
|
|
4917
|
-
for (const o of (_c = f.options) != null ? _c : []) optionOwnerFieldId.set(o.id, f.id);
|
|
4918
|
-
}
|
|
4919
|
-
const ownerDepthForField = (f) => {
|
|
4920
|
-
const b = f.bind_id;
|
|
4921
|
-
if (!b) return void 0;
|
|
4922
|
-
if (typeof b === "string") return lineageDepth.get(b);
|
|
4923
|
-
let best = void 0;
|
|
4924
|
-
for (const id of b) {
|
|
4925
|
-
const d = lineageDepth.get(id);
|
|
4926
|
-
if (d == null) continue;
|
|
4927
|
-
if (best == null || d < best) best = d;
|
|
4928
|
-
}
|
|
4929
|
-
return best;
|
|
4930
|
-
};
|
|
4931
|
-
const ownerDepthForTrigger = (triggerId) => {
|
|
4932
|
-
if (triggerId.startsWith("o:")) {
|
|
4933
|
-
const fid = optionOwnerFieldId.get(triggerId);
|
|
4934
|
-
if (!fid) return void 0;
|
|
4935
|
-
const f2 = fieldById.get(fid);
|
|
4936
|
-
if (!f2) return void 0;
|
|
4937
|
-
return ownerDepthForField(f2);
|
|
4938
|
-
}
|
|
4939
|
-
const f = fieldById.get(triggerId);
|
|
4940
|
-
if (!f || f.button !== true) return void 0;
|
|
4941
|
-
return ownerDepthForField(f);
|
|
4942
|
-
};
|
|
4943
|
-
const tagInclude = new Set((_d = tag.includes) != null ? _d : []);
|
|
4944
|
-
const tagExclude = new Set((_e = tag.excludes) != null ? _e : []);
|
|
4945
|
-
const selected = new Set(
|
|
4946
|
-
(_f = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _f : []
|
|
4947
|
-
);
|
|
4948
|
-
const incMap = (_g = props.includes_for_buttons) != null ? _g : {};
|
|
4949
|
-
const excMap = (_h = props.excludes_for_buttons) != null ? _h : {};
|
|
4950
|
-
const relevantTriggersInOrder = [];
|
|
4951
|
-
for (const key of selected) {
|
|
4952
|
-
const d = ownerDepthForTrigger(key);
|
|
4953
|
-
if (d == null) continue;
|
|
4954
|
-
relevantTriggersInOrder.push(key);
|
|
4955
|
-
}
|
|
4956
|
-
const visible = /* @__PURE__ */ new Set();
|
|
4957
|
-
const isBoundToLineage = (f) => {
|
|
4958
|
-
const b = f.bind_id;
|
|
4959
|
-
if (!b) return false;
|
|
4960
|
-
if (typeof b === "string") return isTagInLineage(b);
|
|
4961
|
-
for (const id of b) if (isTagInLineage(id)) return true;
|
|
4962
|
-
return false;
|
|
4963
|
-
};
|
|
4964
|
-
for (const f of fields) {
|
|
4965
|
-
if (isBoundToLineage(f)) visible.add(f.id);
|
|
4966
|
-
if (tagInclude.has(f.id)) visible.add(f.id);
|
|
4967
|
-
}
|
|
4968
|
-
for (const id of tagExclude) visible.delete(id);
|
|
4969
|
-
const decide = /* @__PURE__ */ new Map();
|
|
4970
|
-
const applyDecision = (fieldId, next) => {
|
|
4971
|
-
const prev = decide.get(fieldId);
|
|
4972
|
-
if (!prev) {
|
|
4973
|
-
decide.set(fieldId, next);
|
|
4974
|
-
return;
|
|
4975
|
-
}
|
|
4976
|
-
if (next.depth < prev.depth) {
|
|
4977
|
-
decide.set(fieldId, next);
|
|
4978
|
-
return;
|
|
4979
|
-
}
|
|
4980
|
-
if (next.depth > prev.depth) return;
|
|
4981
|
-
if (prev.kind === "include" && next.kind === "exclude") {
|
|
4982
|
-
decide.set(fieldId, next);
|
|
4983
|
-
}
|
|
4984
|
-
};
|
|
4985
|
-
const revealedOrder = [];
|
|
4986
|
-
const revealedSeen = /* @__PURE__ */ new Set();
|
|
4987
|
-
for (const triggerId of relevantTriggersInOrder) {
|
|
4988
|
-
const depth = ownerDepthForTrigger(triggerId);
|
|
4989
|
-
if (depth == null) continue;
|
|
4990
|
-
for (const id of (_i = incMap[triggerId]) != null ? _i : []) {
|
|
4991
|
-
applyDecision(id, { depth, kind: "include" });
|
|
4992
|
-
if (!revealedSeen.has(id)) {
|
|
4993
|
-
revealedSeen.add(id);
|
|
4994
|
-
revealedOrder.push(id);
|
|
4995
|
-
}
|
|
4996
|
-
}
|
|
4997
|
-
for (const id of (_j = excMap[triggerId]) != null ? _j : []) {
|
|
4998
|
-
applyDecision(id, { depth, kind: "exclude" });
|
|
4999
|
-
}
|
|
5000
|
-
}
|
|
5001
|
-
for (const [fid, d] of decide) {
|
|
5002
|
-
if (d.kind === "include") visible.add(fid);
|
|
5003
|
-
else visible.delete(fid);
|
|
5004
|
-
}
|
|
5005
|
-
const base = fields.filter((f) => visible.has(f.id)).map((f) => f.id);
|
|
5006
|
-
const order = (_k = props.order_for_tags) == null ? void 0 : _k[tagId];
|
|
5007
|
-
if (order && order.length) {
|
|
5008
|
-
const ordered = order.filter((fid) => visible.has(fid));
|
|
5009
|
-
const orderedSet = new Set(ordered);
|
|
5010
|
-
const rest2 = base.filter((fid) => !orderedSet.has(fid));
|
|
5011
|
-
return [...ordered, ...rest2];
|
|
5012
|
-
}
|
|
5013
|
-
const promoted = revealedOrder.filter((fid) => visible.has(fid));
|
|
5014
|
-
const promotedSet = new Set(promoted);
|
|
5015
|
-
const rest = base.filter((fid) => !promotedSet.has(fid));
|
|
5016
|
-
return [...promoted, ...rest];
|
|
5206
|
+
var _a;
|
|
5207
|
+
return visibleFieldIdsUnder(this.props, tagId, {
|
|
5208
|
+
selectedKeys: new Set(
|
|
5209
|
+
(_a = selectedKeys != null ? selectedKeys : this.options.selectedOptionKeys) != null ? _a : []
|
|
5210
|
+
)
|
|
5211
|
+
});
|
|
5212
|
+
}
|
|
5213
|
+
getNodeMap() {
|
|
5214
|
+
if (!this._nodemap) this._nodemap = buildNodeMap(this.getProps());
|
|
5215
|
+
return this._nodemap;
|
|
5017
5216
|
}
|
|
5018
5217
|
/* ───── history ─────────────────────────────────────────────────────── */
|
|
5019
5218
|
undo() {
|
|
@@ -5037,6 +5236,7 @@ var BuilderImpl = class {
|
|
|
5037
5236
|
this.tagById.clear();
|
|
5038
5237
|
this.fieldById.clear();
|
|
5039
5238
|
this.optionOwnerById.clear();
|
|
5239
|
+
this._nodemap = null;
|
|
5040
5240
|
for (const t of this.props.filters) this.tagById.set(t.id, t);
|
|
5041
5241
|
for (const f of this.props.fields) {
|
|
5042
5242
|
this.fieldById.set(f.id, f);
|
|
@@ -5264,6 +5464,7 @@ var toBindList = (b) => {
|
|
|
5264
5464
|
function createNodeIndex(builder) {
|
|
5265
5465
|
var _a, _b, _c, _d;
|
|
5266
5466
|
const props = builder.getProps();
|
|
5467
|
+
const nodeMap = builder.getNodeMap();
|
|
5267
5468
|
const tags = (_a = props.filters) != null ? _a : [];
|
|
5268
5469
|
const fields = (_b = props.fields) != null ? _b : [];
|
|
5269
5470
|
const tagById = new Map(tags.map((t) => [t.id, t]));
|
|
@@ -5467,7 +5668,9 @@ function createNodeIndex(builder) {
|
|
|
5467
5668
|
return parentById.get(id) === tid;
|
|
5468
5669
|
},
|
|
5469
5670
|
getDescendant(descendantId) {
|
|
5470
|
-
return this.getDescendants().find(
|
|
5671
|
+
return this.getDescendants().find(
|
|
5672
|
+
(item) => item.id == descendantId
|
|
5673
|
+
);
|
|
5471
5674
|
},
|
|
5472
5675
|
getDescendants() {
|
|
5473
5676
|
const results = [];
|
|
@@ -5476,7 +5679,9 @@ function createNodeIndex(builder) {
|
|
|
5476
5679
|
const node2 = getField(fieldId);
|
|
5477
5680
|
if (!node2) continue;
|
|
5478
5681
|
const explicit = includes.has(fieldId) || isFieldBoundDirectToTag(fieldId, id);
|
|
5479
|
-
results.push(
|
|
5682
|
+
results.push(
|
|
5683
|
+
explicit ? node2 : { ...node2, isInherited: true }
|
|
5684
|
+
);
|
|
5480
5685
|
}
|
|
5481
5686
|
return Object.freeze(results);
|
|
5482
5687
|
}
|
|
@@ -5525,7 +5730,9 @@ function createNodeIndex(builder) {
|
|
|
5525
5730
|
return false;
|
|
5526
5731
|
},
|
|
5527
5732
|
getDescendant(descendantId, context) {
|
|
5528
|
-
return this.getDescendants(context).find(
|
|
5733
|
+
return this.getDescendants(context).find(
|
|
5734
|
+
(item) => item.id == descendantId
|
|
5735
|
+
);
|
|
5529
5736
|
},
|
|
5530
5737
|
getDescendants(tagId) {
|
|
5531
5738
|
return resolveDescendants(id, includes, tagId, !isButton);
|
|
@@ -5567,7 +5774,9 @@ function createNodeIndex(builder) {
|
|
|
5567
5774
|
return owner.isBoundTo(tagId);
|
|
5568
5775
|
},
|
|
5569
5776
|
getDescendant(descendantId, context) {
|
|
5570
|
-
return this.getDescendants(context).find(
|
|
5777
|
+
return this.getDescendants(context).find(
|
|
5778
|
+
(item) => item.id == descendantId
|
|
5779
|
+
);
|
|
5571
5780
|
},
|
|
5572
5781
|
getDescendants(tagId) {
|
|
5573
5782
|
return resolveDescendants(id, includes, tagId);
|
|
@@ -5578,7 +5787,7 @@ function createNodeIndex(builder) {
|
|
|
5578
5787
|
return node;
|
|
5579
5788
|
};
|
|
5580
5789
|
const getNode = (input) => {
|
|
5581
|
-
var _a2, _b2, _c2, _d2, _e
|
|
5790
|
+
var _a2, _b2, _c2, _d2, _e;
|
|
5582
5791
|
if (typeof input !== "string") {
|
|
5583
5792
|
if ("bind_id" in input && !("type" in input))
|
|
5584
5793
|
return (_a2 = getTag(input.id)) != null ? _a2 : mkUnknown(input.id);
|
|
@@ -5588,11 +5797,7 @@ function createNodeIndex(builder) {
|
|
|
5588
5797
|
}
|
|
5589
5798
|
const cached = nodeCache.get(input);
|
|
5590
5799
|
if (cached) return cached;
|
|
5591
|
-
|
|
5592
|
-
if (id.startsWith("t:")) return (_d2 = getTag(id)) != null ? _d2 : mkUnknown(id);
|
|
5593
|
-
if (id.startsWith("f:")) return (_e = getField(id)) != null ? _e : mkUnknown(id);
|
|
5594
|
-
if (id.startsWith("o:")) return (_f = getOption(id)) != null ? _f : mkUnknown(id);
|
|
5595
|
-
return (_i = (_h = (_g = getTag(id)) != null ? _g : getField(id)) != null ? _h : getOption(id)) != null ? _i : mkUnknown(id);
|
|
5800
|
+
return (_e = (_d2 = nodeMap.get(input)) == null ? void 0 : _d2.node) != null ? _e : mkUnknown(input);
|
|
5596
5801
|
};
|
|
5597
5802
|
const mkUnknown = (id) => {
|
|
5598
5803
|
const u = {
|
|
@@ -5652,9 +5857,6 @@ function rateOk(svcMap, candidate, primary, policy) {
|
|
|
5652
5857
|
|
|
5653
5858
|
// src/react/canvas/editor.ts
|
|
5654
5859
|
var MAX_LIMIT = 100;
|
|
5655
|
-
var isTagId = (id) => id.startsWith("t:");
|
|
5656
|
-
var isFieldId = (id) => id.startsWith("f:");
|
|
5657
|
-
var isOptionId = (id) => id.startsWith("o:");
|
|
5658
5860
|
function ownerOfOption(props, optionId) {
|
|
5659
5861
|
var _a, _b;
|
|
5660
5862
|
for (const f of (_a = props.fields) != null ? _a : []) {
|
|
@@ -5696,6 +5898,15 @@ var Editor = class {
|
|
|
5696
5898
|
this.pushHistory(this.makeSnapshot("init"));
|
|
5697
5899
|
}
|
|
5698
5900
|
/* ───────────────────────── Public API ───────────────────────── */
|
|
5901
|
+
isTagId(id) {
|
|
5902
|
+
return this.builder.isTagId(id);
|
|
5903
|
+
}
|
|
5904
|
+
isFieldId(id) {
|
|
5905
|
+
return this.builder.isFieldId(id);
|
|
5906
|
+
}
|
|
5907
|
+
isOptionId(id) {
|
|
5908
|
+
return this.builder.isOptionId(id);
|
|
5909
|
+
}
|
|
5699
5910
|
getProps() {
|
|
5700
5911
|
return this.builder.getProps();
|
|
5701
5912
|
}
|
|
@@ -5791,7 +6002,7 @@ var Editor = class {
|
|
|
5791
6002
|
name: "reLabel",
|
|
5792
6003
|
do: () => this.patchProps((p) => {
|
|
5793
6004
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
5794
|
-
if (isTagId(id)) {
|
|
6005
|
+
if (this.isTagId(id)) {
|
|
5795
6006
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
5796
6007
|
if (!t) return;
|
|
5797
6008
|
if (((_b = t.label) != null ? _b : "") === label) return;
|
|
@@ -5799,7 +6010,7 @@ var Editor = class {
|
|
|
5799
6010
|
this.api.refreshGraph();
|
|
5800
6011
|
return;
|
|
5801
6012
|
}
|
|
5802
|
-
if (isOptionId(id)) {
|
|
6013
|
+
if (this.isOptionId(id)) {
|
|
5803
6014
|
const own = ownerOfOption(p, id);
|
|
5804
6015
|
if (!own) return;
|
|
5805
6016
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6100,7 +6311,7 @@ var Editor = class {
|
|
|
6100
6311
|
* - Option: use placeOption() instead
|
|
6101
6312
|
*/
|
|
6102
6313
|
placeNode(id, opts) {
|
|
6103
|
-
if (isTagId(id)) {
|
|
6314
|
+
if (this.isTagId(id)) {
|
|
6104
6315
|
this.exec({
|
|
6105
6316
|
name: "placeTag",
|
|
6106
6317
|
do: () => this.patchProps((p) => {
|
|
@@ -6147,7 +6358,7 @@ var Editor = class {
|
|
|
6147
6358
|
}),
|
|
6148
6359
|
undo: () => this.api.undo()
|
|
6149
6360
|
});
|
|
6150
|
-
} else if (isFieldId(id)) {
|
|
6361
|
+
} else if (this.isFieldId(id)) {
|
|
6151
6362
|
if (!opts.scopeTagId)
|
|
6152
6363
|
throw new Error("placeNode(field): scopeTagId is required");
|
|
6153
6364
|
const fieldId = id;
|
|
@@ -6174,14 +6385,14 @@ var Editor = class {
|
|
|
6174
6385
|
}),
|
|
6175
6386
|
undo: () => this.api.undo()
|
|
6176
6387
|
});
|
|
6177
|
-
} else if (isOptionId(id)) {
|
|
6388
|
+
} else if (this.isOptionId(id)) {
|
|
6178
6389
|
this.placeOption(id, opts);
|
|
6179
6390
|
} else {
|
|
6180
6391
|
throw new Error("placeNode: unknown id prefix");
|
|
6181
6392
|
}
|
|
6182
6393
|
}
|
|
6183
6394
|
placeOption(optionId, opts) {
|
|
6184
|
-
if (!isOptionId(optionId))
|
|
6395
|
+
if (!this.isOptionId(optionId))
|
|
6185
6396
|
throw new Error('placeOption: optionId must start with "o:"');
|
|
6186
6397
|
this.exec({
|
|
6187
6398
|
name: "placeOption",
|
|
@@ -6238,7 +6449,7 @@ var Editor = class {
|
|
|
6238
6449
|
return id;
|
|
6239
6450
|
}
|
|
6240
6451
|
updateOption(optionId, patch) {
|
|
6241
|
-
if (!isOptionId(optionId))
|
|
6452
|
+
if (!this.isOptionId(optionId))
|
|
6242
6453
|
throw new Error('updateOption: optionId must start with "o:"');
|
|
6243
6454
|
this.exec({
|
|
6244
6455
|
name: "updateOption",
|
|
@@ -6257,7 +6468,7 @@ var Editor = class {
|
|
|
6257
6468
|
});
|
|
6258
6469
|
}
|
|
6259
6470
|
removeOption(optionId) {
|
|
6260
|
-
if (!isOptionId(optionId))
|
|
6471
|
+
if (!this.isOptionId(optionId))
|
|
6261
6472
|
throw new Error('removeOption: optionId must start with "o:"');
|
|
6262
6473
|
this.exec({
|
|
6263
6474
|
name: "removeOption",
|
|
@@ -6288,17 +6499,17 @@ var Editor = class {
|
|
|
6288
6499
|
name: "editLabel",
|
|
6289
6500
|
do: () => this.patchProps((p) => {
|
|
6290
6501
|
var _a, _b, _c, _d;
|
|
6291
|
-
if (isTagId(id)) {
|
|
6502
|
+
if (this.isTagId(id)) {
|
|
6292
6503
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6293
6504
|
if (t) t.label = next;
|
|
6294
6505
|
return;
|
|
6295
6506
|
}
|
|
6296
|
-
if (isFieldId(id)) {
|
|
6507
|
+
if (this.isFieldId(id)) {
|
|
6297
6508
|
const f = ((_b = p.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6298
6509
|
if (f) f.label = next;
|
|
6299
6510
|
return;
|
|
6300
6511
|
}
|
|
6301
|
-
if (isOptionId(id)) {
|
|
6512
|
+
if (this.isOptionId(id)) {
|
|
6302
6513
|
const own = ownerOfOption(p, id);
|
|
6303
6514
|
if (!own) return;
|
|
6304
6515
|
const f = ((_c = p.fields) != null ? _c : []).find(
|
|
@@ -6337,7 +6548,7 @@ var Editor = class {
|
|
|
6337
6548
|
const validId = hasSidKey && typeof input.service_id === "number" && Number.isFinite(input.service_id);
|
|
6338
6549
|
const sid = validId ? Number(input.service_id) : void 0;
|
|
6339
6550
|
const nextRole = input.pricing_role;
|
|
6340
|
-
if (isTagId(id)) {
|
|
6551
|
+
if (this.isTagId(id)) {
|
|
6341
6552
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6342
6553
|
if (!t) return;
|
|
6343
6554
|
if (hasSidKey) {
|
|
@@ -6346,7 +6557,7 @@ var Editor = class {
|
|
|
6346
6557
|
}
|
|
6347
6558
|
return;
|
|
6348
6559
|
}
|
|
6349
|
-
if (isOptionId(id)) {
|
|
6560
|
+
if (this.isOptionId(id)) {
|
|
6350
6561
|
const own = ownerOfOption(p, id);
|
|
6351
6562
|
if (!own) return;
|
|
6352
6563
|
const f2 = ((_b = p.fields) != null ? _b : []).find(
|
|
@@ -6553,7 +6764,7 @@ var Editor = class {
|
|
|
6553
6764
|
});
|
|
6554
6765
|
}
|
|
6555
6766
|
remove(id) {
|
|
6556
|
-
if (isTagId(id)) {
|
|
6767
|
+
if (this.isTagId(id)) {
|
|
6557
6768
|
this.exec({
|
|
6558
6769
|
name: "removeTag",
|
|
6559
6770
|
do: () => this.patchProps((p) => {
|
|
@@ -6593,7 +6804,7 @@ var Editor = class {
|
|
|
6593
6804
|
});
|
|
6594
6805
|
return;
|
|
6595
6806
|
}
|
|
6596
|
-
if (isFieldId(id)) {
|
|
6807
|
+
if (this.isFieldId(id)) {
|
|
6597
6808
|
this.exec({
|
|
6598
6809
|
name: "removeField",
|
|
6599
6810
|
do: () => this.patchProps((p) => {
|
|
@@ -6629,7 +6840,7 @@ var Editor = class {
|
|
|
6629
6840
|
});
|
|
6630
6841
|
return;
|
|
6631
6842
|
}
|
|
6632
|
-
if (isOptionId(id)) {
|
|
6843
|
+
if (this.isOptionId(id)) {
|
|
6633
6844
|
this.removeOption(id);
|
|
6634
6845
|
return;
|
|
6635
6846
|
}
|
|
@@ -6638,7 +6849,7 @@ var Editor = class {
|
|
|
6638
6849
|
getNode(id) {
|
|
6639
6850
|
var _a, _b, _c, _d;
|
|
6640
6851
|
const props = this.builder.getProps();
|
|
6641
|
-
if (isTagId(id)) {
|
|
6852
|
+
if (this.isTagId(id)) {
|
|
6642
6853
|
const t = ((_a = props.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6643
6854
|
return {
|
|
6644
6855
|
kind: "tag",
|
|
@@ -6646,12 +6857,12 @@ var Editor = class {
|
|
|
6646
6857
|
owners: { parentTagId: t == null ? void 0 : t.bind_id }
|
|
6647
6858
|
};
|
|
6648
6859
|
}
|
|
6649
|
-
if (isFieldId(id)) {
|
|
6860
|
+
if (this.isFieldId(id)) {
|
|
6650
6861
|
const f = ((_b = props.fields) != null ? _b : []).find((x) => x.id === id);
|
|
6651
6862
|
const bind = Array.isArray(f == null ? void 0 : f.bind_id) ? f.bind_id : (f == null ? void 0 : f.bind_id) ? [f.bind_id] : [];
|
|
6652
6863
|
return { kind: "field", data: f, owners: { bindTagIds: bind } };
|
|
6653
6864
|
}
|
|
6654
|
-
if (isOptionId(id)) {
|
|
6865
|
+
if (this.isOptionId(id)) {
|
|
6655
6866
|
const own = ownerOfOption(props, id);
|
|
6656
6867
|
const f = own ? ((_c = props.fields) != null ? _c : []).find((x) => x.id === own.fieldId) : void 0;
|
|
6657
6868
|
const o = (_d = f == null ? void 0 : f.options) == null ? void 0 : _d.find((x) => x.id === id);
|
|
@@ -6729,7 +6940,7 @@ var Editor = class {
|
|
|
6729
6940
|
if (receiverId === targetId) return true;
|
|
6730
6941
|
const getDirectRelations = (id) => {
|
|
6731
6942
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
6732
|
-
if (isTagId(id)) {
|
|
6943
|
+
if (this.isTagId(id)) {
|
|
6733
6944
|
const t = ((_a = p.filters) != null ? _a : []).find((x) => x.id === id);
|
|
6734
6945
|
return [...(_b = t == null ? void 0 : t.includes) != null ? _b : [], ...(_c = t == null ? void 0 : t.excludes) != null ? _c : []];
|
|
6735
6946
|
}
|
|
@@ -6949,7 +7160,7 @@ var Editor = class {
|
|
|
6949
7160
|
do: () => this.patchProps((p) => {
|
|
6950
7161
|
var _a, _b, _c, _d, _e;
|
|
6951
7162
|
if (kind === "bind") {
|
|
6952
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7163
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
6953
7164
|
if (this.wouldCreateTagCycle(p, fromId, toId2)) {
|
|
6954
7165
|
throw new Error(
|
|
6955
7166
|
`bind would create a cycle: ${fromId} \u2192 ${toId2}`
|
|
@@ -6961,9 +7172,9 @@ var Editor = class {
|
|
|
6961
7172
|
if (child) child.bind_id = fromId;
|
|
6962
7173
|
return;
|
|
6963
7174
|
}
|
|
6964
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
6965
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
6966
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7175
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7176
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7177
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
6967
7178
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
6968
7179
|
(x) => x.id === fieldId
|
|
6969
7180
|
);
|
|
@@ -6987,7 +7198,7 @@ var Editor = class {
|
|
|
6987
7198
|
}
|
|
6988
7199
|
if (kind === "include" || kind === "exclude") {
|
|
6989
7200
|
const key = kind === "include" ? "includes" : "excludes";
|
|
6990
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7201
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
6991
7202
|
const t = ((_c = p.filters) != null ? _c : []).find(
|
|
6992
7203
|
(x) => x.id === fromId
|
|
6993
7204
|
);
|
|
@@ -6996,7 +7207,7 @@ var Editor = class {
|
|
|
6996
7207
|
if (!arr.includes(toId2)) arr.push(toId2);
|
|
6997
7208
|
return;
|
|
6998
7209
|
}
|
|
6999
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7210
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
7000
7211
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
7001
7212
|
const maps = p[mapKey];
|
|
7002
7213
|
const next = { ...maps != null ? maps : {} };
|
|
@@ -7064,16 +7275,16 @@ var Editor = class {
|
|
|
7064
7275
|
do: () => this.patchProps((p) => {
|
|
7065
7276
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7066
7277
|
if (kind === "bind") {
|
|
7067
|
-
if (isTagId(fromId) && isTagId(toId2)) {
|
|
7278
|
+
if (this.isTagId(fromId) && this.isTagId(toId2)) {
|
|
7068
7279
|
const child = ((_a = p.filters) != null ? _a : []).find(
|
|
7069
7280
|
(t) => t.id === toId2
|
|
7070
7281
|
);
|
|
7071
7282
|
if ((child == null ? void 0 : child.bind_id) === fromId) delete child.bind_id;
|
|
7072
7283
|
return;
|
|
7073
7284
|
}
|
|
7074
|
-
if (isTagId(fromId) && isFieldId(toId2) || isFieldId(fromId) && isTagId(toId2)) {
|
|
7075
|
-
const fieldId = isFieldId(toId2) ? toId2 : fromId;
|
|
7076
|
-
const tagId = isTagId(fromId) ? fromId : toId2;
|
|
7285
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2) || this.isFieldId(fromId) && this.isTagId(toId2)) {
|
|
7286
|
+
const fieldId = this.isFieldId(toId2) ? toId2 : fromId;
|
|
7287
|
+
const tagId = this.isTagId(fromId) ? fromId : toId2;
|
|
7077
7288
|
const f = ((_b = p.fields) != null ? _b : []).find(
|
|
7078
7289
|
(x) => x.id === fieldId
|
|
7079
7290
|
);
|
|
@@ -7094,7 +7305,7 @@ var Editor = class {
|
|
|
7094
7305
|
}
|
|
7095
7306
|
if (kind === "include" || kind === "exclude") {
|
|
7096
7307
|
const key = kind === "include" ? "includes" : "excludes";
|
|
7097
|
-
if (isTagId(fromId) && isFieldId(toId2)) {
|
|
7308
|
+
if (this.isTagId(fromId) && this.isFieldId(toId2)) {
|
|
7098
7309
|
const t = ((_d = p.filters) != null ? _d : []).find(
|
|
7099
7310
|
(x) => x.id === fromId
|
|
7100
7311
|
);
|
|
@@ -7103,7 +7314,7 @@ var Editor = class {
|
|
|
7103
7314
|
if (!((_f = t[key]) == null ? void 0 : _f.length)) delete t[key];
|
|
7104
7315
|
return;
|
|
7105
7316
|
}
|
|
7106
|
-
if (isOptionId(fromId) && isFieldId(toId2)) {
|
|
7317
|
+
if (this.isOptionId(fromId) && this.isFieldId(toId2)) {
|
|
7107
7318
|
const mapKey = kind === "include" ? "includes_for_options" : "excludes_for_options";
|
|
7108
7319
|
const maps = p[mapKey];
|
|
7109
7320
|
if (!maps) return;
|
|
@@ -7570,8 +7781,6 @@ function toStrSet(v) {
|
|
|
7570
7781
|
}
|
|
7571
7782
|
|
|
7572
7783
|
// src/react/canvas/selection.ts
|
|
7573
|
-
var isTagId2 = (id) => typeof id === "string" && id.startsWith("t:");
|
|
7574
|
-
var isOptionId2 = (id) => typeof id === "string" && id.startsWith("o:");
|
|
7575
7784
|
var Selection = class {
|
|
7576
7785
|
constructor(builder, opts) {
|
|
7577
7786
|
this.builder = builder;
|
|
@@ -7643,7 +7852,7 @@ var Selection = class {
|
|
|
7643
7852
|
var _a;
|
|
7644
7853
|
const props = this.builder.getProps();
|
|
7645
7854
|
if (((_a = this.opts.env) != null ? _a : "client") === "workspace") {
|
|
7646
|
-
const tagIds = Array.from(this.set).filter(
|
|
7855
|
+
const tagIds = Array.from(this.set).filter(this.builder.isTagId.bind(this.builder));
|
|
7647
7856
|
if (tagIds.length > 1) {
|
|
7648
7857
|
return { kind: "multi", groups: Array.from(this.set) };
|
|
7649
7858
|
}
|
|
@@ -7676,7 +7885,7 @@ var Selection = class {
|
|
|
7676
7885
|
this.currentTagId = Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7677
7886
|
return;
|
|
7678
7887
|
}
|
|
7679
|
-
if (
|
|
7888
|
+
if (this.builder.isOptionId(id)) {
|
|
7680
7889
|
const host = fields.find(
|
|
7681
7890
|
(x) => {
|
|
7682
7891
|
var _a2;
|
|
@@ -7700,7 +7909,7 @@ var Selection = class {
|
|
|
7700
7909
|
resolveTagContextId(props) {
|
|
7701
7910
|
var _a;
|
|
7702
7911
|
if (this.currentTagId) return this.currentTagId;
|
|
7703
|
-
for (const id of this.set) if (
|
|
7912
|
+
for (const id of this.set) if (this.builder.isTagId(id)) return id;
|
|
7704
7913
|
const fields = (_a = props.fields) != null ? _a : [];
|
|
7705
7914
|
for (const id of this.set) {
|
|
7706
7915
|
const f = fields.find((x) => x.id === id);
|
|
@@ -7708,7 +7917,7 @@ var Selection = class {
|
|
|
7708
7917
|
return Array.isArray(f.bind_id) ? f.bind_id[0] : f.bind_id;
|
|
7709
7918
|
}
|
|
7710
7919
|
for (const id of this.set) {
|
|
7711
|
-
if (
|
|
7920
|
+
if (this.builder.isOptionId(id)) {
|
|
7712
7921
|
const host = fields.find(
|
|
7713
7922
|
(x) => {
|
|
7714
7923
|
var _a2;
|
|
@@ -7829,7 +8038,7 @@ var Selection = class {
|
|
|
7829
8038
|
}
|
|
7830
8039
|
findOptionById(fields, selId) {
|
|
7831
8040
|
var _a, _b;
|
|
7832
|
-
if (
|
|
8041
|
+
if (this.builder.isOptionId(selId)) {
|
|
7833
8042
|
for (const f of fields) {
|
|
7834
8043
|
const o = (_a = f.options) == null ? void 0 : _a.find((x) => x.id === selId);
|
|
7835
8044
|
if (o) return o;
|
|
@@ -8251,8 +8460,8 @@ function useCanvasOwned(initialProps, canvasOpts, builderOpts) {
|
|
|
8251
8460
|
// src/react/workspace/context/hooks/use-canvas.ts
|
|
8252
8461
|
var React16 = __toESM(require("react"), 1);
|
|
8253
8462
|
var import_react4 = require("react");
|
|
8254
|
-
var
|
|
8255
|
-
var
|
|
8463
|
+
var isTagId = (id) => id.startsWith("t:");
|
|
8464
|
+
var isOptionId = (id) => id.startsWith("o:");
|
|
8256
8465
|
function deriveSelectionInfo(props, ids) {
|
|
8257
8466
|
var _a, _b, _c, _d;
|
|
8258
8467
|
const tags = [];
|
|
@@ -8261,11 +8470,11 @@ function deriveSelectionInfo(props, ids) {
|
|
|
8261
8470
|
const fieldById = /* @__PURE__ */ new Map();
|
|
8262
8471
|
for (const f of (_a = props.fields) != null ? _a : []) fieldById.set(f.id, f);
|
|
8263
8472
|
for (const id of ids) {
|
|
8264
|
-
if (
|
|
8473
|
+
if (isTagId(id)) {
|
|
8265
8474
|
tags.push(id);
|
|
8266
8475
|
continue;
|
|
8267
8476
|
}
|
|
8268
|
-
if (
|
|
8477
|
+
if (isOptionId(id)) {
|
|
8269
8478
|
options.push(id);
|
|
8270
8479
|
continue;
|
|
8271
8480
|
}
|