@timeax/digital-service-engine 0.2.7 → 0.2.9
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 +1688 -1218
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +21 -1
- package/dist/core/index.d.ts +21 -1
- package/dist/core/index.js +1686 -1218
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +586 -376
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +8 -0
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.js +586 -376
- package/dist/react/index.js.map +1 -1
- package/dist/workspace/index.cjs +595 -389
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +8 -0
- package/dist/workspace/index.d.ts +8 -0
- package/dist/workspace/index.js +595 -389
- package/dist/workspace/index.js.map +1 -1
- package/package.json +1 -1
package/dist/workspace/index.cjs
CHANGED
|
@@ -4121,13 +4121,7 @@ function resolveRootTags(tags) {
|
|
|
4121
4121
|
const roots = tags.filter((t) => !t.bind_id);
|
|
4122
4122
|
return roots.length ? roots : tags.slice(0, 1);
|
|
4123
4123
|
}
|
|
4124
|
-
function
|
|
4125
|
-
var _a, _b, _c, _d, _e, _f;
|
|
4126
|
-
const inc = (_a = v.props.includes_for_buttons) != null ? _a : {};
|
|
4127
|
-
const exc = (_b = v.props.excludes_for_buttons) != null ? _b : {};
|
|
4128
|
-
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;
|
|
4129
|
-
}
|
|
4130
|
-
function collectSelectableTriggersInContext(v, tagId, selectedKeys, onlyEffectful) {
|
|
4124
|
+
function collectSelectableTriggersInContext(v, tagId, selectedKeys, effectfulKeys) {
|
|
4131
4125
|
var _a;
|
|
4132
4126
|
const visible = visibleFieldsUnder(v.props, tagId, {
|
|
4133
4127
|
selectedKeys
|
|
@@ -4136,11 +4130,11 @@ function collectSelectableTriggersInContext(v, tagId, selectedKeys, onlyEffectfu
|
|
|
4136
4130
|
for (const f of visible) {
|
|
4137
4131
|
if (f.button === true) {
|
|
4138
4132
|
const t = f.id;
|
|
4139
|
-
if (
|
|
4133
|
+
if (effectfulKeys.has(t)) triggers.push(t);
|
|
4140
4134
|
}
|
|
4141
4135
|
for (const o of (_a = f.options) != null ? _a : []) {
|
|
4142
|
-
const t =
|
|
4143
|
-
if (
|
|
4136
|
+
const t = o.id;
|
|
4137
|
+
if (effectfulKeys.has(t)) triggers.push(t);
|
|
4144
4138
|
}
|
|
4145
4139
|
}
|
|
4146
4140
|
triggers.sort();
|
|
@@ -4240,20 +4234,38 @@ function dedupeErrorsInPlace(v, startIndex) {
|
|
|
4240
4234
|
v.errors.splice(startIndex, v.errors.length - startIndex, ...kept);
|
|
4241
4235
|
}
|
|
4242
4236
|
function validateVisibility(v, options = {}) {
|
|
4243
|
-
var _a, _b, _c;
|
|
4237
|
+
var _a, _b, _c, _d, _e;
|
|
4238
|
+
v.simulatedVisibilityContexts = [];
|
|
4244
4239
|
const simulate = options.simulate === true;
|
|
4245
4240
|
if (!simulate) {
|
|
4246
4241
|
runVisibilityRulesOnce(v);
|
|
4242
|
+
for (const tag of v.tags) {
|
|
4243
|
+
v.simulatedVisibilityContexts.push({
|
|
4244
|
+
tagId: tag.id,
|
|
4245
|
+
selectedKeys: Array.from(v.selectedKeys),
|
|
4246
|
+
visibleFieldIds: v.fieldsVisibleUnder(tag.id).map((f) => f.id)
|
|
4247
|
+
});
|
|
4248
|
+
}
|
|
4247
4249
|
return;
|
|
4248
4250
|
}
|
|
4249
4251
|
const maxStates = Math.max(1, (_a = options.maxStates) != null ? _a : 500);
|
|
4250
4252
|
const maxDepth = Math.max(0, (_b = options.maxDepth) != null ? _b : 6);
|
|
4251
4253
|
const onlyEffectful = options.onlyEffectfulTriggers !== false;
|
|
4254
|
+
const effectfulKeys = /* @__PURE__ */ new Set();
|
|
4255
|
+
if (onlyEffectful) {
|
|
4256
|
+
for (const key of Object.keys((_c = v.props.includes_for_buttons) != null ? _c : {})) {
|
|
4257
|
+
effectfulKeys.add(key);
|
|
4258
|
+
}
|
|
4259
|
+
for (const key of Object.keys((_d = v.props.excludes_for_buttons) != null ? _d : {})) {
|
|
4260
|
+
effectfulKeys.add(key);
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4252
4263
|
const roots = resolveRootTags(v.tags);
|
|
4253
4264
|
const rootTags = options.simulateAllRoots ? roots : roots.slice(0, 1);
|
|
4254
|
-
const originalSelected = new Set((
|
|
4265
|
+
const originalSelected = new Set((_e = v.selectedKeys) != null ? _e : []);
|
|
4255
4266
|
const errorsStart = v.errors.length;
|
|
4256
4267
|
const visited = /* @__PURE__ */ new Set();
|
|
4268
|
+
const seenContexts = /* @__PURE__ */ new Set();
|
|
4257
4269
|
const stack = [];
|
|
4258
4270
|
for (const rt of rootTags) {
|
|
4259
4271
|
stack.push({
|
|
@@ -4266,10 +4278,27 @@ function validateVisibility(v, options = {}) {
|
|
|
4266
4278
|
while (stack.length) {
|
|
4267
4279
|
if (validatedStates >= maxStates) break;
|
|
4268
4280
|
const state = stack.pop();
|
|
4269
|
-
const sig = stableKeyOfSelection(state.selected)
|
|
4281
|
+
const sig = `${state.rootTagId}::${stableKeyOfSelection(state.selected)}`;
|
|
4270
4282
|
if (visited.has(sig)) continue;
|
|
4271
4283
|
visited.add(sig);
|
|
4272
4284
|
v.selectedKeys = state.selected;
|
|
4285
|
+
const visibleNow = visibleFieldsUnder(v.props, state.rootTagId, {
|
|
4286
|
+
selectedKeys: state.selected
|
|
4287
|
+
}).map((f) => f.id);
|
|
4288
|
+
const context = {
|
|
4289
|
+
tagId: state.rootTagId,
|
|
4290
|
+
selectedKeys: Array.from(state.selected),
|
|
4291
|
+
visibleFieldIds: visibleNow
|
|
4292
|
+
};
|
|
4293
|
+
const contextKey = [
|
|
4294
|
+
context.tagId,
|
|
4295
|
+
[...context.selectedKeys].sort().join("|"),
|
|
4296
|
+
[...context.visibleFieldIds].sort().join("|")
|
|
4297
|
+
].join("::");
|
|
4298
|
+
if (!seenContexts.has(contextKey)) {
|
|
4299
|
+
seenContexts.add(contextKey);
|
|
4300
|
+
v.simulatedVisibilityContexts.push(context);
|
|
4301
|
+
}
|
|
4273
4302
|
validatedStates++;
|
|
4274
4303
|
runVisibilityRulesOnce(v);
|
|
4275
4304
|
if (state.depth >= maxDepth) continue;
|
|
@@ -4277,7 +4306,7 @@ function validateVisibility(v, options = {}) {
|
|
|
4277
4306
|
v,
|
|
4278
4307
|
state.rootTagId,
|
|
4279
4308
|
state.selected,
|
|
4280
|
-
|
|
4309
|
+
effectfulKeys
|
|
4281
4310
|
);
|
|
4282
4311
|
for (let i = triggers.length - 1; i >= 0; i--) {
|
|
4283
4312
|
const trig = triggers[i];
|
|
@@ -4519,8 +4548,8 @@ function validateOptionMaps(v) {
|
|
|
4519
4548
|
};
|
|
4520
4549
|
}
|
|
4521
4550
|
if (ref.kind === "field") {
|
|
4522
|
-
const
|
|
4523
|
-
if (!
|
|
4551
|
+
const isButton = ref.node.button === true;
|
|
4552
|
+
if (!isButton)
|
|
4524
4553
|
return { ok: false, nodeId: ref.id, affected: [ref.id] };
|
|
4525
4554
|
return { ok: true, nodeId: ref.id, affected: [ref.id] };
|
|
4526
4555
|
}
|
|
@@ -4711,9 +4740,9 @@ function validateServiceVsUserInput(v) {
|
|
|
4711
4740
|
for (const f of v.fields) {
|
|
4712
4741
|
const anySvc = hasAnyServiceOption(f);
|
|
4713
4742
|
const hasName = !!(f.name && f.name.trim());
|
|
4714
|
-
const
|
|
4743
|
+
const isButton = f.button === true;
|
|
4715
4744
|
const hasFieldService = f.service_id !== void 0 && f.service_id !== null;
|
|
4716
|
-
const hasTriggerMap =
|
|
4745
|
+
const hasTriggerMap = isButton && hasButtonTriggerMap(v, f.id);
|
|
4717
4746
|
if (f.type === "custom" && anySvc) {
|
|
4718
4747
|
v.errors.push({
|
|
4719
4748
|
code: "user_input_field_has_service_option",
|
|
@@ -4730,7 +4759,7 @@ function validateServiceVsUserInput(v) {
|
|
|
4730
4759
|
v.errors.push({
|
|
4731
4760
|
code: "service_field_missing_service_id",
|
|
4732
4761
|
severity: "error",
|
|
4733
|
-
message:
|
|
4762
|
+
message: isButton ? `Button field "${f.id}" has no "name", no "service_id", and no includes/excludes trigger map. Add a name, attach a service_id, or configure includes_for_buttons/excludes_for_buttons.` : `Service-backed field "${f.id}" has no "name" and must provide at least one option with a service_id.`,
|
|
4734
4763
|
nodeId: f.id
|
|
4735
4764
|
});
|
|
4736
4765
|
} else {
|
|
@@ -4908,15 +4937,6 @@ function passesRatePolicy(policy, primaryRate, candidateRate) {
|
|
|
4908
4937
|
return candidateRate <= primaryRate * (1 - rp.pct / 100);
|
|
4909
4938
|
}
|
|
4910
4939
|
}
|
|
4911
|
-
function rateOk(svcMap, candidate, primary, policy) {
|
|
4912
|
-
const cand = getServiceCapability(svcMap, candidate);
|
|
4913
|
-
const prim = getServiceCapability(svcMap, primary);
|
|
4914
|
-
if (!cand || !prim) return false;
|
|
4915
|
-
const cRate = toFiniteNumber(cand.rate);
|
|
4916
|
-
const pRate = toFiniteNumber(prim.rate);
|
|
4917
|
-
if (!Number.isFinite(cRate) || !Number.isFinite(pRate)) return false;
|
|
4918
|
-
return passesRatePolicy(policy.ratePolicy, pRate, cRate);
|
|
4919
|
-
}
|
|
4920
4940
|
function getServiceCapabilityEntry(svcMap, candidate) {
|
|
4921
4941
|
if (candidate === void 0 || candidate === null) return void 0;
|
|
4922
4942
|
const direct = svcMap[candidate];
|
|
@@ -5044,6 +5064,324 @@ function validateRates(v) {
|
|
|
5044
5064
|
}
|
|
5045
5065
|
}
|
|
5046
5066
|
|
|
5067
|
+
// src/core/rate-coherence.ts
|
|
5068
|
+
function buildTriggerEffectMap(props) {
|
|
5069
|
+
var _a, _b;
|
|
5070
|
+
const map = /* @__PURE__ */ new Map();
|
|
5071
|
+
const ensure = (key) => {
|
|
5072
|
+
let item = map.get(key);
|
|
5073
|
+
if (!item) {
|
|
5074
|
+
item = { includes: /* @__PURE__ */ new Set(), excludes: /* @__PURE__ */ new Set() };
|
|
5075
|
+
map.set(key, item);
|
|
5076
|
+
}
|
|
5077
|
+
return item;
|
|
5078
|
+
};
|
|
5079
|
+
for (const [key, ids] of Object.entries((_a = props.includes_for_buttons) != null ? _a : {})) {
|
|
5080
|
+
const item = ensure(key);
|
|
5081
|
+
for (const id of ids != null ? ids : []) item.includes.add(id);
|
|
5082
|
+
}
|
|
5083
|
+
for (const [key, ids] of Object.entries((_b = props.excludes_for_buttons) != null ? _b : {})) {
|
|
5084
|
+
const item = ensure(key);
|
|
5085
|
+
for (const id of ids != null ? ids : []) item.excludes.add(id);
|
|
5086
|
+
}
|
|
5087
|
+
return map;
|
|
5088
|
+
}
|
|
5089
|
+
function isRefExcludedBySelectedKeys(ref, selectedKeys, effectMap) {
|
|
5090
|
+
for (const key of selectedKeys) {
|
|
5091
|
+
const effects = effectMap.get(key);
|
|
5092
|
+
if (!effects) continue;
|
|
5093
|
+
if (ref.fieldId && effects.excludes.has(ref.fieldId) || effects.excludes.has(ref.nodeId)) {
|
|
5094
|
+
return true;
|
|
5095
|
+
}
|
|
5096
|
+
}
|
|
5097
|
+
return false;
|
|
5098
|
+
}
|
|
5099
|
+
|
|
5100
|
+
// src/core/validate/steps/rate-coherence.ts
|
|
5101
|
+
function normalizeRole(role, fallback) {
|
|
5102
|
+
return role === "base" || role === "utility" ? role : fallback;
|
|
5103
|
+
}
|
|
5104
|
+
function uniqueStrings(values) {
|
|
5105
|
+
const out = /* @__PURE__ */ new Set();
|
|
5106
|
+
for (const value of values) {
|
|
5107
|
+
if (!value) continue;
|
|
5108
|
+
out.add(value);
|
|
5109
|
+
}
|
|
5110
|
+
return Array.from(out);
|
|
5111
|
+
}
|
|
5112
|
+
function getRate(serviceMap, serviceId) {
|
|
5113
|
+
const cap = getServiceCapability(serviceMap, serviceId);
|
|
5114
|
+
const rate = cap == null ? void 0 : cap.rate;
|
|
5115
|
+
if (typeof rate !== "number" || !Number.isFinite(rate)) return void 0;
|
|
5116
|
+
return rate;
|
|
5117
|
+
}
|
|
5118
|
+
function collectContextRefs(tag, visibleFields, serviceMap) {
|
|
5119
|
+
var _a, _b, _c, _d, _e;
|
|
5120
|
+
const serviceRefs = [];
|
|
5121
|
+
let tagDefault;
|
|
5122
|
+
if (tag.service_id !== void 0 && tag.service_id !== null) {
|
|
5123
|
+
const tagRate = getRate(serviceMap, tag.service_id);
|
|
5124
|
+
if (tagRate != null) {
|
|
5125
|
+
tagDefault = {
|
|
5126
|
+
key: tag.id,
|
|
5127
|
+
nodeId: tag.id,
|
|
5128
|
+
nodeKind: "tag",
|
|
5129
|
+
serviceId: tag.service_id,
|
|
5130
|
+
rate: tagRate,
|
|
5131
|
+
label: (_a = tag.label) != null ? _a : tag.id,
|
|
5132
|
+
pricingRole: "base"
|
|
5133
|
+
};
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5136
|
+
for (const field of visibleFields) {
|
|
5137
|
+
const fieldRole = normalizeRole(field.pricing_role, "base");
|
|
5138
|
+
if (field.service_id !== void 0 && field.service_id !== null) {
|
|
5139
|
+
const rate = getRate(serviceMap, field.service_id);
|
|
5140
|
+
if (rate != null) {
|
|
5141
|
+
serviceRefs.push({
|
|
5142
|
+
key: field.id,
|
|
5143
|
+
nodeId: field.id,
|
|
5144
|
+
fieldId: field.id,
|
|
5145
|
+
nodeKind: "button",
|
|
5146
|
+
serviceId: field.service_id,
|
|
5147
|
+
rate,
|
|
5148
|
+
label: (_b = field.label) != null ? _b : field.id,
|
|
5149
|
+
pricingRole: fieldRole
|
|
5150
|
+
});
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
5153
|
+
for (const option of (_c = field.options) != null ? _c : []) {
|
|
5154
|
+
if (option.service_id === void 0 || option.service_id === null) continue;
|
|
5155
|
+
const rate = getRate(serviceMap, option.service_id);
|
|
5156
|
+
if (rate == null) continue;
|
|
5157
|
+
serviceRefs.push({
|
|
5158
|
+
key: option.id,
|
|
5159
|
+
nodeId: option.id,
|
|
5160
|
+
fieldId: field.id,
|
|
5161
|
+
nodeKind: "option",
|
|
5162
|
+
serviceId: option.service_id,
|
|
5163
|
+
rate,
|
|
5164
|
+
label: (_d = option.label) != null ? _d : option.id,
|
|
5165
|
+
pricingRole: normalizeRole((_e = option.pricing_role) != null ? _e : field.pricing_role, "base")
|
|
5166
|
+
});
|
|
5167
|
+
}
|
|
5168
|
+
}
|
|
5169
|
+
return { tagDefault, serviceRefs };
|
|
5170
|
+
}
|
|
5171
|
+
function pickHighestRatePrimary(refs) {
|
|
5172
|
+
return refs.reduce((best, cur) => {
|
|
5173
|
+
if (!best) return cur;
|
|
5174
|
+
if (cur.rate > best.rate) return cur;
|
|
5175
|
+
if (cur.rate < best.rate) return best;
|
|
5176
|
+
return cur.nodeId < best.nodeId ? cur : best;
|
|
5177
|
+
}, void 0);
|
|
5178
|
+
}
|
|
5179
|
+
function validateRateCoherenceForVisibleContext(params) {
|
|
5180
|
+
const { v, tagId, selectedKeys, visibleFieldIds, effectMap, seen } = params;
|
|
5181
|
+
const tag = v.tagById.get(tagId);
|
|
5182
|
+
if (!tag) return;
|
|
5183
|
+
const visibleFields = visibleFieldIds.map((id) => v.fieldById.get(id)).filter(Boolean);
|
|
5184
|
+
const { tagDefault, serviceRefs: allServiceRefs } = collectContextRefs(
|
|
5185
|
+
tag,
|
|
5186
|
+
visibleFields,
|
|
5187
|
+
v.serviceMap
|
|
5188
|
+
);
|
|
5189
|
+
const baseRefs = allServiceRefs.filter((ref) => ref.pricingRole === "base");
|
|
5190
|
+
if (baseRefs.length === 0 && !tagDefault) return;
|
|
5191
|
+
const ratePolicy = normalizeRatePolicy(v.options.ratePolicy);
|
|
5192
|
+
const visibleInvalidFieldIds = visibleFieldIds.filter(
|
|
5193
|
+
(fieldId) => v.invalidRateFieldIds.has(fieldId)
|
|
5194
|
+
);
|
|
5195
|
+
for (const fieldId of visibleInvalidFieldIds) {
|
|
5196
|
+
const internalKey = [
|
|
5197
|
+
"rate-coherence-internal",
|
|
5198
|
+
tagId,
|
|
5199
|
+
[...selectedKeys].sort().join("|"),
|
|
5200
|
+
fieldId
|
|
5201
|
+
].join("::");
|
|
5202
|
+
if (seen.has(internalKey)) continue;
|
|
5203
|
+
seen.add(internalKey);
|
|
5204
|
+
v.errors.push({
|
|
5205
|
+
code: "rate_coherence_violation",
|
|
5206
|
+
severity: "error",
|
|
5207
|
+
nodeId: fieldId,
|
|
5208
|
+
message: `Field "${fieldId}" is internally invalid under rate policy "${ratePolicy.kind}".`,
|
|
5209
|
+
details: {
|
|
5210
|
+
kind: "internal_field",
|
|
5211
|
+
tagId,
|
|
5212
|
+
selectedKeys: [...selectedKeys],
|
|
5213
|
+
visibleFieldIds: [...visibleFieldIds],
|
|
5214
|
+
fieldId,
|
|
5215
|
+
invalidFieldIds: [fieldId],
|
|
5216
|
+
affectedIds: uniqueStrings([tagId, ...selectedKeys, fieldId])
|
|
5217
|
+
}
|
|
5218
|
+
});
|
|
5219
|
+
}
|
|
5220
|
+
const selectedSet = new Set(selectedKeys);
|
|
5221
|
+
const selectedServiceRefs = baseRefs.filter((ref) => selectedSet.has(ref.key));
|
|
5222
|
+
if (baseRefs.length === 0) return;
|
|
5223
|
+
for (let i = 0; i < baseRefs.length; i++) {
|
|
5224
|
+
for (let j = i + 1; j < baseRefs.length; j++) {
|
|
5225
|
+
const left = baseRefs[i];
|
|
5226
|
+
const right = baseRefs[j];
|
|
5227
|
+
const hypotheticalKeys = [...selectedKeys, left.key, right.key];
|
|
5228
|
+
const survivingRefs = baseRefs.filter(
|
|
5229
|
+
(ref) => !isRefExcludedBySelectedKeys(
|
|
5230
|
+
{ fieldId: ref.fieldId, nodeId: ref.nodeId },
|
|
5231
|
+
hypotheticalKeys,
|
|
5232
|
+
effectMap
|
|
5233
|
+
)
|
|
5234
|
+
);
|
|
5235
|
+
const survivingSet = new Set(survivingRefs.map((ref) => ref.nodeId));
|
|
5236
|
+
if (!survivingSet.has(left.nodeId) || !survivingSet.has(right.nodeId)) {
|
|
5237
|
+
continue;
|
|
5238
|
+
}
|
|
5239
|
+
if (survivingRefs.length <= 1) continue;
|
|
5240
|
+
const survivingSelected = survivingRefs.filter(
|
|
5241
|
+
(ref) => selectedSet.has(ref.key)
|
|
5242
|
+
);
|
|
5243
|
+
const tagIsCompeting = survivingSelected.length === 0;
|
|
5244
|
+
const primary = pickHighestRatePrimary(survivingRefs);
|
|
5245
|
+
if (!primary) continue;
|
|
5246
|
+
const comparePool = survivingRefs.filter((ref) => ref.nodeId !== primary.nodeId);
|
|
5247
|
+
for (const candidate of comparePool) {
|
|
5248
|
+
if (passesRatePolicy(ratePolicy, primary.rate, candidate.rate)) continue;
|
|
5249
|
+
const issueKey = [
|
|
5250
|
+
"rate-coherence-context",
|
|
5251
|
+
tagId,
|
|
5252
|
+
[...selectedKeys].sort().join("|"),
|
|
5253
|
+
[...survivingRefs.map((r) => r.nodeId).sort()].join("|"),
|
|
5254
|
+
primary.nodeId,
|
|
5255
|
+
candidate.nodeId,
|
|
5256
|
+
ratePolicy.kind,
|
|
5257
|
+
"pct" in ratePolicy ? String(ratePolicy.pct) : ""
|
|
5258
|
+
].join("::");
|
|
5259
|
+
if (seen.has(issueKey)) continue;
|
|
5260
|
+
seen.add(issueKey);
|
|
5261
|
+
v.errors.push({
|
|
5262
|
+
code: "rate_coherence_violation",
|
|
5263
|
+
severity: "error",
|
|
5264
|
+
nodeId: candidate.nodeId,
|
|
5265
|
+
message: "Visible service context contains incompatible base service rates.",
|
|
5266
|
+
details: {
|
|
5267
|
+
kind: "selected_context",
|
|
5268
|
+
tagId,
|
|
5269
|
+
selectedKeys: [...selectedKeys],
|
|
5270
|
+
visibleFieldIds: [...visibleFieldIds],
|
|
5271
|
+
primary: {
|
|
5272
|
+
nodeId: primary.nodeId,
|
|
5273
|
+
fieldId: primary.fieldId,
|
|
5274
|
+
service_id: primary.serviceId,
|
|
5275
|
+
serviceId: primary.serviceId,
|
|
5276
|
+
rate: primary.rate
|
|
5277
|
+
},
|
|
5278
|
+
candidate: {
|
|
5279
|
+
nodeId: candidate.nodeId,
|
|
5280
|
+
fieldId: candidate.fieldId,
|
|
5281
|
+
service_id: candidate.serviceId,
|
|
5282
|
+
serviceId: candidate.serviceId,
|
|
5283
|
+
rate: candidate.rate
|
|
5284
|
+
},
|
|
5285
|
+
policy: ratePolicy.kind,
|
|
5286
|
+
policyPct: "pct" in ratePolicy ? ratePolicy.pct : void 0,
|
|
5287
|
+
invalidFieldIds: visibleInvalidFieldIds,
|
|
5288
|
+
affectedIds: uniqueStrings([
|
|
5289
|
+
tagId,
|
|
5290
|
+
...selectedKeys,
|
|
5291
|
+
primary.nodeId,
|
|
5292
|
+
primary.fieldId,
|
|
5293
|
+
candidate.nodeId,
|
|
5294
|
+
candidate.fieldId,
|
|
5295
|
+
tagIsCompeting ? tagDefault == null ? void 0 : tagDefault.nodeId : void 0
|
|
5296
|
+
]),
|
|
5297
|
+
affectedServiceIds: uniqueStrings([
|
|
5298
|
+
String(primary.serviceId),
|
|
5299
|
+
String(candidate.serviceId)
|
|
5300
|
+
])
|
|
5301
|
+
}
|
|
5302
|
+
});
|
|
5303
|
+
}
|
|
5304
|
+
}
|
|
5305
|
+
}
|
|
5306
|
+
if (selectedServiceRefs.length === 0 && tagDefault && baseRefs.length > 0) {
|
|
5307
|
+
const survivingByDefault = baseRefs.filter(
|
|
5308
|
+
(ref) => !isRefExcludedBySelectedKeys(
|
|
5309
|
+
{ fieldId: ref.fieldId, nodeId: ref.nodeId },
|
|
5310
|
+
selectedKeys,
|
|
5311
|
+
effectMap
|
|
5312
|
+
)
|
|
5313
|
+
);
|
|
5314
|
+
for (const candidate of survivingByDefault) {
|
|
5315
|
+
if (passesRatePolicy(ratePolicy, tagDefault.rate, candidate.rate)) continue;
|
|
5316
|
+
const issueKey = [
|
|
5317
|
+
"rate-coherence-default",
|
|
5318
|
+
tagId,
|
|
5319
|
+
[...selectedKeys].sort().join("|"),
|
|
5320
|
+
tagDefault.nodeId,
|
|
5321
|
+
candidate.nodeId,
|
|
5322
|
+
ratePolicy.kind,
|
|
5323
|
+
"pct" in ratePolicy ? String(ratePolicy.pct) : ""
|
|
5324
|
+
].join("::");
|
|
5325
|
+
if (seen.has(issueKey)) continue;
|
|
5326
|
+
seen.add(issueKey);
|
|
5327
|
+
v.errors.push({
|
|
5328
|
+
code: "rate_coherence_violation",
|
|
5329
|
+
severity: "error",
|
|
5330
|
+
nodeId: candidate.nodeId,
|
|
5331
|
+
message: "Visible service context contains incompatible base service rates.",
|
|
5332
|
+
details: {
|
|
5333
|
+
kind: "selected_context",
|
|
5334
|
+
tagId,
|
|
5335
|
+
selectedKeys: [...selectedKeys],
|
|
5336
|
+
visibleFieldIds: [...visibleFieldIds],
|
|
5337
|
+
primary: {
|
|
5338
|
+
nodeId: tagDefault.nodeId,
|
|
5339
|
+
service_id: tagDefault.serviceId,
|
|
5340
|
+
serviceId: tagDefault.serviceId,
|
|
5341
|
+
rate: tagDefault.rate
|
|
5342
|
+
},
|
|
5343
|
+
candidate: {
|
|
5344
|
+
nodeId: candidate.nodeId,
|
|
5345
|
+
fieldId: candidate.fieldId,
|
|
5346
|
+
service_id: candidate.serviceId,
|
|
5347
|
+
serviceId: candidate.serviceId,
|
|
5348
|
+
rate: candidate.rate
|
|
5349
|
+
},
|
|
5350
|
+
policy: ratePolicy.kind,
|
|
5351
|
+
policyPct: "pct" in ratePolicy ? ratePolicy.pct : void 0,
|
|
5352
|
+
invalidFieldIds: visibleInvalidFieldIds,
|
|
5353
|
+
affectedIds: uniqueStrings([
|
|
5354
|
+
tagId,
|
|
5355
|
+
...selectedKeys,
|
|
5356
|
+
tagDefault.nodeId,
|
|
5357
|
+
candidate.nodeId,
|
|
5358
|
+
candidate.fieldId
|
|
5359
|
+
]),
|
|
5360
|
+
affectedServiceIds: uniqueStrings([
|
|
5361
|
+
String(tagDefault.serviceId),
|
|
5362
|
+
String(candidate.serviceId)
|
|
5363
|
+
])
|
|
5364
|
+
}
|
|
5365
|
+
});
|
|
5366
|
+
}
|
|
5367
|
+
}
|
|
5368
|
+
}
|
|
5369
|
+
function validateRateCoherence(v) {
|
|
5370
|
+
if (Object.keys(v.serviceMap).length === 0 || v.tags.length === 0) return;
|
|
5371
|
+
const effectMap = buildTriggerEffectMap(v.props);
|
|
5372
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5373
|
+
for (const context of v.simulatedVisibilityContexts) {
|
|
5374
|
+
validateRateCoherenceForVisibleContext({
|
|
5375
|
+
v,
|
|
5376
|
+
tagId: context.tagId,
|
|
5377
|
+
selectedKeys: context.selectedKeys,
|
|
5378
|
+
visibleFieldIds: context.visibleFieldIds,
|
|
5379
|
+
effectMap,
|
|
5380
|
+
seen
|
|
5381
|
+
});
|
|
5382
|
+
}
|
|
5383
|
+
}
|
|
5384
|
+
|
|
5047
5385
|
// src/core/validate/steps/constraints.ts
|
|
5048
5386
|
function constraintKeysInChain(v, tagId) {
|
|
5049
5387
|
const keys = [];
|
|
@@ -5800,6 +6138,84 @@ function mergeValidatorOptions(defaults = {}, overrides = {}) {
|
|
|
5800
6138
|
};
|
|
5801
6139
|
}
|
|
5802
6140
|
|
|
6141
|
+
// src/core/validate/index.ts
|
|
6142
|
+
function readVisibilitySimOpts(ctx) {
|
|
6143
|
+
const c = ctx;
|
|
6144
|
+
const simulate = c.simulateVisibility === true || c.visibilitySimulate === true || c.simulate === true;
|
|
6145
|
+
const maxStates = typeof c.maxVisibilityStates === "number" ? c.maxVisibilityStates : typeof c.visibilityMaxStates === "number" ? c.visibilityMaxStates : typeof c.maxStates === "number" ? c.maxStates : void 0;
|
|
6146
|
+
const maxDepth = typeof c.maxVisibilityDepth === "number" ? c.maxVisibilityDepth : typeof c.visibilityMaxDepth === "number" ? c.visibilityMaxDepth : typeof c.maxDepth === "number" ? c.maxDepth : void 0;
|
|
6147
|
+
const simulateAllRoots = c.simulateAllRoots === true || c.visibilitySimulateAllRoots === true;
|
|
6148
|
+
const onlyEffectfulTriggers = c.onlyEffectfulTriggers === false ? false : c.visibilityOnlyEffectfulTriggers !== false;
|
|
6149
|
+
return {
|
|
6150
|
+
simulate,
|
|
6151
|
+
maxStates,
|
|
6152
|
+
maxDepth,
|
|
6153
|
+
simulateAllRoots,
|
|
6154
|
+
onlyEffectfulTriggers
|
|
6155
|
+
};
|
|
6156
|
+
}
|
|
6157
|
+
function validate(props, ctx = {}) {
|
|
6158
|
+
var _a, _b, _c;
|
|
6159
|
+
const options = mergeValidatorOptions({}, ctx);
|
|
6160
|
+
const fallbackSettings = resolveFallbackSettings(options);
|
|
6161
|
+
const ratePolicy = resolveGlobalRatePolicy(options);
|
|
6162
|
+
const errors = [];
|
|
6163
|
+
const serviceMap = (_a = options.serviceMap) != null ? _a : {};
|
|
6164
|
+
const selectedKeys = new Set(
|
|
6165
|
+
(_b = options.selectedOptionKeys) != null ? _b : []
|
|
6166
|
+
);
|
|
6167
|
+
const tags = Array.isArray(props.filters) ? props.filters : [];
|
|
6168
|
+
const fields = Array.isArray(props.fields) ? props.fields : [];
|
|
6169
|
+
const tagById = /* @__PURE__ */ new Map();
|
|
6170
|
+
const fieldById = /* @__PURE__ */ new Map();
|
|
6171
|
+
for (const t of tags) tagById.set(t.id, t);
|
|
6172
|
+
for (const f of fields) fieldById.set(f.id, f);
|
|
6173
|
+
const v = {
|
|
6174
|
+
props,
|
|
6175
|
+
nodeMap: (_c = options.nodeMap) != null ? _c : buildNodeMap(props),
|
|
6176
|
+
options: {
|
|
6177
|
+
...options,
|
|
6178
|
+
ratePolicy,
|
|
6179
|
+
fallbackSettings
|
|
6180
|
+
},
|
|
6181
|
+
errors,
|
|
6182
|
+
serviceMap,
|
|
6183
|
+
selectedKeys,
|
|
6184
|
+
tags,
|
|
6185
|
+
fields,
|
|
6186
|
+
invalidRateFieldIds: /* @__PURE__ */ new Set(),
|
|
6187
|
+
tagById,
|
|
6188
|
+
fieldById,
|
|
6189
|
+
fieldsVisibleUnder: (_tagId) => [],
|
|
6190
|
+
simulatedVisibilityContexts: []
|
|
6191
|
+
};
|
|
6192
|
+
validateStructure(v);
|
|
6193
|
+
validateIdentity(v);
|
|
6194
|
+
validateOptionMaps(v);
|
|
6195
|
+
validateOrderKinds(v);
|
|
6196
|
+
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
6197
|
+
const visSim = readVisibilitySimOpts(options);
|
|
6198
|
+
validateVisibility(v, visSim);
|
|
6199
|
+
applyPolicies(
|
|
6200
|
+
v.errors,
|
|
6201
|
+
v.props,
|
|
6202
|
+
v.serviceMap,
|
|
6203
|
+
v.options.policies,
|
|
6204
|
+
v.fieldsVisibleUnder,
|
|
6205
|
+
v.tags
|
|
6206
|
+
);
|
|
6207
|
+
validateServiceVsUserInput(v);
|
|
6208
|
+
validateUtilityMarkers(v);
|
|
6209
|
+
validateRates(v);
|
|
6210
|
+
validateRateCoherence(v);
|
|
6211
|
+
validateConstraints(v);
|
|
6212
|
+
validateCustomFields(v);
|
|
6213
|
+
validateGlobalUtilityGuard(v);
|
|
6214
|
+
validateUnboundFields(v);
|
|
6215
|
+
validateFallbacks(v);
|
|
6216
|
+
return v.errors;
|
|
6217
|
+
}
|
|
6218
|
+
|
|
5803
6219
|
// src/core/builder.ts
|
|
5804
6220
|
var import_lodash_es2 = require("lodash-es");
|
|
5805
6221
|
function createBuilder(opts = {}) {
|
|
@@ -6082,344 +6498,6 @@ function toStringSet(v) {
|
|
|
6082
6498
|
return new Set(v.map(String));
|
|
6083
6499
|
}
|
|
6084
6500
|
|
|
6085
|
-
// src/core/rate-coherence.ts
|
|
6086
|
-
function validateRateCoherenceDeep(params) {
|
|
6087
|
-
var _a, _b, _c;
|
|
6088
|
-
const { builder, services, tagId } = params;
|
|
6089
|
-
const ratePolicy = normalizeRatePolicy(params.ratePolicy);
|
|
6090
|
-
const props = builder.getProps();
|
|
6091
|
-
const invalidFieldIds = new Set((_a = params.invalidFieldIds) != null ? _a : []);
|
|
6092
|
-
const fields = (_b = props.fields) != null ? _b : [];
|
|
6093
|
-
const fieldById = new Map(fields.map((f) => [f.id, f]));
|
|
6094
|
-
const tagById = new Map(((_c = props.filters) != null ? _c : []).map((t) => [t.id, t]));
|
|
6095
|
-
const tag = tagById.get(tagId);
|
|
6096
|
-
const baselineFieldIds = builder.visibleFields(tagId, []);
|
|
6097
|
-
const baselineFields = baselineFieldIds.map((fid) => fieldById.get(fid)).filter(Boolean);
|
|
6098
|
-
const anchors = collectAnchors(baselineFields);
|
|
6099
|
-
const diagnostics = [];
|
|
6100
|
-
const seen = /* @__PURE__ */ new Set();
|
|
6101
|
-
for (const anchor of anchors) {
|
|
6102
|
-
const selectedKeys = anchor.kind === "option" ? [`${anchor.fieldId}::${anchor.id}`] : [anchor.fieldId];
|
|
6103
|
-
const visibleFields = builder.visibleFields(tagId, selectedKeys).map((fid) => fieldById.get(fid)).filter(Boolean);
|
|
6104
|
-
const visibleInvalidFieldIds = visibleFields.map((field) => field.id).filter((fieldId) => invalidFieldIds.has(fieldId));
|
|
6105
|
-
for (const fieldId of visibleInvalidFieldIds) {
|
|
6106
|
-
const key = `internal|${tagId}|${fieldId}`;
|
|
6107
|
-
if (seen.has(key)) continue;
|
|
6108
|
-
seen.add(key);
|
|
6109
|
-
diagnostics.push({
|
|
6110
|
-
kind: "internal_field",
|
|
6111
|
-
scope: "visible_group",
|
|
6112
|
-
tagId,
|
|
6113
|
-
fieldId,
|
|
6114
|
-
nodeId: fieldId,
|
|
6115
|
-
message: `Field "${fieldId}" is internally invalid under rate policy "${ratePolicy.kind}".`,
|
|
6116
|
-
simulationAnchor: {
|
|
6117
|
-
kind: anchor.kind,
|
|
6118
|
-
id: anchor.id,
|
|
6119
|
-
fieldId: anchor.fieldId,
|
|
6120
|
-
label: anchor.label
|
|
6121
|
-
},
|
|
6122
|
-
invalidFieldIds: [fieldId]
|
|
6123
|
-
});
|
|
6124
|
-
}
|
|
6125
|
-
const references = visibleFields.flatMap(
|
|
6126
|
-
(field) => collectFieldReferences(field, services)
|
|
6127
|
-
);
|
|
6128
|
-
if (references.length <= 1) continue;
|
|
6129
|
-
const primary = references.reduce((best, current) => {
|
|
6130
|
-
if (current.rate !== best.rate) {
|
|
6131
|
-
return current.rate > best.rate ? current : best;
|
|
6132
|
-
}
|
|
6133
|
-
const bestKey = `${best.fieldId}|${best.nodeId}`;
|
|
6134
|
-
const currentKey = `${current.fieldId}|${current.nodeId}`;
|
|
6135
|
-
return currentKey < bestKey ? current : best;
|
|
6136
|
-
});
|
|
6137
|
-
for (const candidate of references) {
|
|
6138
|
-
if (candidate.nodeId === primary.nodeId) continue;
|
|
6139
|
-
if (candidate.fieldId === primary.fieldId) continue;
|
|
6140
|
-
if (passesRatePolicy(ratePolicy, primary.rate, candidate.rate)) {
|
|
6141
|
-
continue;
|
|
6142
|
-
}
|
|
6143
|
-
const key = contextualKey(tagId, primary, candidate, ratePolicy);
|
|
6144
|
-
if (seen.has(key)) continue;
|
|
6145
|
-
seen.add(key);
|
|
6146
|
-
diagnostics.push({
|
|
6147
|
-
kind: "contextual",
|
|
6148
|
-
scope: "visible_group",
|
|
6149
|
-
tagId,
|
|
6150
|
-
nodeId: candidate.nodeId,
|
|
6151
|
-
primary: toDiagnosticRef(primary),
|
|
6152
|
-
offender: toDiagnosticRef(candidate),
|
|
6153
|
-
policy: ratePolicy.kind,
|
|
6154
|
-
policyPct: "pct" in ratePolicy ? ratePolicy.pct : void 0,
|
|
6155
|
-
message: explainRateMismatch(
|
|
6156
|
-
ratePolicy,
|
|
6157
|
-
primary,
|
|
6158
|
-
candidate,
|
|
6159
|
-
describeLabel(tag)
|
|
6160
|
-
),
|
|
6161
|
-
simulationAnchor: {
|
|
6162
|
-
kind: anchor.kind,
|
|
6163
|
-
id: anchor.id,
|
|
6164
|
-
fieldId: anchor.fieldId,
|
|
6165
|
-
label: anchor.label
|
|
6166
|
-
},
|
|
6167
|
-
invalidFieldIds: visibleInvalidFieldIds
|
|
6168
|
-
});
|
|
6169
|
-
}
|
|
6170
|
-
}
|
|
6171
|
-
return diagnostics;
|
|
6172
|
-
}
|
|
6173
|
-
function collectAnchors(fields) {
|
|
6174
|
-
var _a, _b;
|
|
6175
|
-
const anchors = [];
|
|
6176
|
-
for (const field of fields) {
|
|
6177
|
-
if (!isButton(field)) continue;
|
|
6178
|
-
if (Array.isArray(field.options) && field.options.length > 0) {
|
|
6179
|
-
for (const option of field.options) {
|
|
6180
|
-
anchors.push({
|
|
6181
|
-
kind: "option",
|
|
6182
|
-
id: option.id,
|
|
6183
|
-
fieldId: field.id,
|
|
6184
|
-
label: (_a = option.label) != null ? _a : option.id
|
|
6185
|
-
});
|
|
6186
|
-
}
|
|
6187
|
-
continue;
|
|
6188
|
-
}
|
|
6189
|
-
anchors.push({
|
|
6190
|
-
kind: "field",
|
|
6191
|
-
id: field.id,
|
|
6192
|
-
fieldId: field.id,
|
|
6193
|
-
label: (_b = field.label) != null ? _b : field.id
|
|
6194
|
-
});
|
|
6195
|
-
}
|
|
6196
|
-
return anchors;
|
|
6197
|
-
}
|
|
6198
|
-
function collectFieldReferences(field, services) {
|
|
6199
|
-
var _a;
|
|
6200
|
-
const members = collectBaseMembers(field, services);
|
|
6201
|
-
if (members.length === 0) return [];
|
|
6202
|
-
if (isMultiField(field)) {
|
|
6203
|
-
const averageRate = members.reduce((sum, member) => sum + member.rate, 0) / members.length;
|
|
6204
|
-
return [
|
|
6205
|
-
{
|
|
6206
|
-
refKind: "multi",
|
|
6207
|
-
nodeId: field.id,
|
|
6208
|
-
fieldId: field.id,
|
|
6209
|
-
label: (_a = field.label) != null ? _a : field.id,
|
|
6210
|
-
rate: averageRate,
|
|
6211
|
-
members
|
|
6212
|
-
}
|
|
6213
|
-
];
|
|
6214
|
-
}
|
|
6215
|
-
return members.map((member) => ({
|
|
6216
|
-
refKind: "single",
|
|
6217
|
-
nodeId: member.id,
|
|
6218
|
-
fieldId: field.id,
|
|
6219
|
-
label: member.label,
|
|
6220
|
-
rate: member.rate,
|
|
6221
|
-
service_id: member.service_id,
|
|
6222
|
-
members: [member]
|
|
6223
|
-
}));
|
|
6224
|
-
}
|
|
6225
|
-
function collectBaseMembers(field, services) {
|
|
6226
|
-
var _a, _b, _c;
|
|
6227
|
-
const members = [];
|
|
6228
|
-
if (Array.isArray(field.options) && field.options.length > 0) {
|
|
6229
|
-
for (const option of field.options) {
|
|
6230
|
-
const role2 = normalizeRole((_a = option.pricing_role) != null ? _a : field.pricing_role, "base");
|
|
6231
|
-
if (role2 !== "base") continue;
|
|
6232
|
-
if (option.service_id === void 0 || option.service_id === null) {
|
|
6233
|
-
continue;
|
|
6234
|
-
}
|
|
6235
|
-
const cap2 = getServiceCapability(services, option.service_id);
|
|
6236
|
-
if (!cap2 || typeof cap2.rate !== "number" || !Number.isFinite(cap2.rate)) {
|
|
6237
|
-
continue;
|
|
6238
|
-
}
|
|
6239
|
-
members.push({
|
|
6240
|
-
kind: "option",
|
|
6241
|
-
id: option.id,
|
|
6242
|
-
fieldId: field.id,
|
|
6243
|
-
label: (_b = option.label) != null ? _b : option.id,
|
|
6244
|
-
service_id: option.service_id,
|
|
6245
|
-
rate: cap2.rate
|
|
6246
|
-
});
|
|
6247
|
-
}
|
|
6248
|
-
return members;
|
|
6249
|
-
}
|
|
6250
|
-
const role = normalizeRole(field.pricing_role, "base");
|
|
6251
|
-
if (role !== "base") return members;
|
|
6252
|
-
if (field.service_id === void 0 || field.service_id === null) return members;
|
|
6253
|
-
const cap = getServiceCapability(services, field.service_id);
|
|
6254
|
-
if (!cap || typeof cap.rate !== "number" || !Number.isFinite(cap.rate)) {
|
|
6255
|
-
return members;
|
|
6256
|
-
}
|
|
6257
|
-
members.push({
|
|
6258
|
-
kind: "field",
|
|
6259
|
-
id: field.id,
|
|
6260
|
-
fieldId: field.id,
|
|
6261
|
-
label: (_c = field.label) != null ? _c : field.id,
|
|
6262
|
-
service_id: field.service_id,
|
|
6263
|
-
rate: cap.rate
|
|
6264
|
-
});
|
|
6265
|
-
return members;
|
|
6266
|
-
}
|
|
6267
|
-
function isButton(field) {
|
|
6268
|
-
if (field.button === true) return true;
|
|
6269
|
-
return Array.isArray(field.options) && field.options.length > 0;
|
|
6270
|
-
}
|
|
6271
|
-
function normalizeRole(role, fallback) {
|
|
6272
|
-
return role === "base" || role === "utility" ? role : fallback;
|
|
6273
|
-
}
|
|
6274
|
-
function toDiagnosticRef(reference) {
|
|
6275
|
-
return {
|
|
6276
|
-
nodeId: reference.nodeId,
|
|
6277
|
-
fieldId: reference.fieldId,
|
|
6278
|
-
label: reference.label,
|
|
6279
|
-
refKind: reference.refKind,
|
|
6280
|
-
service_id: reference.service_id,
|
|
6281
|
-
rate: reference.rate
|
|
6282
|
-
};
|
|
6283
|
-
}
|
|
6284
|
-
function contextualKey(tagId, primary, candidate, ratePolicy) {
|
|
6285
|
-
const pctKey = "pct" in ratePolicy ? `:${ratePolicy.pct}` : "";
|
|
6286
|
-
return [
|
|
6287
|
-
"contextual",
|
|
6288
|
-
tagId,
|
|
6289
|
-
primary.fieldId,
|
|
6290
|
-
primary.nodeId,
|
|
6291
|
-
candidate.fieldId,
|
|
6292
|
-
candidate.nodeId,
|
|
6293
|
-
`${ratePolicy.kind}${pctKey}`
|
|
6294
|
-
].join("|");
|
|
6295
|
-
}
|
|
6296
|
-
function describeLabel(tag) {
|
|
6297
|
-
var _a, _b;
|
|
6298
|
-
return (_b = (_a = tag == null ? void 0 : tag.label) != null ? _a : tag == null ? void 0 : tag.id) != null ? _b : "tag";
|
|
6299
|
-
}
|
|
6300
|
-
function explainRateMismatch(policy, primary, candidate, where) {
|
|
6301
|
-
var _a, _b;
|
|
6302
|
-
const primaryLabel = `${(_a = primary.label) != null ? _a : primary.nodeId} (${primary.rate})`;
|
|
6303
|
-
const candidateLabel = `${(_b = candidate.label) != null ? _b : candidate.nodeId} (${candidate.rate})`;
|
|
6304
|
-
switch (policy.kind) {
|
|
6305
|
-
case "eq_primary":
|
|
6306
|
-
return `Rate coherence failed (${where}): ${candidateLabel} must exactly match ${primaryLabel}.`;
|
|
6307
|
-
case "lte_primary":
|
|
6308
|
-
return `Rate coherence failed (${where}): ${candidateLabel} must stay within ${policy.pct}% below and never above ${primaryLabel}.`;
|
|
6309
|
-
case "within_pct":
|
|
6310
|
-
return `Rate coherence failed (${where}): ${candidateLabel} must be within ${policy.pct}% of ${primaryLabel}.`;
|
|
6311
|
-
case "at_least_pct_lower":
|
|
6312
|
-
return `Rate coherence failed (${where}): ${candidateLabel} must be at least ${policy.pct}% lower than ${primaryLabel}.`;
|
|
6313
|
-
}
|
|
6314
|
-
}
|
|
6315
|
-
|
|
6316
|
-
// src/core/validate/index.ts
|
|
6317
|
-
function readVisibilitySimOpts(ctx) {
|
|
6318
|
-
const c = ctx;
|
|
6319
|
-
const simulate = c.simulateVisibility === true || c.visibilitySimulate === true || c.simulate === true;
|
|
6320
|
-
const maxStates = typeof c.maxVisibilityStates === "number" ? c.maxVisibilityStates : typeof c.visibilityMaxStates === "number" ? c.visibilityMaxStates : typeof c.maxStates === "number" ? c.maxStates : void 0;
|
|
6321
|
-
const maxDepth = typeof c.maxVisibilityDepth === "number" ? c.maxVisibilityDepth : typeof c.visibilityMaxDepth === "number" ? c.visibilityMaxDepth : typeof c.maxDepth === "number" ? c.maxDepth : void 0;
|
|
6322
|
-
const simulateAllRoots = c.simulateAllRoots === true || c.visibilitySimulateAllRoots === true;
|
|
6323
|
-
const onlyEffectfulTriggers = c.onlyEffectfulTriggers === false ? false : c.visibilityOnlyEffectfulTriggers !== false;
|
|
6324
|
-
return {
|
|
6325
|
-
simulate,
|
|
6326
|
-
maxStates,
|
|
6327
|
-
maxDepth,
|
|
6328
|
-
simulateAllRoots,
|
|
6329
|
-
onlyEffectfulTriggers
|
|
6330
|
-
};
|
|
6331
|
-
}
|
|
6332
|
-
function validate(props, ctx = {}) {
|
|
6333
|
-
var _a, _b, _c;
|
|
6334
|
-
const options = mergeValidatorOptions({}, ctx);
|
|
6335
|
-
const fallbackSettings = resolveFallbackSettings(options);
|
|
6336
|
-
const ratePolicy = resolveGlobalRatePolicy(options);
|
|
6337
|
-
const errors = [];
|
|
6338
|
-
const serviceMap = (_a = options.serviceMap) != null ? _a : {};
|
|
6339
|
-
const selectedKeys = new Set(
|
|
6340
|
-
(_b = options.selectedOptionKeys) != null ? _b : []
|
|
6341
|
-
);
|
|
6342
|
-
const tags = Array.isArray(props.filters) ? props.filters : [];
|
|
6343
|
-
const fields = Array.isArray(props.fields) ? props.fields : [];
|
|
6344
|
-
const tagById = /* @__PURE__ */ new Map();
|
|
6345
|
-
const fieldById = /* @__PURE__ */ new Map();
|
|
6346
|
-
for (const t of tags) tagById.set(t.id, t);
|
|
6347
|
-
for (const f of fields) fieldById.set(f.id, f);
|
|
6348
|
-
const v = {
|
|
6349
|
-
props,
|
|
6350
|
-
nodeMap: (_c = options.nodeMap) != null ? _c : buildNodeMap(props),
|
|
6351
|
-
options: {
|
|
6352
|
-
...options,
|
|
6353
|
-
ratePolicy,
|
|
6354
|
-
fallbackSettings
|
|
6355
|
-
},
|
|
6356
|
-
errors,
|
|
6357
|
-
serviceMap,
|
|
6358
|
-
selectedKeys,
|
|
6359
|
-
tags,
|
|
6360
|
-
fields,
|
|
6361
|
-
invalidRateFieldIds: /* @__PURE__ */ new Set(),
|
|
6362
|
-
tagById,
|
|
6363
|
-
fieldById,
|
|
6364
|
-
fieldsVisibleUnder: (_tagId) => []
|
|
6365
|
-
};
|
|
6366
|
-
validateStructure(v);
|
|
6367
|
-
validateIdentity(v);
|
|
6368
|
-
validateOptionMaps(v);
|
|
6369
|
-
validateOrderKinds(v);
|
|
6370
|
-
v.fieldsVisibleUnder = createFieldsVisibleUnder(v);
|
|
6371
|
-
const visSim = readVisibilitySimOpts(options);
|
|
6372
|
-
validateVisibility(v, visSim);
|
|
6373
|
-
applyPolicies(
|
|
6374
|
-
v.errors,
|
|
6375
|
-
v.props,
|
|
6376
|
-
v.serviceMap,
|
|
6377
|
-
v.options.policies,
|
|
6378
|
-
v.fieldsVisibleUnder,
|
|
6379
|
-
v.tags
|
|
6380
|
-
);
|
|
6381
|
-
validateServiceVsUserInput(v);
|
|
6382
|
-
validateUtilityMarkers(v);
|
|
6383
|
-
validateRates(v);
|
|
6384
|
-
if (Object.keys(serviceMap).length > 0 && tags.length > 0) {
|
|
6385
|
-
const builder = createBuilder({ serviceMap });
|
|
6386
|
-
builder.load(props);
|
|
6387
|
-
for (const tag of tags) {
|
|
6388
|
-
const diags = validateRateCoherenceDeep({
|
|
6389
|
-
builder,
|
|
6390
|
-
services: serviceMap,
|
|
6391
|
-
tagId: tag.id,
|
|
6392
|
-
ratePolicy,
|
|
6393
|
-
invalidFieldIds: v.invalidRateFieldIds
|
|
6394
|
-
});
|
|
6395
|
-
for (const diag of diags) {
|
|
6396
|
-
if (diag.kind !== "contextual") continue;
|
|
6397
|
-
errors.push({
|
|
6398
|
-
code: "rate_coherence_violation",
|
|
6399
|
-
severity: "error",
|
|
6400
|
-
message: diag.message,
|
|
6401
|
-
nodeId: diag.nodeId,
|
|
6402
|
-
details: {
|
|
6403
|
-
tagId: diag.tagId,
|
|
6404
|
-
simulationAnchor: diag.simulationAnchor,
|
|
6405
|
-
primary: diag.primary,
|
|
6406
|
-
offender: diag.offender,
|
|
6407
|
-
policy: diag.policy,
|
|
6408
|
-
policyPct: diag.policyPct,
|
|
6409
|
-
invalidFieldIds: diag.invalidFieldIds
|
|
6410
|
-
}
|
|
6411
|
-
});
|
|
6412
|
-
}
|
|
6413
|
-
}
|
|
6414
|
-
}
|
|
6415
|
-
validateConstraints(v);
|
|
6416
|
-
validateCustomFields(v);
|
|
6417
|
-
validateGlobalUtilityGuard(v);
|
|
6418
|
-
validateUnboundFields(v);
|
|
6419
|
-
validateFallbacks(v);
|
|
6420
|
-
return v.errors;
|
|
6421
|
-
}
|
|
6422
|
-
|
|
6423
6501
|
// src/core/fallback.ts
|
|
6424
6502
|
var DEFAULT_SETTINGS = {
|
|
6425
6503
|
requireConstraintFit: true,
|
|
@@ -6841,9 +6919,9 @@ function createNodeIndex(builder) {
|
|
|
6841
6919
|
if (cached) return cached;
|
|
6842
6920
|
const raw = fieldById.get(id);
|
|
6843
6921
|
if (!raw) return void 0;
|
|
6844
|
-
const
|
|
6845
|
-
const includes =
|
|
6846
|
-
const excludes =
|
|
6922
|
+
const isButton = raw.button === true;
|
|
6923
|
+
const includes = isButton ? Object.freeze(new Set((_b2 = (_a2 = props.includes_for_buttons) == null ? void 0 : _a2[id]) != null ? _b2 : [])) : emptySet;
|
|
6924
|
+
const excludes = isButton ? Object.freeze(new Set((_d2 = (_c2 = props.excludes_for_buttons) == null ? void 0 : _c2[id]) != null ? _d2 : [])) : emptySet;
|
|
6847
6925
|
const bindIds = () => {
|
|
6848
6926
|
const cachedBind = fieldBindIdsCache.get(id);
|
|
6849
6927
|
if (cachedBind) return cachedBind;
|
|
@@ -6880,7 +6958,7 @@ function createNodeIndex(builder) {
|
|
|
6880
6958
|
);
|
|
6881
6959
|
},
|
|
6882
6960
|
getDescendants(tagId) {
|
|
6883
|
-
return resolveDescendants(id, includes, tagId, !
|
|
6961
|
+
return resolveDescendants(id, includes, tagId, !isButton);
|
|
6884
6962
|
}
|
|
6885
6963
|
};
|
|
6886
6964
|
fieldNodeCache.set(id, node);
|
|
@@ -6964,23 +7042,20 @@ function createNodeIndex(builder) {
|
|
|
6964
7042
|
|
|
6965
7043
|
// src/core/service-filter.ts
|
|
6966
7044
|
function filterServicesForVisibleGroup(input, deps) {
|
|
6967
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
7045
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
6968
7046
|
const svcMap = (_c = (_b = (_a = deps.builder).getServiceMap) == null ? void 0 : _b.call(_a)) != null ? _c : {};
|
|
6969
7047
|
const builderOptions = (_e = (_d = deps.builder).getOptions) == null ? void 0 : _e.call(_d);
|
|
6970
7048
|
const { context } = input;
|
|
6971
7049
|
const usedSet = new Set(context.usedServiceIds.map(String));
|
|
6972
|
-
const primary = context.usedServiceIds[0];
|
|
6973
7050
|
const explicitFallbackSettings = (_f = context.fallbackSettings) != null ? _f : context.fallback;
|
|
6974
7051
|
const resolvedRatePolicy = normalizeRatePolicy(
|
|
6975
7052
|
(_h = (_g = context.ratePolicy) != null ? _g : explicitFallbackSettings == null ? void 0 : explicitFallbackSettings.ratePolicy) != null ? _h : builderOptions == null ? void 0 : builderOptions.ratePolicy
|
|
6976
7053
|
);
|
|
6977
|
-
const fallbackSettingsSource = explicitFallbackSettings != null ? explicitFallbackSettings : builderOptions == null ? void 0 : builderOptions.fallbackSettings;
|
|
6978
|
-
const fb = {
|
|
6979
|
-
...DEFAULT_FALLBACK_SETTINGS,
|
|
6980
|
-
...fallbackSettingsSource != null ? fallbackSettingsSource : {},
|
|
6981
|
-
ratePolicy: resolvedRatePolicy
|
|
6982
|
-
};
|
|
6983
7054
|
const policySource = (_j = (_i = context.policies) != null ? _i : builderOptions == null ? void 0 : builderOptions.policies) != null ? _j : [];
|
|
7055
|
+
const resolvedCustomPrimaryRate = resolveCustomPrimaryRate(
|
|
7056
|
+
context.rateContext,
|
|
7057
|
+
svcMap
|
|
7058
|
+
);
|
|
6984
7059
|
const visibleServiceIds = context.selectedButtons === void 0 ? void 0 : collectVisibleServiceIds(
|
|
6985
7060
|
deps.builder,
|
|
6986
7061
|
context.tagId,
|
|
@@ -7007,7 +7082,19 @@ function filterServicesForVisibleGroup(input, deps) {
|
|
|
7007
7082
|
cap.id,
|
|
7008
7083
|
(_k = context.effectiveConstraints) != null ? _k : {}
|
|
7009
7084
|
);
|
|
7010
|
-
const passesRate2 =
|
|
7085
|
+
const passesRate2 = resolvedCustomPrimaryRate != null ? passesRatePolicy(
|
|
7086
|
+
resolvedRatePolicy,
|
|
7087
|
+
resolvedCustomPrimaryRate,
|
|
7088
|
+
toFiniteNumber(cap.rate)
|
|
7089
|
+
) : candidatePassesRateCoherence(
|
|
7090
|
+
deps.builder,
|
|
7091
|
+
svcMap,
|
|
7092
|
+
context.tagId,
|
|
7093
|
+
(_l = context.selectedButtons) != null ? _l : [],
|
|
7094
|
+
context.usedServiceIds,
|
|
7095
|
+
id,
|
|
7096
|
+
resolvedRatePolicy
|
|
7097
|
+
);
|
|
7011
7098
|
const polRes = evaluatePoliciesRaw(
|
|
7012
7099
|
policySource,
|
|
7013
7100
|
[...context.usedServiceIds, id],
|
|
@@ -7039,6 +7126,17 @@ function filterServicesForVisibleGroup(input, deps) {
|
|
|
7039
7126
|
diagnostics: lastDiagnostics && lastDiagnostics.length ? lastDiagnostics : void 0
|
|
7040
7127
|
};
|
|
7041
7128
|
}
|
|
7129
|
+
function resolveCustomPrimaryRate(rateContext, serviceMap) {
|
|
7130
|
+
if (!rateContext || rateContext.mode !== "custom_primary_rate") {
|
|
7131
|
+
return void 0;
|
|
7132
|
+
}
|
|
7133
|
+
if (rateContext.source === "manual") {
|
|
7134
|
+
return toFiniteNumber(rateContext.primaryRate);
|
|
7135
|
+
}
|
|
7136
|
+
if (rateContext.primaryServiceId == null) return void 0;
|
|
7137
|
+
const cap = getServiceCapability(serviceMap, rateContext.primaryServiceId);
|
|
7138
|
+
return toFiniteNumber(cap == null ? void 0 : cap.rate);
|
|
7139
|
+
}
|
|
7042
7140
|
function evaluatePoliciesRaw(raw, serviceIds, svcMap, tagId, visibleServiceIds) {
|
|
7043
7141
|
const compiled = compilePolicies(raw);
|
|
7044
7142
|
const evaluated = evaluateServicePolicies(
|
|
@@ -7126,7 +7224,9 @@ function collectVisibleServiceIds(builder, tagId, selectedButtons) {
|
|
|
7126
7224
|
const fields = (_b = props.fields) != null ? _b : [];
|
|
7127
7225
|
const tag = tags.find((t) => t.id === tagId);
|
|
7128
7226
|
if ((tag == null ? void 0 : tag.service_id) != null) out.add(String(tag.service_id));
|
|
7129
|
-
const visibleFieldIds = new Set(
|
|
7227
|
+
const visibleFieldIds = new Set(
|
|
7228
|
+
builder.visibleFields(tagId, selectedButtons)
|
|
7229
|
+
);
|
|
7130
7230
|
for (const field of fields) {
|
|
7131
7231
|
if (!visibleFieldIds.has(field.id)) continue;
|
|
7132
7232
|
if (field.service_id != null) {
|
|
@@ -7149,8 +7249,7 @@ function matchesRuleFilter(cap, rule, tagId) {
|
|
|
7149
7249
|
if (!cap) return false;
|
|
7150
7250
|
const f = rule.filter;
|
|
7151
7251
|
if (!f) return true;
|
|
7152
|
-
|
|
7153
|
-
return true;
|
|
7252
|
+
return !(f.tag_id && !toStrSet(f.tag_id).has(String(tagId)));
|
|
7154
7253
|
}
|
|
7155
7254
|
function toStrSet(v) {
|
|
7156
7255
|
const arr = Array.isArray(v) ? v : [v];
|
|
@@ -7158,6 +7257,107 @@ function toStrSet(v) {
|
|
|
7158
7257
|
for (const x of arr) s.add(String(x));
|
|
7159
7258
|
return s;
|
|
7160
7259
|
}
|
|
7260
|
+
function candidatePassesRateCoherence(builder, serviceMap, tagId, selectedKeys, usedServiceIds, candidateId, ratePolicy) {
|
|
7261
|
+
var _a, _b, _c, _d;
|
|
7262
|
+
if (usedServiceIds.length === 0) return true;
|
|
7263
|
+
const props = builder.getProps();
|
|
7264
|
+
const baseFields = (_a = props.fields) != null ? _a : [];
|
|
7265
|
+
const candidateFieldId = syntheticServiceFieldId("candidate", candidateId, 0);
|
|
7266
|
+
const syntheticFields = [
|
|
7267
|
+
...usedServiceIds.map((serviceId, index) => ({
|
|
7268
|
+
id: syntheticServiceFieldId("used", serviceId, index),
|
|
7269
|
+
label: `Used service ${String(serviceId)}`,
|
|
7270
|
+
type: "custom",
|
|
7271
|
+
button: true,
|
|
7272
|
+
service_id: serviceId,
|
|
7273
|
+
pricing_role: "base"
|
|
7274
|
+
})),
|
|
7275
|
+
{
|
|
7276
|
+
id: candidateFieldId,
|
|
7277
|
+
label: `Candidate ${String(candidateId)}`,
|
|
7278
|
+
type: "custom",
|
|
7279
|
+
button: true,
|
|
7280
|
+
service_id: candidateId,
|
|
7281
|
+
pricing_role: "base"
|
|
7282
|
+
}
|
|
7283
|
+
];
|
|
7284
|
+
const fields = [...baseFields, ...syntheticFields];
|
|
7285
|
+
const visibleFieldIds = [
|
|
7286
|
+
...builder.visibleFields(tagId, selectedKeys),
|
|
7287
|
+
...syntheticFields.map((field) => field.id)
|
|
7288
|
+
];
|
|
7289
|
+
const anchoredFilters = ((_b = props.filters) != null ? _b : []).map(
|
|
7290
|
+
(tag) => tag.id === tagId && usedServiceIds[0] != null ? { ...tag, service_id: usedServiceIds[0] } : tag
|
|
7291
|
+
);
|
|
7292
|
+
const validationProps = {
|
|
7293
|
+
...props,
|
|
7294
|
+
filters: anchoredFilters,
|
|
7295
|
+
fields
|
|
7296
|
+
};
|
|
7297
|
+
const errors = [];
|
|
7298
|
+
const tags = (_c = validationProps.filters) != null ? _c : [];
|
|
7299
|
+
const fieldById = new Map(fields.map((field) => [field.id, field]));
|
|
7300
|
+
const tagById = new Map(tags.map((tag) => [tag.id, tag]));
|
|
7301
|
+
const v = {
|
|
7302
|
+
props: validationProps,
|
|
7303
|
+
nodeMap: buildNodeMap(validationProps),
|
|
7304
|
+
options: {
|
|
7305
|
+
...(_d = builder.getOptions) == null ? void 0 : _d.call(builder),
|
|
7306
|
+
serviceMap,
|
|
7307
|
+
ratePolicy
|
|
7308
|
+
},
|
|
7309
|
+
errors,
|
|
7310
|
+
serviceMap,
|
|
7311
|
+
selectedKeys: new Set(selectedKeys),
|
|
7312
|
+
tags,
|
|
7313
|
+
fields,
|
|
7314
|
+
invalidRateFieldIds: /* @__PURE__ */ new Set(),
|
|
7315
|
+
tagById,
|
|
7316
|
+
fieldById,
|
|
7317
|
+
fieldsVisibleUnder: () => [],
|
|
7318
|
+
simulatedVisibilityContexts: []
|
|
7319
|
+
};
|
|
7320
|
+
validateRateCoherenceForVisibleContext({
|
|
7321
|
+
v,
|
|
7322
|
+
tagId,
|
|
7323
|
+
selectedKeys,
|
|
7324
|
+
visibleFieldIds,
|
|
7325
|
+
effectMap: buildTriggerEffectMap(validationProps),
|
|
7326
|
+
seen: /* @__PURE__ */ new Set()
|
|
7327
|
+
});
|
|
7328
|
+
return !errors.some(
|
|
7329
|
+
(error) => rateIssueAffectsCandidate(
|
|
7330
|
+
error,
|
|
7331
|
+
candidateId,
|
|
7332
|
+
candidateFieldId,
|
|
7333
|
+
usedServiceIds[0]
|
|
7334
|
+
)
|
|
7335
|
+
);
|
|
7336
|
+
}
|
|
7337
|
+
function syntheticServiceFieldId(kind, serviceId, index) {
|
|
7338
|
+
return `__service_filter_${kind}__:${index}:${String(serviceId)}`;
|
|
7339
|
+
}
|
|
7340
|
+
function rateIssueAffectsCandidate(error, candidateId, candidateFieldId, primaryAnchorId) {
|
|
7341
|
+
var _a, _b, _c, _d;
|
|
7342
|
+
if (error.code !== "rate_coherence_violation") return false;
|
|
7343
|
+
const candidateKey = String(candidateId);
|
|
7344
|
+
const details = (_a = error.details) != null ? _a : {};
|
|
7345
|
+
const anchorKey = primaryAnchorId == null ? void 0 : String(primaryAnchorId);
|
|
7346
|
+
const primaryMatchesAnchor = anchorKey == null || String((_b = details.primary) == null ? void 0 : _b.serviceId) === anchorKey || String((_c = details.primary) == null ? void 0 : _c.service_id) === anchorKey;
|
|
7347
|
+
if (primaryMatchesAnchor && ((_d = details.affectedServiceIds) == null ? void 0 : _d.some(
|
|
7348
|
+
(serviceId) => String(serviceId) === candidateKey
|
|
7349
|
+
))) {
|
|
7350
|
+
return true;
|
|
7351
|
+
}
|
|
7352
|
+
if (primaryMatchesAnchor && String(error.nodeId) === candidateFieldId) {
|
|
7353
|
+
return true;
|
|
7354
|
+
}
|
|
7355
|
+
return [details.primary, details.candidate].some((ref) => {
|
|
7356
|
+
if (!ref) return false;
|
|
7357
|
+
if (!primaryMatchesAnchor) return false;
|
|
7358
|
+
return String(ref.serviceId) === candidateKey || String(ref.service_id) === candidateKey || String(ref.fieldId) === candidateFieldId || String(ref.nodeId) === candidateFieldId;
|
|
7359
|
+
});
|
|
7360
|
+
}
|
|
7161
7361
|
|
|
7162
7362
|
// src/react/canvas/editor/editor-ids.ts
|
|
7163
7363
|
function uniqueId(ctx, base) {
|
|
@@ -7787,7 +7987,7 @@ function setService(ctx, id, input) {
|
|
|
7787
7987
|
);
|
|
7788
7988
|
}
|
|
7789
7989
|
const isOptionBased = Array.isArray(f.options) && f.options.length > 0;
|
|
7790
|
-
const
|
|
7990
|
+
const isButton = !!f.button;
|
|
7791
7991
|
if (nextRole) {
|
|
7792
7992
|
f.pricing_role = nextRole;
|
|
7793
7993
|
}
|
|
@@ -7803,7 +8003,7 @@ function setService(ctx, id, input) {
|
|
|
7803
8003
|
if ("service_id" in f) delete f.service_id;
|
|
7804
8004
|
return;
|
|
7805
8005
|
}
|
|
7806
|
-
if (!
|
|
8006
|
+
if (!isButton) {
|
|
7807
8007
|
if (hasSidKey) {
|
|
7808
8008
|
ctx.api.emit("error", {
|
|
7809
8009
|
message: "Only button fields (without options) can have a service_id.",
|
|
@@ -8827,7 +9027,8 @@ function filterServicesForVisibleGroup2(ctx, candidates, input) {
|
|
|
8827
9027
|
policies: input.policies,
|
|
8828
9028
|
ratePolicy: input.ratePolicy,
|
|
8829
9029
|
fallbackSettings: input.fallbackSettings,
|
|
8830
|
-
fallback: input.fallback
|
|
9030
|
+
fallback: input.fallback,
|
|
9031
|
+
rateContext: input.rateContext
|
|
8831
9032
|
}
|
|
8832
9033
|
};
|
|
8833
9034
|
const result = filterServicesForVisibleGroup(coreInput, {
|
|
@@ -10985,18 +11186,23 @@ function useErrors(opts = {}) {
|
|
|
10985
11186
|
setValidating(true);
|
|
10986
11187
|
schedule(
|
|
10987
11188
|
() => {
|
|
10988
|
-
var _a2, _b2, _c2, _d2, _e2;
|
|
11189
|
+
var _a2, _b2, _c2, _d2, _e2, _f, _g;
|
|
10989
11190
|
if (token !== runTokenRef.current) return;
|
|
10990
11191
|
try {
|
|
10991
11192
|
const props = api.editor.getProps();
|
|
10992
|
-
const
|
|
11193
|
+
const builderOptions = (_c2 = (_b2 = (_a2 = api.builder).getOptions) == null ? void 0 : _b2.call(_a2)) != null ? _c2 : {};
|
|
11194
|
+
const res = validate(props, {
|
|
11195
|
+
...builderOptions,
|
|
11196
|
+
simulateVisibility: (_d2 = builderOptions.simulateVisibility) != null ? _d2 : true,
|
|
11197
|
+
visibilityOnlyEffectfulTriggers: (_e2 = builderOptions.visibilityOnlyEffectfulTriggers) != null ? _e2 : true
|
|
11198
|
+
});
|
|
10993
11199
|
if (token !== runTokenRef.current) return;
|
|
10994
11200
|
setValidation(toValidationRows(res != null ? res : []));
|
|
10995
11201
|
} catch (err) {
|
|
10996
11202
|
if (token !== runTokenRef.current) return;
|
|
10997
11203
|
pushLog({
|
|
10998
|
-
message: (
|
|
10999
|
-
code: (
|
|
11204
|
+
message: (_f = err == null ? void 0 : err.message) != null ? _f : "validate() threw",
|
|
11205
|
+
code: (_g = err == null ? void 0 : err.code) != null ? _g : "validate_throw",
|
|
11000
11206
|
meta: err
|
|
11001
11207
|
});
|
|
11002
11208
|
setValidation([]);
|