@timeax/digital-service-engine 0.3.1 → 0.3.3
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 +471 -434
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +1 -8
- package/dist/core/index.d.ts +1 -8
- package/dist/core/index.js +471 -434
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +1636 -1145
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +66 -29
- package/dist/react/index.d.ts +66 -29
- package/dist/react/index.js +1635 -1145
- package/dist/react/index.js.map +1 -1
- package/dist/workspace/index.cjs +651 -173
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +71 -24
- package/dist/workspace/index.d.ts +71 -24
- package/dist/workspace/index.js +650 -173
- package/dist/workspace/index.js.map +1 -1
- package/package.json +2 -2
package/dist/core/index.js
CHANGED
|
@@ -4664,141 +4664,74 @@ function toBindArray(bind) {
|
|
|
4664
4664
|
return Array.isArray(bind) ? bind.slice() : [bind];
|
|
4665
4665
|
}
|
|
4666
4666
|
|
|
4667
|
-
// src/utils/build-order-snapshot.ts
|
|
4668
|
-
function
|
|
4669
|
-
var _a, _b
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
const tagId = selection.activeTagId;
|
|
4683
|
-
const selectedButtonKeys = (_d = selection.selectedKeys) != null ? _d : toSelectedOptionKeys(selection.optionSelectionsByFieldId);
|
|
4684
|
-
const visibleFieldIds = builder.visibleFields(
|
|
4685
|
-
tagId,
|
|
4686
|
-
selectedButtonKeys
|
|
4687
|
-
);
|
|
4688
|
-
const tagById = new Map(
|
|
4689
|
-
((_e = props.filters) != null ? _e : []).map((t) => [t.id, t])
|
|
4690
|
-
);
|
|
4691
|
-
const fieldById = new Map(
|
|
4692
|
-
((_f = props.fields) != null ? _f : []).map((f) => [f.id, f])
|
|
4693
|
-
);
|
|
4694
|
-
const tagConstraints = (_h = (_g = tagById.get(tagId)) == null ? void 0 : _g.constraints) != null ? _h : void 0;
|
|
4695
|
-
const selectionFields = visibleFieldIds.map((fid) => fieldById.get(fid)).filter((f) => !!f).map((f) => {
|
|
4696
|
-
var _a2;
|
|
4697
|
-
const optIds = isOptionBased(f) ? (_a2 = selection.optionSelectionsByFieldId[f.id]) != null ? _a2 : [] : void 0;
|
|
4667
|
+
// src/utils/build-order-snapshot/fallbacks.ts
|
|
4668
|
+
function pruneFallbacksConservative(fallbacks, env, svcMap, policy) {
|
|
4669
|
+
var _a, _b;
|
|
4670
|
+
if (!fallbacks) return { pruned: void 0, original: void 0 };
|
|
4671
|
+
try {
|
|
4672
|
+
const { props: prunedProps } = pruneInvalidNodeFallbacks(
|
|
4673
|
+
{
|
|
4674
|
+
filters: [],
|
|
4675
|
+
fields: [],
|
|
4676
|
+
schema_version: "1.0",
|
|
4677
|
+
fallbacks
|
|
4678
|
+
},
|
|
4679
|
+
svcMap,
|
|
4680
|
+
policy
|
|
4681
|
+
);
|
|
4698
4682
|
return {
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
...optIds && optIds.length ? { selectedOptions: optIds } : {}
|
|
4683
|
+
pruned: prunedProps.fallbacks,
|
|
4684
|
+
original: fallbacks
|
|
4702
4685
|
};
|
|
4703
|
-
}
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
selection,
|
|
4723
|
-
tagById,
|
|
4724
|
-
fieldById
|
|
4725
|
-
);
|
|
4726
|
-
const { min, max } = resolveMinMax(servicesList, services);
|
|
4727
|
-
const maybeNodeMap = typeof builder.getNodeMap === "function" ? builder.getNodeMap() : void 0;
|
|
4728
|
-
const resolvedOrderKind = resolveOrderKind({
|
|
4729
|
-
props,
|
|
4730
|
-
activeTagId: tagId,
|
|
4731
|
-
selectedTriggerKeys: selectedButtonKeys,
|
|
4732
|
-
nodeMap: maybeNodeMap
|
|
4733
|
-
});
|
|
4734
|
-
const prunedFallbacks = pruneFallbacksConservative(
|
|
4735
|
-
props.fallbacks,
|
|
4736
|
-
{ tagId, constraints: tagConstraints, serviceMap, servicesList },
|
|
4737
|
-
services,
|
|
4738
|
-
fbSettings
|
|
4739
|
-
);
|
|
4740
|
-
const utilities = collectUtilityLineItems(
|
|
4741
|
-
visibleFieldIds,
|
|
4742
|
-
fieldById,
|
|
4743
|
-
selection,
|
|
4744
|
-
quantity
|
|
4745
|
-
);
|
|
4746
|
-
const warnings = mode === "dev" ? buildDevWarnings(
|
|
4747
|
-
props,
|
|
4748
|
-
services,
|
|
4749
|
-
tagId,
|
|
4750
|
-
serviceMap,
|
|
4751
|
-
prunedFallbacks.original,
|
|
4752
|
-
prunedFallbacks.pruned,
|
|
4753
|
-
fieldById,
|
|
4754
|
-
visibleFieldIds,
|
|
4755
|
-
selection
|
|
4756
|
-
) : void 0;
|
|
4757
|
-
const snapshotPolicy = toSnapshotPolicy(fbSettings);
|
|
4758
|
-
const meta = {
|
|
4759
|
-
schema_version: props.schema_version,
|
|
4760
|
-
workspaceId: settings.workspaceId,
|
|
4761
|
-
builder: settings.builderCommit ? { commit: settings.builderCommit } : void 0,
|
|
4762
|
-
context: {
|
|
4763
|
-
tag: tagId,
|
|
4764
|
-
constraints: tagConstraints != null ? tagConstraints : {},
|
|
4765
|
-
nodeContexts: buildNodeContexts(
|
|
4766
|
-
tagId,
|
|
4767
|
-
visibleFieldIds,
|
|
4768
|
-
fieldById,
|
|
4769
|
-
selection
|
|
4770
|
-
),
|
|
4771
|
-
policy: snapshotPolicy
|
|
4686
|
+
} catch {
|
|
4687
|
+
const out = {};
|
|
4688
|
+
const requireFit = (_a = policy.requireConstraintFit) != null ? _a : true;
|
|
4689
|
+
if (fallbacks.nodes) {
|
|
4690
|
+
const keptNodes = {};
|
|
4691
|
+
for (const [nodeId, candidates] of Object.entries(
|
|
4692
|
+
fallbacks.nodes
|
|
4693
|
+
)) {
|
|
4694
|
+
if (!env.serviceMap[nodeId]) continue;
|
|
4695
|
+
const primary = ((_b = env.serviceMap[nodeId]) != null ? _b : [])[0];
|
|
4696
|
+
const kept = [];
|
|
4697
|
+
for (const cand of candidates != null ? candidates : []) {
|
|
4698
|
+
if (!rateOk(svcMap, cand, primary, policy)) continue;
|
|
4699
|
+
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints)) continue;
|
|
4700
|
+
kept.push(cand);
|
|
4701
|
+
}
|
|
4702
|
+
if (kept.length) keptNodes[nodeId] = kept;
|
|
4703
|
+
}
|
|
4704
|
+
if (Object.keys(keptNodes).length) out.nodes = keptNodes;
|
|
4772
4705
|
}
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
};
|
|
4800
|
-
return snapshot;
|
|
4706
|
+
if (fallbacks.global) {
|
|
4707
|
+
const keptGlobal = {};
|
|
4708
|
+
const present = new Set(env.servicesList.map((sid) => String(sid)));
|
|
4709
|
+
for (const [primary, cands] of Object.entries(
|
|
4710
|
+
fallbacks.global
|
|
4711
|
+
)) {
|
|
4712
|
+
if (!present.has(String(primary))) continue;
|
|
4713
|
+
const primId = isFiniteNumber2(primary) ? Number(primary) : primary;
|
|
4714
|
+
const kept = [];
|
|
4715
|
+
for (const cand of cands != null ? cands : []) {
|
|
4716
|
+
if (!rateOk(svcMap, cand, primId, policy)) continue;
|
|
4717
|
+
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints)) continue;
|
|
4718
|
+
kept.push(cand);
|
|
4719
|
+
}
|
|
4720
|
+
if (kept.length) keptGlobal[primId] = kept;
|
|
4721
|
+
}
|
|
4722
|
+
if (Object.keys(keptGlobal).length) out.global = keptGlobal;
|
|
4723
|
+
}
|
|
4724
|
+
return {
|
|
4725
|
+
pruned: Object.keys(out).length ? out : void 0,
|
|
4726
|
+
original: fallbacks
|
|
4727
|
+
};
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
function isFiniteNumber2(v) {
|
|
4731
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
4801
4732
|
}
|
|
4733
|
+
|
|
4734
|
+
// src/utils/build-order-snapshot/selection.ts
|
|
4802
4735
|
function isOptionBased(f) {
|
|
4803
4736
|
const hasOptions = Array.isArray(f.options) && f.options.length > 0;
|
|
4804
4737
|
return hasOptions || isMultiField(f);
|
|
@@ -4806,50 +4739,227 @@ function isOptionBased(f) {
|
|
|
4806
4739
|
function toSelectedOptionKeys(byField) {
|
|
4807
4740
|
const keys = [];
|
|
4808
4741
|
for (const [fieldId, optionIds] of Object.entries(byField != null ? byField : {})) {
|
|
4809
|
-
for (const
|
|
4810
|
-
keys.push(`${fieldId}::${
|
|
4742
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
4743
|
+
keys.push(`${fieldId}::${optionId}`);
|
|
4811
4744
|
}
|
|
4812
4745
|
}
|
|
4813
4746
|
return keys;
|
|
4814
4747
|
}
|
|
4815
|
-
function
|
|
4816
|
-
|
|
4817
|
-
|
|
4748
|
+
function getSelectedOptionsByFieldId(selection, fieldById) {
|
|
4749
|
+
const out = {};
|
|
4750
|
+
for (const visit of buildSelectedNodeVisitOrder(selection, fieldById)) {
|
|
4751
|
+
if (visit.kind !== "option") continue;
|
|
4752
|
+
if (!out[visit.fieldId]) out[visit.fieldId] = [];
|
|
4753
|
+
out[visit.fieldId].push(visit.optionId);
|
|
4754
|
+
}
|
|
4755
|
+
return out;
|
|
4756
|
+
}
|
|
4757
|
+
function buildSelectedNodeVisitOrder(selection, fieldById) {
|
|
4758
|
+
var _a, _b, _c;
|
|
4759
|
+
const out = [];
|
|
4760
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4761
|
+
function pushField(fieldId) {
|
|
4762
|
+
const key = `field:${fieldId}`;
|
|
4763
|
+
if (seen.has(key)) return;
|
|
4764
|
+
seen.add(key);
|
|
4765
|
+
out.push({ kind: "field", fieldId });
|
|
4766
|
+
}
|
|
4767
|
+
function pushOption(fieldId, optionId) {
|
|
4768
|
+
const key = `option:${fieldId}::${optionId}`;
|
|
4769
|
+
if (seen.has(key)) return;
|
|
4770
|
+
seen.add(key);
|
|
4771
|
+
out.push({ kind: "option", fieldId, optionId });
|
|
4772
|
+
}
|
|
4773
|
+
for (const item of (_a = selection.optionTraversalOrder) != null ? _a : []) {
|
|
4774
|
+
pushOption(item.fieldId, item.optionId);
|
|
4775
|
+
}
|
|
4776
|
+
for (const rawKey of (_b = selection.selectedKeys) != null ? _b : []) {
|
|
4777
|
+
const key = String(rawKey);
|
|
4778
|
+
if (key.includes("::")) {
|
|
4779
|
+
const [fieldId, optionId] = key.split("::", 2);
|
|
4780
|
+
if (fieldId && optionId) pushOption(fieldId, optionId);
|
|
4781
|
+
continue;
|
|
4782
|
+
}
|
|
4783
|
+
const field = fieldById.get(key);
|
|
4784
|
+
if (field) {
|
|
4785
|
+
pushField(field.id);
|
|
4786
|
+
continue;
|
|
4787
|
+
}
|
|
4788
|
+
const ownerField = findOptionOwnerField(key, fieldById);
|
|
4789
|
+
if (ownerField) pushOption(ownerField.id, key);
|
|
4790
|
+
}
|
|
4791
|
+
for (const [fieldId, optionIds] of Object.entries(
|
|
4792
|
+
(_c = selection.optionSelectionsByFieldId) != null ? _c : {}
|
|
4793
|
+
)) {
|
|
4794
|
+
if (!fieldById.has(fieldId)) continue;
|
|
4795
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
4796
|
+
pushOption(fieldId, optionId);
|
|
4797
|
+
}
|
|
4798
|
+
}
|
|
4799
|
+
return out;
|
|
4800
|
+
}
|
|
4801
|
+
function findOptionOwnerField(optionId, fieldById) {
|
|
4802
|
+
var _a;
|
|
4803
|
+
for (const field of fieldById.values()) {
|
|
4804
|
+
if ((_a = field.options) == null ? void 0 : _a.some((option) => option.id === optionId)) return field;
|
|
4805
|
+
}
|
|
4806
|
+
return void 0;
|
|
4807
|
+
}
|
|
4808
|
+
|
|
4809
|
+
// src/utils/build-order-snapshot/services.ts
|
|
4810
|
+
function isServiceBased(field) {
|
|
4811
|
+
var _a;
|
|
4812
|
+
if (field.service_id !== void 0 && field.service_id !== null) return true;
|
|
4813
|
+
return !!((_a = field.options) == null ? void 0 : _a.some(
|
|
4814
|
+
(item) => item.service_id !== void 0 && item.service_id !== null
|
|
4815
|
+
));
|
|
4818
4816
|
}
|
|
4819
|
-
function
|
|
4817
|
+
function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById, services) {
|
|
4818
|
+
var _a, _b, _c, _d;
|
|
4819
|
+
const serviceMap = {};
|
|
4820
|
+
const visible = new Set(visibleFieldIds);
|
|
4821
|
+
const selectedBaseServices = [];
|
|
4822
|
+
const visits = buildSelectedNodeVisitOrder(selection, fieldById);
|
|
4823
|
+
let index = 0;
|
|
4824
|
+
function addSelectedBaseService(origin, sid) {
|
|
4825
|
+
pushService(serviceMap, origin, sid);
|
|
4826
|
+
selectedBaseServices.push({
|
|
4827
|
+
origin,
|
|
4828
|
+
sid,
|
|
4829
|
+
rate: readServiceRate(services, sid),
|
|
4830
|
+
index: index++
|
|
4831
|
+
});
|
|
4832
|
+
}
|
|
4833
|
+
for (const visit of visits) {
|
|
4834
|
+
if (!visible.has(visit.fieldId)) continue;
|
|
4835
|
+
const field = fieldById.get(visit.fieldId);
|
|
4836
|
+
if (!field) continue;
|
|
4837
|
+
if (visit.kind === "field") {
|
|
4838
|
+
const role2 = (_a = field.pricing_role) != null ? _a : "base";
|
|
4839
|
+
if (role2 === "utility") continue;
|
|
4840
|
+
if (field.service_id !== void 0 && field.service_id !== null) {
|
|
4841
|
+
addSelectedBaseService(field.id, field.service_id);
|
|
4842
|
+
}
|
|
4843
|
+
continue;
|
|
4844
|
+
}
|
|
4845
|
+
const option = (_b = field.options) == null ? void 0 : _b.find((item) => item.id === visit.optionId);
|
|
4846
|
+
if (!option) continue;
|
|
4847
|
+
const role = (_d = (_c = option.pricing_role) != null ? _c : field.pricing_role) != null ? _d : "base";
|
|
4848
|
+
if (role === "utility") continue;
|
|
4849
|
+
if (option.service_id !== void 0 && option.service_id !== null) {
|
|
4850
|
+
addSelectedBaseService(option.id, option.service_id);
|
|
4851
|
+
}
|
|
4852
|
+
}
|
|
4853
|
+
if (selectedBaseServices.length > 0) {
|
|
4854
|
+
const primary = pickHighestRatePrimary2(selectedBaseServices);
|
|
4855
|
+
const ordered = [
|
|
4856
|
+
primary.sid,
|
|
4857
|
+
...selectedBaseServices.filter((item) => item !== primary).sort((a, b) => a.index - b.index).map((item) => item.sid)
|
|
4858
|
+
];
|
|
4859
|
+
return { serviceMap, servicesList: dedupeByString(ordered) };
|
|
4860
|
+
}
|
|
4861
|
+
const tag = tagById.get(tagId);
|
|
4862
|
+
if ((tag == null ? void 0 : tag.service_id) !== void 0 && tag.service_id !== null) {
|
|
4863
|
+
pushService(serviceMap, tagId, tag.service_id);
|
|
4864
|
+
return { serviceMap, servicesList: [tag.service_id] };
|
|
4865
|
+
}
|
|
4866
|
+
return { serviceMap, servicesList: [] };
|
|
4867
|
+
}
|
|
4868
|
+
function pickHighestRatePrimary2(services) {
|
|
4869
|
+
let best = services[0];
|
|
4870
|
+
for (const item of services.slice(1)) {
|
|
4871
|
+
if (item.rate > best.rate) best = item;
|
|
4872
|
+
}
|
|
4873
|
+
return best;
|
|
4874
|
+
}
|
|
4875
|
+
function getCap2(map, id) {
|
|
4876
|
+
var _a;
|
|
4877
|
+
return (_a = map == null ? void 0 : map[id]) != null ? _a : map == null ? void 0 : map[String(id)];
|
|
4878
|
+
}
|
|
4879
|
+
function readServiceRate(services, sid) {
|
|
4880
|
+
var _a;
|
|
4881
|
+
const rate = Number((_a = getCap2(services, sid)) == null ? void 0 : _a.rate);
|
|
4882
|
+
return Number.isFinite(rate) ? rate : Number.NEGATIVE_INFINITY;
|
|
4883
|
+
}
|
|
4884
|
+
function pushService(map, nodeId, sid) {
|
|
4885
|
+
if (!map[nodeId]) map[nodeId] = [];
|
|
4886
|
+
map[nodeId].push(sid);
|
|
4887
|
+
}
|
|
4888
|
+
function dedupeByString(arr) {
|
|
4889
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4890
|
+
const out = [];
|
|
4891
|
+
for (const value of arr) {
|
|
4892
|
+
const key = String(value);
|
|
4893
|
+
if (seen.has(key)) continue;
|
|
4894
|
+
seen.add(key);
|
|
4895
|
+
out.push(value);
|
|
4896
|
+
}
|
|
4897
|
+
return out;
|
|
4898
|
+
}
|
|
4899
|
+
|
|
4900
|
+
// src/utils/build-order-snapshot/inputs.ts
|
|
4901
|
+
function buildInputs(visibleFieldIds, fieldById, selection, selectedOptionsByFieldId) {
|
|
4820
4902
|
const formValues = {};
|
|
4821
4903
|
const selections = {};
|
|
4822
4904
|
for (const fid of visibleFieldIds) {
|
|
4823
|
-
const
|
|
4824
|
-
if (!
|
|
4825
|
-
const
|
|
4826
|
-
if (
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
if (!name || val === void 0) continue;
|
|
4833
|
-
formValues[name] = val;
|
|
4905
|
+
const field = fieldById.get(fid);
|
|
4906
|
+
if (!field) continue;
|
|
4907
|
+
const selectedOptionIds = selectedOptionsByFieldId[fid];
|
|
4908
|
+
if (selectedOptionIds == null ? void 0 : selectedOptionIds.length) selections[fid] = [...selectedOptionIds];
|
|
4909
|
+
if (!isServiceBased(field)) {
|
|
4910
|
+
const name = field.name;
|
|
4911
|
+
const value = selection.formValuesByFieldId[fid];
|
|
4912
|
+
if (!name || value === void 0) continue;
|
|
4913
|
+
formValues[name] = value;
|
|
4834
4914
|
}
|
|
4835
4915
|
}
|
|
4836
4916
|
return { formValues, selections };
|
|
4837
4917
|
}
|
|
4918
|
+
|
|
4919
|
+
// src/utils/build-order-snapshot/min-max.ts
|
|
4920
|
+
function getCap3(map, id) {
|
|
4921
|
+
var _a;
|
|
4922
|
+
return (_a = map == null ? void 0 : map[id]) != null ? _a : map == null ? void 0 : map[String(id)];
|
|
4923
|
+
}
|
|
4924
|
+
function resolveMinMax(servicesList, services) {
|
|
4925
|
+
let min;
|
|
4926
|
+
let max;
|
|
4927
|
+
for (const sid of servicesList) {
|
|
4928
|
+
const cap = getCap3(services, sid);
|
|
4929
|
+
if (!cap) continue;
|
|
4930
|
+
if (typeof cap.min === "number" && Number.isFinite(cap.min)) {
|
|
4931
|
+
min = min === void 0 ? cap.min : Math.min(min, cap.min);
|
|
4932
|
+
}
|
|
4933
|
+
if (typeof cap.max === "number" && Number.isFinite(cap.max)) {
|
|
4934
|
+
max = max === void 0 ? cap.max : Math.max(max, cap.max);
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4937
|
+
return { min: min != null ? min : 1, ...max !== void 0 ? { max } : {} };
|
|
4938
|
+
}
|
|
4939
|
+
|
|
4940
|
+
// src/utils/build-order-snapshot/policy.ts
|
|
4941
|
+
function toSnapshotPolicy(settings) {
|
|
4942
|
+
var _a;
|
|
4943
|
+
return {
|
|
4944
|
+
ratePolicy: normalizeRatePolicy(settings.ratePolicy),
|
|
4945
|
+
requireConstraintFit: (_a = settings.requireConstraintFit) != null ? _a : true
|
|
4946
|
+
};
|
|
4947
|
+
}
|
|
4948
|
+
|
|
4949
|
+
// src/utils/build-order-snapshot/quantity.ts
|
|
4838
4950
|
function resolveQuantity(visibleFieldIds, fieldById, tagById, selection, tagId, hostDefault) {
|
|
4839
4951
|
var _a;
|
|
4840
4952
|
for (const fid of visibleFieldIds) {
|
|
4841
|
-
const
|
|
4842
|
-
if (!
|
|
4843
|
-
const rule = readQuantityRule(
|
|
4844
|
-
(_a = f.meta) == null ? void 0 : _a.quantity
|
|
4845
|
-
);
|
|
4953
|
+
const field = fieldById.get(fid);
|
|
4954
|
+
if (!field) continue;
|
|
4955
|
+
const rule = readQuantityRule((_a = field.meta) == null ? void 0 : _a.quantity);
|
|
4846
4956
|
if (!rule) continue;
|
|
4847
4957
|
const raw = selection.formValuesByFieldId[fid];
|
|
4848
4958
|
const evaluated = evaluateQuantityRule(rule, raw);
|
|
4849
4959
|
if (Number.isFinite(evaluated) && evaluated > 0) {
|
|
4850
4960
|
return {
|
|
4851
4961
|
quantity: evaluated,
|
|
4852
|
-
source: { kind: "field", id:
|
|
4962
|
+
source: { kind: "field", id: field.id, rule }
|
|
4853
4963
|
};
|
|
4854
4964
|
}
|
|
4855
4965
|
break;
|
|
@@ -4862,24 +4972,47 @@ function resolveQuantity(visibleFieldIds, fieldById, tagById, selection, tagId,
|
|
|
4862
4972
|
tagId
|
|
4863
4973
|
);
|
|
4864
4974
|
if (nodeDefault) return nodeDefault;
|
|
4865
|
-
return {
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4975
|
+
return { quantity: hostDefault, source: { kind: "default", defaultedFromHost: true } };
|
|
4976
|
+
}
|
|
4977
|
+
function resolveNodeDefaultQuantity(visibleFieldIds, fieldById, tagById, selection, tagId) {
|
|
4978
|
+
var _a, _b, _c;
|
|
4979
|
+
const visible = new Set(visibleFieldIds);
|
|
4980
|
+
const visits = buildSelectedNodeVisitOrder(selection, fieldById);
|
|
4981
|
+
for (const visit of visits) {
|
|
4982
|
+
if (visit.kind !== "option") continue;
|
|
4983
|
+
if (!visible.has(visit.fieldId)) continue;
|
|
4984
|
+
const field = fieldById.get(visit.fieldId);
|
|
4985
|
+
if (!((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.length)) continue;
|
|
4986
|
+
const option = field.options.find((item) => item.id === visit.optionId);
|
|
4987
|
+
const quantity = readPositiveFiniteNumber((_b = option == null ? void 0 : option.meta) == null ? void 0 : _b.quantityDefault);
|
|
4988
|
+
if (quantity !== void 0) {
|
|
4989
|
+
return { quantity, source: { kind: "option", id: option.id } };
|
|
4990
|
+
}
|
|
4991
|
+
}
|
|
4992
|
+
for (const visit of visits) {
|
|
4993
|
+
if (!visible.has(visit.fieldId)) continue;
|
|
4994
|
+
const field = fieldById.get(visit.fieldId);
|
|
4995
|
+
if (!field) continue;
|
|
4996
|
+
const quantity = readPositiveFiniteNumber(field.quantityDefault);
|
|
4997
|
+
if (quantity !== void 0) {
|
|
4998
|
+
return { quantity, source: { kind: "field", id: field.id } };
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
const tag = tagById.get(tagId);
|
|
5002
|
+
const tagQuantity = readPositiveFiniteNumber((_c = tag == null ? void 0 : tag.meta) == null ? void 0 : _c.quantityDefault);
|
|
5003
|
+
if (tagQuantity !== void 0) {
|
|
5004
|
+
return { quantity: tagQuantity, source: { kind: "tag", id: tagId } };
|
|
5005
|
+
}
|
|
5006
|
+
return void 0;
|
|
4869
5007
|
}
|
|
4870
5008
|
function readQuantityRule(v) {
|
|
4871
5009
|
if (!v || typeof v !== "object") return void 0;
|
|
4872
5010
|
const src = v;
|
|
4873
|
-
if (src.valueBy !== "value" && src.valueBy !== "length" && src.valueBy !== "eval")
|
|
4874
|
-
return void 0;
|
|
5011
|
+
if (src.valueBy !== "value" && src.valueBy !== "length" && src.valueBy !== "eval") return void 0;
|
|
4875
5012
|
const out = { valueBy: src.valueBy };
|
|
4876
5013
|
if (src.code && typeof src.code === "string") out.code = src.code;
|
|
4877
|
-
if (typeof src.multiply === "number" && Number.isFinite(src.multiply))
|
|
4878
|
-
|
|
4879
|
-
}
|
|
4880
|
-
if (typeof src.fallback === "number" && Number.isFinite(src.fallback)) {
|
|
4881
|
-
out.fallback = src.fallback;
|
|
4882
|
-
}
|
|
5014
|
+
if (typeof src.multiply === "number" && Number.isFinite(src.multiply)) out.multiply = src.multiply;
|
|
5015
|
+
if (typeof src.fallback === "number" && Number.isFinite(src.fallback)) out.fallback = src.fallback;
|
|
4883
5016
|
if (src.clamp && typeof src.clamp === "object") {
|
|
4884
5017
|
const min = typeof src.clamp.min === "number" && Number.isFinite(src.clamp.min) ? src.clamp.min : void 0;
|
|
4885
5018
|
const max = typeof src.clamp.max === "number" && Number.isFinite(src.clamp.max) ? src.clamp.max : void 0;
|
|
@@ -4950,231 +5083,43 @@ function applyClamp(value, clamp2) {
|
|
|
4950
5083
|
if ((clamp2 == null ? void 0 : clamp2.max) !== void 0) next = Math.min(next, clamp2.max);
|
|
4951
5084
|
return next;
|
|
4952
5085
|
}
|
|
4953
|
-
function
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
for (const { fieldId, optionId } of optionVisit) {
|
|
4957
|
-
if (!visibleFieldIds.includes(fieldId)) continue;
|
|
4958
|
-
const field = fieldById.get(fieldId);
|
|
4959
|
-
const option = (_a = field == null ? void 0 : field.options) == null ? void 0 : _a.find((item) => item.id === optionId);
|
|
4960
|
-
const quantityDefault = readQuantityDefault(
|
|
4961
|
-
(_b = option == null ? void 0 : option.meta) == null ? void 0 : _b.quantityDefault
|
|
4962
|
-
);
|
|
4963
|
-
if (quantityDefault !== void 0) {
|
|
4964
|
-
return {
|
|
4965
|
-
quantity: quantityDefault,
|
|
4966
|
-
source: { kind: "option", id: optionId }
|
|
4967
|
-
};
|
|
4968
|
-
}
|
|
4969
|
-
}
|
|
4970
|
-
for (const fieldId of visibleFieldIds) {
|
|
4971
|
-
const field = fieldById.get(fieldId);
|
|
4972
|
-
if (!field) continue;
|
|
4973
|
-
const isButtonStyle = field.button === true || Array.isArray(field.options) && field.options.length > 0;
|
|
4974
|
-
if (!isButtonStyle) continue;
|
|
4975
|
-
const quantityDefault = readQuantityDefault(
|
|
4976
|
-
field.quantityDefault
|
|
4977
|
-
);
|
|
4978
|
-
if (quantityDefault !== void 0) {
|
|
4979
|
-
return {
|
|
4980
|
-
quantity: quantityDefault,
|
|
4981
|
-
source: { kind: "field", id: field.id }
|
|
4982
|
-
};
|
|
4983
|
-
}
|
|
4984
|
-
}
|
|
4985
|
-
const tagQuantityDefault = readQuantityDefault(
|
|
4986
|
-
(_d = (_c = tagById.get(tagId)) == null ? void 0 : _c.meta) == null ? void 0 : _d.quantityDefault
|
|
4987
|
-
);
|
|
4988
|
-
if (tagQuantityDefault !== void 0) {
|
|
4989
|
-
return {
|
|
4990
|
-
quantity: tagQuantityDefault,
|
|
4991
|
-
source: { kind: "tag", id: tagId }
|
|
4992
|
-
};
|
|
4993
|
-
}
|
|
4994
|
-
return void 0;
|
|
4995
|
-
}
|
|
4996
|
-
function readQuantityDefault(value) {
|
|
4997
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
4998
|
-
}
|
|
4999
|
-
function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById) {
|
|
5000
|
-
var _a;
|
|
5001
|
-
const serviceMap = {};
|
|
5002
|
-
const ordered = [];
|
|
5003
|
-
const tag = tagById.get(tagId);
|
|
5004
|
-
let primary;
|
|
5005
|
-
let primaryOrigin;
|
|
5006
|
-
if ((tag == null ? void 0 : tag.service_id) !== void 0) {
|
|
5007
|
-
primary = tag.service_id;
|
|
5008
|
-
primaryOrigin = "tag";
|
|
5009
|
-
}
|
|
5010
|
-
const optionVisit = buildOptionVisitOrder(selection, fieldById);
|
|
5011
|
-
for (const { fieldId, optionId } of optionVisit) {
|
|
5012
|
-
if (!visibleFieldIds.includes(fieldId)) continue;
|
|
5013
|
-
const f = fieldById.get(fieldId);
|
|
5014
|
-
if (!f || !Array.isArray(f.options)) continue;
|
|
5015
|
-
const opt = f.options.find((o) => o.id === optionId);
|
|
5016
|
-
if (!opt) continue;
|
|
5017
|
-
const role = (_a = opt.pricing_role) != null ? _a : "base";
|
|
5018
|
-
const sid = opt.service_id;
|
|
5019
|
-
if (role === "utility") continue;
|
|
5020
|
-
if (sid !== void 0) {
|
|
5021
|
-
if (primary === void 0 || primaryOrigin === "tag") {
|
|
5022
|
-
primary = sid;
|
|
5023
|
-
primaryOrigin = "option";
|
|
5024
|
-
ordered.length = 0;
|
|
5025
|
-
ordered.push(primary);
|
|
5026
|
-
} else {
|
|
5027
|
-
ordered.push(sid);
|
|
5028
|
-
}
|
|
5029
|
-
pushService(serviceMap, optionId, sid);
|
|
5030
|
-
}
|
|
5031
|
-
}
|
|
5032
|
-
if (primaryOrigin !== "option" && primary !== void 0) {
|
|
5033
|
-
ordered.unshift(primary);
|
|
5034
|
-
pushService(serviceMap, tagId, primary);
|
|
5035
|
-
} else {
|
|
5036
|
-
}
|
|
5037
|
-
const servicesList = dedupeByString(ordered);
|
|
5038
|
-
return { serviceMap, servicesList };
|
|
5039
|
-
}
|
|
5040
|
-
function buildOptionVisitOrder(selection, fieldById) {
|
|
5041
|
-
var _a;
|
|
5042
|
-
if (selection.optionTraversalOrder && selection.optionTraversalOrder.length) {
|
|
5043
|
-
return selection.optionTraversalOrder.slice();
|
|
5044
|
-
}
|
|
5045
|
-
const out = [];
|
|
5046
|
-
for (const [fid, optIds] of Object.entries(
|
|
5047
|
-
(_a = selection.optionSelectionsByFieldId) != null ? _a : {}
|
|
5048
|
-
)) {
|
|
5049
|
-
const f = fieldById.get(fid);
|
|
5050
|
-
if (!f) continue;
|
|
5051
|
-
for (const oid of optIds != null ? optIds : [])
|
|
5052
|
-
out.push({ fieldId: fid, optionId: oid });
|
|
5053
|
-
}
|
|
5054
|
-
return out;
|
|
5055
|
-
}
|
|
5056
|
-
function pushService(map, nodeId, sid) {
|
|
5057
|
-
if (!map[nodeId]) map[nodeId] = [];
|
|
5058
|
-
map[nodeId].push(sid);
|
|
5059
|
-
}
|
|
5060
|
-
function dedupeByString(arr) {
|
|
5061
|
-
const s = /* @__PURE__ */ new Set();
|
|
5062
|
-
const out = [];
|
|
5063
|
-
for (const v of arr) {
|
|
5064
|
-
const key = String(v);
|
|
5065
|
-
if (s.has(key)) continue;
|
|
5066
|
-
s.add(key);
|
|
5067
|
-
out.push(v);
|
|
5068
|
-
}
|
|
5069
|
-
return out;
|
|
5070
|
-
}
|
|
5071
|
-
function pruneFallbacksConservative(fallbacks, env, svcMap, policy) {
|
|
5072
|
-
var _a, _b;
|
|
5073
|
-
if (!fallbacks) return { pruned: void 0, original: void 0 };
|
|
5074
|
-
try {
|
|
5075
|
-
const { props: prunedProps } = pruneInvalidNodeFallbacks(
|
|
5076
|
-
{
|
|
5077
|
-
filters: [],
|
|
5078
|
-
fields: [],
|
|
5079
|
-
schema_version: "1.0",
|
|
5080
|
-
fallbacks
|
|
5081
|
-
},
|
|
5082
|
-
svcMap,
|
|
5083
|
-
policy
|
|
5084
|
-
);
|
|
5085
|
-
return {
|
|
5086
|
-
pruned: prunedProps.fallbacks,
|
|
5087
|
-
original: fallbacks
|
|
5088
|
-
};
|
|
5089
|
-
} catch {
|
|
5090
|
-
const out = {};
|
|
5091
|
-
const requireFit = (_a = policy.requireConstraintFit) != null ? _a : true;
|
|
5092
|
-
if (fallbacks.nodes) {
|
|
5093
|
-
const keptNodes = {};
|
|
5094
|
-
for (const [nodeId, candidates] of Object.entries(
|
|
5095
|
-
fallbacks.nodes
|
|
5096
|
-
)) {
|
|
5097
|
-
if (!env.serviceMap[nodeId]) continue;
|
|
5098
|
-
const primary = ((_b = env.serviceMap[nodeId]) != null ? _b : [])[0];
|
|
5099
|
-
const kept = [];
|
|
5100
|
-
for (const cand of candidates != null ? candidates : []) {
|
|
5101
|
-
if (!rateOk(svcMap, cand, primary, policy)) continue;
|
|
5102
|
-
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints))
|
|
5103
|
-
continue;
|
|
5104
|
-
kept.push(cand);
|
|
5105
|
-
}
|
|
5106
|
-
if (kept.length) keptNodes[nodeId] = kept;
|
|
5107
|
-
}
|
|
5108
|
-
if (Object.keys(keptNodes).length) out.nodes = keptNodes;
|
|
5109
|
-
}
|
|
5110
|
-
if (fallbacks.global) {
|
|
5111
|
-
const keptGlobal = {};
|
|
5112
|
-
const present = new Set(env.servicesList.map((sid) => String(sid)));
|
|
5113
|
-
for (const [primary, cands] of Object.entries(
|
|
5114
|
-
fallbacks.global
|
|
5115
|
-
)) {
|
|
5116
|
-
if (!present.has(String(primary))) continue;
|
|
5117
|
-
const primId = isFiniteNumber2(primary) ? Number(primary) : primary;
|
|
5118
|
-
const kept = [];
|
|
5119
|
-
for (const cand of cands != null ? cands : []) {
|
|
5120
|
-
if (!rateOk(svcMap, cand, primId, policy)) continue;
|
|
5121
|
-
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints))
|
|
5122
|
-
continue;
|
|
5123
|
-
kept.push(cand);
|
|
5124
|
-
}
|
|
5125
|
-
if (kept.length) keptGlobal[primId] = kept;
|
|
5126
|
-
}
|
|
5127
|
-
if (Object.keys(keptGlobal).length)
|
|
5128
|
-
out.global = keptGlobal;
|
|
5129
|
-
}
|
|
5130
|
-
return {
|
|
5131
|
-
pruned: Object.keys(out).length ? out : void 0,
|
|
5132
|
-
original: fallbacks
|
|
5133
|
-
};
|
|
5134
|
-
}
|
|
5135
|
-
}
|
|
5136
|
-
function isFiniteNumber2(v) {
|
|
5137
|
-
return typeof v === "number" && Number.isFinite(v);
|
|
5086
|
+
function readPositiveFiniteNumber(value) {
|
|
5087
|
+
const n = Number(value);
|
|
5088
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
5138
5089
|
}
|
|
5139
|
-
|
|
5090
|
+
|
|
5091
|
+
// src/utils/build-order-snapshot/utilities.ts
|
|
5092
|
+
function collectUtilityLineItems(visibleFieldIds, fieldById, selection, selectedOptionsByFieldId, quantity) {
|
|
5140
5093
|
var _a, _b, _c, _d, _e;
|
|
5141
5094
|
const items = [];
|
|
5142
5095
|
for (const fid of visibleFieldIds) {
|
|
5143
|
-
const
|
|
5144
|
-
if (!
|
|
5145
|
-
const isUtilityField = ((_a =
|
|
5146
|
-
const marker = readUtilityMarker((_b =
|
|
5096
|
+
const field = fieldById.get(fid);
|
|
5097
|
+
if (!field) continue;
|
|
5098
|
+
const isUtilityField = ((_a = field.pricing_role) != null ? _a : "base") === "utility";
|
|
5099
|
+
const marker = readUtilityMarker((_b = field.meta) == null ? void 0 : _b.utility);
|
|
5147
5100
|
if (isUtilityField && marker) {
|
|
5148
|
-
const
|
|
5149
|
-
const item = buildUtilityItemFromMarker(
|
|
5150
|
-
f.id,
|
|
5151
|
-
marker,
|
|
5152
|
-
quantity,
|
|
5153
|
-
val
|
|
5154
|
-
);
|
|
5101
|
+
const value = selection.formValuesByFieldId[field.id];
|
|
5102
|
+
const item = buildUtilityItemFromMarker(field.id, marker, quantity, value);
|
|
5155
5103
|
if (item) items.push(item);
|
|
5156
5104
|
}
|
|
5157
|
-
if (Array.isArray(
|
|
5158
|
-
const
|
|
5159
|
-
if (
|
|
5160
|
-
|
|
5161
|
-
|
|
5105
|
+
if (Array.isArray(field.options) && field.options.length) {
|
|
5106
|
+
const selectedOptionIds = (_c = selectedOptionsByFieldId[field.id]) != null ? _c : [];
|
|
5107
|
+
if (!selectedOptionIds.length) continue;
|
|
5108
|
+
const optById = new Map(field.options.map((o) => [o.id, o]));
|
|
5109
|
+
for (const oid of selectedOptionIds) {
|
|
5110
|
+
const option = optById.get(oid);
|
|
5111
|
+
if (!option) continue;
|
|
5112
|
+
if (((_d = option.pricing_role) != null ? _d : "base") !== "utility") continue;
|
|
5113
|
+
const optionMarker = readUtilityMarker((_e = option.meta) == null ? void 0 : _e.utility);
|
|
5114
|
+
if (!optionMarker) continue;
|
|
5115
|
+
const parentValue = selection.formValuesByFieldId[field.id];
|
|
5116
|
+
const item = buildUtilityItemFromMarker(
|
|
5117
|
+
option.id,
|
|
5118
|
+
optionMarker,
|
|
5119
|
+
quantity,
|
|
5120
|
+
parentValue
|
|
5162
5121
|
);
|
|
5163
|
-
|
|
5164
|
-
const opt = optById.get(oid);
|
|
5165
|
-
if (!opt) continue;
|
|
5166
|
-
if (((_d = opt.pricing_role) != null ? _d : "base") !== "utility") continue;
|
|
5167
|
-
const om = readUtilityMarker((_e = opt.meta) == null ? void 0 : _e.utility);
|
|
5168
|
-
if (!om) continue;
|
|
5169
|
-
const parentVal = selection.formValuesByFieldId[f.id];
|
|
5170
|
-
const item = buildUtilityItemFromMarker(
|
|
5171
|
-
opt.id,
|
|
5172
|
-
om,
|
|
5173
|
-
quantity,
|
|
5174
|
-
parentVal
|
|
5175
|
-
);
|
|
5176
|
-
if (item) items.push(item);
|
|
5177
|
-
}
|
|
5122
|
+
if (item) items.push(item);
|
|
5178
5123
|
}
|
|
5179
5124
|
}
|
|
5180
5125
|
}
|
|
@@ -5183,19 +5128,16 @@ function collectUtilityLineItems(visibleFieldIds, fieldById, selection, quantity
|
|
|
5183
5128
|
function readUtilityMarker(v) {
|
|
5184
5129
|
if (!v || typeof v !== "object") return void 0;
|
|
5185
5130
|
const src = v;
|
|
5186
|
-
if (!src.mode || typeof src.rate !== "number" || !Number.isFinite(src.rate))
|
|
5187
|
-
|
|
5188
|
-
if (src.mode !== "flat" && src.mode !== "per_quantity" && src.mode !== "per_value" && src.mode !== "percent")
|
|
5131
|
+
if (!src.mode || typeof src.rate !== "number" || !Number.isFinite(src.rate)) return void 0;
|
|
5132
|
+
if (src.mode !== "flat" && src.mode !== "per_quantity" && src.mode !== "per_value" && src.mode !== "percent") {
|
|
5189
5133
|
return void 0;
|
|
5134
|
+
}
|
|
5190
5135
|
const out = { mode: src.mode, rate: src.rate };
|
|
5191
|
-
if (src.valueBy === "value" || src.valueBy === "length")
|
|
5192
|
-
out.valueBy = src.valueBy;
|
|
5136
|
+
if (src.valueBy === "value" || src.valueBy === "length") out.valueBy = src.valueBy;
|
|
5193
5137
|
if (src.percentBase === "service_total" || src.percentBase === "base_service" || src.percentBase === "all") {
|
|
5194
5138
|
out.percentBase = src.percentBase;
|
|
5195
5139
|
}
|
|
5196
|
-
if (typeof src.label === "string" && src.label.trim())
|
|
5197
|
-
out.label = src.label.trim();
|
|
5198
|
-
}
|
|
5140
|
+
if (typeof src.label === "string" && src.label.trim()) out.label = src.label.trim();
|
|
5199
5141
|
return out;
|
|
5200
5142
|
}
|
|
5201
5143
|
function buildUtilityItemFromMarker(nodeId, marker, quantity, value) {
|
|
@@ -5218,17 +5160,19 @@ function buildUtilityItemFromMarker(nodeId, marker, quantity, value) {
|
|
|
5218
5160
|
}
|
|
5219
5161
|
return base;
|
|
5220
5162
|
}
|
|
5221
|
-
|
|
5163
|
+
|
|
5164
|
+
// src/utils/build-order-snapshot/context.ts
|
|
5165
|
+
function buildNodeContexts(tagId, visibleFieldIds, fieldById, _selection, selectedOptionsByFieldId) {
|
|
5222
5166
|
var _a;
|
|
5223
5167
|
const ctx = {};
|
|
5224
5168
|
ctx[tagId] = tagId;
|
|
5225
5169
|
for (const fid of visibleFieldIds) {
|
|
5226
|
-
const
|
|
5227
|
-
if (!
|
|
5228
|
-
const binds = normalizeBindIds(
|
|
5170
|
+
const field = fieldById.get(fid);
|
|
5171
|
+
if (!field) continue;
|
|
5172
|
+
const binds = normalizeBindIds(field.bind_id);
|
|
5229
5173
|
const applicable = binds.has(tagId);
|
|
5230
|
-
const
|
|
5231
|
-
for (const oid of
|
|
5174
|
+
const selectedOptionIds = (_a = selectedOptionsByFieldId[fid]) != null ? _a : [];
|
|
5175
|
+
for (const oid of selectedOptionIds) {
|
|
5232
5176
|
ctx[oid] = applicable ? tagId : null;
|
|
5233
5177
|
}
|
|
5234
5178
|
}
|
|
@@ -5244,66 +5188,159 @@ function normalizeBindIds(bind) {
|
|
|
5244
5188
|
}
|
|
5245
5189
|
return out;
|
|
5246
5190
|
}
|
|
5247
|
-
|
|
5191
|
+
|
|
5192
|
+
// src/utils/build-order-snapshot/warnings.ts
|
|
5193
|
+
function buildDevWarnings(props, svcMap, originalFallbacks, fieldById, visibleFieldIds, selection) {
|
|
5248
5194
|
const out = {};
|
|
5249
5195
|
const maybeCollectFailed = globalThis.collectFailedFallbacks;
|
|
5250
5196
|
try {
|
|
5251
5197
|
if (maybeCollectFailed && originalFallbacks) {
|
|
5252
5198
|
const diags = maybeCollectFailed(
|
|
5253
|
-
{
|
|
5254
|
-
...props,
|
|
5255
|
-
fallbacks: originalFallbacks
|
|
5256
|
-
},
|
|
5199
|
+
{ ...props, fallbacks: originalFallbacks },
|
|
5257
5200
|
svcMap,
|
|
5258
5201
|
{ mode: "dev" }
|
|
5259
5202
|
);
|
|
5260
|
-
if (diags
|
|
5261
|
-
out.fallbacks = diags;
|
|
5262
|
-
}
|
|
5203
|
+
if (diags == null ? void 0 : diags.length) out.fallbacks = diags;
|
|
5263
5204
|
}
|
|
5264
5205
|
} catch {
|
|
5265
5206
|
}
|
|
5266
5207
|
const utilityWarnings = [];
|
|
5267
5208
|
for (const fid of visibleFieldIds) {
|
|
5268
|
-
const
|
|
5269
|
-
if (!
|
|
5270
|
-
const
|
|
5271
|
-
if (
|
|
5209
|
+
const field = fieldById.get(fid);
|
|
5210
|
+
if (!field) continue;
|
|
5211
|
+
const hasValue = selection.formValuesByFieldId[fid] !== void 0;
|
|
5212
|
+
if (hasValue && !field.name && !isOptionBased(field)) {
|
|
5272
5213
|
utilityWarnings.push({
|
|
5273
5214
|
nodeId: fid,
|
|
5274
5215
|
reason: "missing_field_name_for_form_value"
|
|
5275
5216
|
});
|
|
5276
5217
|
}
|
|
5277
5218
|
}
|
|
5278
|
-
if (utilityWarnings.length)
|
|
5279
|
-
out.utility = utilityWarnings;
|
|
5280
|
-
}
|
|
5219
|
+
if (utilityWarnings.length) out.utility = utilityWarnings;
|
|
5281
5220
|
if (!out.fallbacks && !out.utility) return void 0;
|
|
5282
5221
|
return out;
|
|
5283
5222
|
}
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
}
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5223
|
+
|
|
5224
|
+
// src/utils/build-order-snapshot/index.ts
|
|
5225
|
+
function buildOrderSnapshot(props, builder, selection, services, settings = {}) {
|
|
5226
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
5227
|
+
const mode = (_a = settings.mode) != null ? _a : "prod";
|
|
5228
|
+
const hostDefaultQty = Number.isFinite((_b = settings.hostDefaultQuantity) != null ? _b : 1) ? settings.hostDefaultQuantity : 1;
|
|
5229
|
+
const fbSettings = {
|
|
5230
|
+
requireConstraintFit: true,
|
|
5231
|
+
ratePolicy: { kind: "lte_primary", pct: 5 },
|
|
5232
|
+
selectionStrategy: "priority",
|
|
5233
|
+
mode: mode === "dev" ? "dev" : "strict",
|
|
5234
|
+
...(_c = settings.fallback) != null ? _c : {}
|
|
5235
|
+
};
|
|
5236
|
+
const builtAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5237
|
+
const tagId = selection.activeTagId;
|
|
5238
|
+
const selectedButtonKeys = (_d = selection.selectedKeys) != null ? _d : toSelectedOptionKeys(selection.optionSelectionsByFieldId);
|
|
5239
|
+
const visibleFieldIds = builder.visibleFields(tagId, selectedButtonKeys);
|
|
5240
|
+
const tagById = new Map(((_e = props.filters) != null ? _e : []).map((t) => [t.id, t]));
|
|
5241
|
+
const fieldById = new Map(((_f = props.fields) != null ? _f : []).map((f) => [f.id, f]));
|
|
5242
|
+
const tagConstraints = (_h = (_g = tagById.get(tagId)) == null ? void 0 : _g.constraints) != null ? _h : void 0;
|
|
5243
|
+
const selectedOptionsByFieldId = getSelectedOptionsByFieldId(selection, fieldById);
|
|
5244
|
+
const selectionFields = visibleFieldIds.map((fid) => fieldById.get(fid)).filter((f) => !!f).map((f) => {
|
|
5245
|
+
var _a2;
|
|
5246
|
+
const optionIds = isOptionBased(f) ? (_a2 = selectedOptionsByFieldId[f.id]) != null ? _a2 : [] : void 0;
|
|
5247
|
+
return {
|
|
5248
|
+
id: f.id,
|
|
5249
|
+
type: String(f.type),
|
|
5250
|
+
...optionIds && optionIds.length ? { selectedOptions: optionIds } : {}
|
|
5251
|
+
};
|
|
5252
|
+
});
|
|
5253
|
+
const { formValues, selections } = buildInputs(
|
|
5254
|
+
visibleFieldIds,
|
|
5255
|
+
fieldById,
|
|
5256
|
+
selection,
|
|
5257
|
+
selectedOptionsByFieldId
|
|
5258
|
+
);
|
|
5259
|
+
const qtyRes = resolveQuantity(
|
|
5260
|
+
visibleFieldIds,
|
|
5261
|
+
fieldById,
|
|
5262
|
+
tagById,
|
|
5263
|
+
selection,
|
|
5264
|
+
tagId,
|
|
5265
|
+
hostDefaultQty
|
|
5266
|
+
);
|
|
5267
|
+
const { serviceMap, servicesList } = resolveServices(
|
|
5268
|
+
tagId,
|
|
5269
|
+
visibleFieldIds,
|
|
5270
|
+
selection,
|
|
5271
|
+
tagById,
|
|
5272
|
+
fieldById,
|
|
5273
|
+
services
|
|
5274
|
+
);
|
|
5275
|
+
const { min, max } = resolveMinMax(servicesList, services);
|
|
5276
|
+
const maybeNodeMap = typeof builder.getNodeMap === "function" ? builder.getNodeMap() : void 0;
|
|
5277
|
+
const resolvedOrderKind = resolveOrderKind({
|
|
5278
|
+
props,
|
|
5279
|
+
activeTagId: tagId,
|
|
5280
|
+
selectedTriggerKeys: selectedButtonKeys,
|
|
5281
|
+
nodeMap: maybeNodeMap
|
|
5282
|
+
});
|
|
5283
|
+
const prunedFallbacks = pruneFallbacksConservative(
|
|
5284
|
+
props.fallbacks,
|
|
5285
|
+
{ tagId, constraints: tagConstraints, serviceMap, servicesList },
|
|
5286
|
+
services,
|
|
5287
|
+
fbSettings
|
|
5288
|
+
);
|
|
5289
|
+
const utilities = collectUtilityLineItems(
|
|
5290
|
+
visibleFieldIds,
|
|
5291
|
+
fieldById,
|
|
5292
|
+
selection,
|
|
5293
|
+
selectedOptionsByFieldId,
|
|
5294
|
+
qtyRes.quantity
|
|
5295
|
+
);
|
|
5296
|
+
const warnings = mode === "dev" ? buildDevWarnings(
|
|
5297
|
+
props,
|
|
5298
|
+
services,
|
|
5299
|
+
prunedFallbacks.original,
|
|
5300
|
+
fieldById,
|
|
5301
|
+
visibleFieldIds,
|
|
5302
|
+
selection
|
|
5303
|
+
) : void 0;
|
|
5304
|
+
const meta = {
|
|
5305
|
+
schema_version: props.schema_version,
|
|
5306
|
+
workspaceId: settings.workspaceId,
|
|
5307
|
+
builder: settings.builderCommit ? { commit: settings.builderCommit } : void 0,
|
|
5308
|
+
context: {
|
|
5309
|
+
tag: tagId,
|
|
5310
|
+
constraints: tagConstraints != null ? tagConstraints : {},
|
|
5311
|
+
nodeContexts: buildNodeContexts(
|
|
5312
|
+
tagId,
|
|
5313
|
+
visibleFieldIds,
|
|
5314
|
+
fieldById,
|
|
5315
|
+
selection,
|
|
5316
|
+
selectedOptionsByFieldId
|
|
5317
|
+
),
|
|
5318
|
+
policy: toSnapshotPolicy(fbSettings)
|
|
5304
5319
|
}
|
|
5305
|
-
}
|
|
5306
|
-
return {
|
|
5320
|
+
};
|
|
5321
|
+
return {
|
|
5322
|
+
version: "1",
|
|
5323
|
+
mode,
|
|
5324
|
+
builtAt,
|
|
5325
|
+
selection: {
|
|
5326
|
+
tag: tagId,
|
|
5327
|
+
buttons: selectedButtonKeys,
|
|
5328
|
+
fields: selectionFields
|
|
5329
|
+
},
|
|
5330
|
+
inputs: { form: formValues, selections },
|
|
5331
|
+
min,
|
|
5332
|
+
max: max != null ? max : min,
|
|
5333
|
+
orderKind: resolvedOrderKind.kind,
|
|
5334
|
+
orderKindSource: resolvedOrderKind.source,
|
|
5335
|
+
quantity: qtyRes.quantity,
|
|
5336
|
+
quantitySource: qtyRes.source,
|
|
5337
|
+
services: servicesList,
|
|
5338
|
+
serviceMap,
|
|
5339
|
+
...prunedFallbacks.pruned ? { fallbacks: prunedFallbacks.pruned } : {},
|
|
5340
|
+
...utilities.length ? { utilities } : {},
|
|
5341
|
+
...warnings ? { warnings } : {},
|
|
5342
|
+
meta
|
|
5343
|
+
};
|
|
5307
5344
|
}
|
|
5308
5345
|
|
|
5309
5346
|
// src/core/fallback-editor.ts
|