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