@timeax/digital-service-engine 0.3.2 → 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 +471 -434
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +32 -28
- package/dist/react/index.d.ts +32 -28
- package/dist/react/index.js +471 -434
- package/dist/react/index.js.map +1 -1
- package/dist/workspace/index.cjs +83 -63
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +33 -23
- package/dist/workspace/index.d.ts +33 -23
- package/dist/workspace/index.js +83 -63
- package/dist/workspace/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -5073,141 +5073,74 @@ function toBindArray(bind) {
|
|
|
5073
5073
|
return Array.isArray(bind) ? bind.slice() : [bind];
|
|
5074
5074
|
}
|
|
5075
5075
|
|
|
5076
|
-
// src/utils/build-order-snapshot.ts
|
|
5077
|
-
function
|
|
5078
|
-
var _a2, _b
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
const tagId = selection.activeTagId;
|
|
5092
|
-
const selectedButtonKeys = (_d = selection.selectedKeys) != null ? _d : toSelectedOptionKeys(selection.optionSelectionsByFieldId);
|
|
5093
|
-
const visibleFieldIds = builder.visibleFields(
|
|
5094
|
-
tagId,
|
|
5095
|
-
selectedButtonKeys
|
|
5096
|
-
);
|
|
5097
|
-
const tagById = new Map(
|
|
5098
|
-
((_e = props.filters) != null ? _e : []).map((t) => [t.id, t])
|
|
5099
|
-
);
|
|
5100
|
-
const fieldById = new Map(
|
|
5101
|
-
((_f = props.fields) != null ? _f : []).map((f) => [f.id, f])
|
|
5102
|
-
);
|
|
5103
|
-
const tagConstraints = (_h = (_g = tagById.get(tagId)) == null ? void 0 : _g.constraints) != null ? _h : void 0;
|
|
5104
|
-
const selectionFields = visibleFieldIds.map((fid) => fieldById.get(fid)).filter((f) => !!f).map((f) => {
|
|
5105
|
-
var _a3;
|
|
5106
|
-
const optIds = isOptionBased(f) ? (_a3 = selection.optionSelectionsByFieldId[f.id]) != null ? _a3 : [] : void 0;
|
|
5076
|
+
// src/utils/build-order-snapshot/fallbacks.ts
|
|
5077
|
+
function pruneFallbacksConservative(fallbacks, env, svcMap, policy) {
|
|
5078
|
+
var _a2, _b;
|
|
5079
|
+
if (!fallbacks) return { pruned: void 0, original: void 0 };
|
|
5080
|
+
try {
|
|
5081
|
+
const { props: prunedProps } = pruneInvalidNodeFallbacks(
|
|
5082
|
+
{
|
|
5083
|
+
filters: [],
|
|
5084
|
+
fields: [],
|
|
5085
|
+
schema_version: "1.0",
|
|
5086
|
+
fallbacks
|
|
5087
|
+
},
|
|
5088
|
+
svcMap,
|
|
5089
|
+
policy
|
|
5090
|
+
);
|
|
5107
5091
|
return {
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
...optIds && optIds.length ? { selectedOptions: optIds } : {}
|
|
5092
|
+
pruned: prunedProps.fallbacks,
|
|
5093
|
+
original: fallbacks
|
|
5111
5094
|
};
|
|
5112
|
-
}
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
selection,
|
|
5132
|
-
tagById,
|
|
5133
|
-
fieldById
|
|
5134
|
-
);
|
|
5135
|
-
const { min, max } = resolveMinMax(servicesList, services);
|
|
5136
|
-
const maybeNodeMap = typeof builder.getNodeMap === "function" ? builder.getNodeMap() : void 0;
|
|
5137
|
-
const resolvedOrderKind = resolveOrderKind({
|
|
5138
|
-
props,
|
|
5139
|
-
activeTagId: tagId,
|
|
5140
|
-
selectedTriggerKeys: selectedButtonKeys,
|
|
5141
|
-
nodeMap: maybeNodeMap
|
|
5142
|
-
});
|
|
5143
|
-
const prunedFallbacks = pruneFallbacksConservative(
|
|
5144
|
-
props.fallbacks,
|
|
5145
|
-
{ tagId, constraints: tagConstraints, serviceMap, servicesList },
|
|
5146
|
-
services,
|
|
5147
|
-
fbSettings
|
|
5148
|
-
);
|
|
5149
|
-
const utilities = collectUtilityLineItems(
|
|
5150
|
-
visibleFieldIds,
|
|
5151
|
-
fieldById,
|
|
5152
|
-
selection,
|
|
5153
|
-
quantity
|
|
5154
|
-
);
|
|
5155
|
-
const warnings = mode === "dev" ? buildDevWarnings(
|
|
5156
|
-
props,
|
|
5157
|
-
services,
|
|
5158
|
-
tagId,
|
|
5159
|
-
serviceMap,
|
|
5160
|
-
prunedFallbacks.original,
|
|
5161
|
-
prunedFallbacks.pruned,
|
|
5162
|
-
fieldById,
|
|
5163
|
-
visibleFieldIds,
|
|
5164
|
-
selection
|
|
5165
|
-
) : void 0;
|
|
5166
|
-
const snapshotPolicy = toSnapshotPolicy(fbSettings);
|
|
5167
|
-
const meta = {
|
|
5168
|
-
schema_version: props.schema_version,
|
|
5169
|
-
workspaceId: settings.workspaceId,
|
|
5170
|
-
builder: settings.builderCommit ? { commit: settings.builderCommit } : void 0,
|
|
5171
|
-
context: {
|
|
5172
|
-
tag: tagId,
|
|
5173
|
-
constraints: tagConstraints != null ? tagConstraints : {},
|
|
5174
|
-
nodeContexts: buildNodeContexts(
|
|
5175
|
-
tagId,
|
|
5176
|
-
visibleFieldIds,
|
|
5177
|
-
fieldById,
|
|
5178
|
-
selection
|
|
5179
|
-
),
|
|
5180
|
-
policy: snapshotPolicy
|
|
5095
|
+
} catch {
|
|
5096
|
+
const out = {};
|
|
5097
|
+
const requireFit = (_a2 = policy.requireConstraintFit) != null ? _a2 : true;
|
|
5098
|
+
if (fallbacks.nodes) {
|
|
5099
|
+
const keptNodes = {};
|
|
5100
|
+
for (const [nodeId, candidates] of Object.entries(
|
|
5101
|
+
fallbacks.nodes
|
|
5102
|
+
)) {
|
|
5103
|
+
if (!env.serviceMap[nodeId]) continue;
|
|
5104
|
+
const primary = ((_b = env.serviceMap[nodeId]) != null ? _b : [])[0];
|
|
5105
|
+
const kept = [];
|
|
5106
|
+
for (const cand of candidates != null ? candidates : []) {
|
|
5107
|
+
if (!rateOk(svcMap, cand, primary, policy)) continue;
|
|
5108
|
+
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints)) continue;
|
|
5109
|
+
kept.push(cand);
|
|
5110
|
+
}
|
|
5111
|
+
if (kept.length) keptNodes[nodeId] = kept;
|
|
5112
|
+
}
|
|
5113
|
+
if (Object.keys(keptNodes).length) out.nodes = keptNodes;
|
|
5181
5114
|
}
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
...utilities.length ? { utilities } : {},
|
|
5206
|
-
...warnings ? { warnings } : {},
|
|
5207
|
-
meta
|
|
5208
|
-
};
|
|
5209
|
-
return snapshot;
|
|
5115
|
+
if (fallbacks.global) {
|
|
5116
|
+
const keptGlobal = {};
|
|
5117
|
+
const present = new Set(env.servicesList.map((sid) => String(sid)));
|
|
5118
|
+
for (const [primary, cands] of Object.entries(
|
|
5119
|
+
fallbacks.global
|
|
5120
|
+
)) {
|
|
5121
|
+
if (!present.has(String(primary))) continue;
|
|
5122
|
+
const primId = isFiniteNumber2(primary) ? Number(primary) : primary;
|
|
5123
|
+
const kept = [];
|
|
5124
|
+
for (const cand of cands != null ? cands : []) {
|
|
5125
|
+
if (!rateOk(svcMap, cand, primId, policy)) continue;
|
|
5126
|
+
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints)) continue;
|
|
5127
|
+
kept.push(cand);
|
|
5128
|
+
}
|
|
5129
|
+
if (kept.length) keptGlobal[primId] = kept;
|
|
5130
|
+
}
|
|
5131
|
+
if (Object.keys(keptGlobal).length) out.global = keptGlobal;
|
|
5132
|
+
}
|
|
5133
|
+
return {
|
|
5134
|
+
pruned: Object.keys(out).length ? out : void 0,
|
|
5135
|
+
original: fallbacks
|
|
5136
|
+
};
|
|
5137
|
+
}
|
|
5210
5138
|
}
|
|
5139
|
+
function isFiniteNumber2(v) {
|
|
5140
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
5141
|
+
}
|
|
5142
|
+
|
|
5143
|
+
// src/utils/build-order-snapshot/selection.ts
|
|
5211
5144
|
function isOptionBased(f) {
|
|
5212
5145
|
const hasOptions = Array.isArray(f.options) && f.options.length > 0;
|
|
5213
5146
|
return hasOptions || isMultiField(f);
|
|
@@ -5215,50 +5148,227 @@ function isOptionBased(f) {
|
|
|
5215
5148
|
function toSelectedOptionKeys(byField) {
|
|
5216
5149
|
const keys = [];
|
|
5217
5150
|
for (const [fieldId, optionIds] of Object.entries(byField != null ? byField : {})) {
|
|
5218
|
-
for (const
|
|
5219
|
-
keys.push(`${fieldId}::${
|
|
5151
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
5152
|
+
keys.push(`${fieldId}::${optionId}`);
|
|
5220
5153
|
}
|
|
5221
5154
|
}
|
|
5222
5155
|
return keys;
|
|
5223
5156
|
}
|
|
5224
|
-
function
|
|
5225
|
-
|
|
5226
|
-
|
|
5157
|
+
function getSelectedOptionsByFieldId(selection, fieldById) {
|
|
5158
|
+
const out = {};
|
|
5159
|
+
for (const visit of buildSelectedNodeVisitOrder(selection, fieldById)) {
|
|
5160
|
+
if (visit.kind !== "option") continue;
|
|
5161
|
+
if (!out[visit.fieldId]) out[visit.fieldId] = [];
|
|
5162
|
+
out[visit.fieldId].push(visit.optionId);
|
|
5163
|
+
}
|
|
5164
|
+
return out;
|
|
5165
|
+
}
|
|
5166
|
+
function buildSelectedNodeVisitOrder(selection, fieldById) {
|
|
5167
|
+
var _a2, _b, _c;
|
|
5168
|
+
const out = [];
|
|
5169
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5170
|
+
function pushField(fieldId) {
|
|
5171
|
+
const key = `field:${fieldId}`;
|
|
5172
|
+
if (seen.has(key)) return;
|
|
5173
|
+
seen.add(key);
|
|
5174
|
+
out.push({ kind: "field", fieldId });
|
|
5175
|
+
}
|
|
5176
|
+
function pushOption(fieldId, optionId) {
|
|
5177
|
+
const key = `option:${fieldId}::${optionId}`;
|
|
5178
|
+
if (seen.has(key)) return;
|
|
5179
|
+
seen.add(key);
|
|
5180
|
+
out.push({ kind: "option", fieldId, optionId });
|
|
5181
|
+
}
|
|
5182
|
+
for (const item of (_a2 = selection.optionTraversalOrder) != null ? _a2 : []) {
|
|
5183
|
+
pushOption(item.fieldId, item.optionId);
|
|
5184
|
+
}
|
|
5185
|
+
for (const rawKey of (_b = selection.selectedKeys) != null ? _b : []) {
|
|
5186
|
+
const key = String(rawKey);
|
|
5187
|
+
if (key.includes("::")) {
|
|
5188
|
+
const [fieldId, optionId] = key.split("::", 2);
|
|
5189
|
+
if (fieldId && optionId) pushOption(fieldId, optionId);
|
|
5190
|
+
continue;
|
|
5191
|
+
}
|
|
5192
|
+
const field = fieldById.get(key);
|
|
5193
|
+
if (field) {
|
|
5194
|
+
pushField(field.id);
|
|
5195
|
+
continue;
|
|
5196
|
+
}
|
|
5197
|
+
const ownerField = findOptionOwnerField(key, fieldById);
|
|
5198
|
+
if (ownerField) pushOption(ownerField.id, key);
|
|
5199
|
+
}
|
|
5200
|
+
for (const [fieldId, optionIds] of Object.entries(
|
|
5201
|
+
(_c = selection.optionSelectionsByFieldId) != null ? _c : {}
|
|
5202
|
+
)) {
|
|
5203
|
+
if (!fieldById.has(fieldId)) continue;
|
|
5204
|
+
for (const optionId of optionIds != null ? optionIds : []) {
|
|
5205
|
+
pushOption(fieldId, optionId);
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
return out;
|
|
5209
|
+
}
|
|
5210
|
+
function findOptionOwnerField(optionId, fieldById) {
|
|
5211
|
+
var _a2;
|
|
5212
|
+
for (const field of fieldById.values()) {
|
|
5213
|
+
if ((_a2 = field.options) == null ? void 0 : _a2.some((option) => option.id === optionId)) return field;
|
|
5214
|
+
}
|
|
5215
|
+
return void 0;
|
|
5227
5216
|
}
|
|
5228
|
-
|
|
5217
|
+
|
|
5218
|
+
// src/utils/build-order-snapshot/services.ts
|
|
5219
|
+
function isServiceBased(field) {
|
|
5220
|
+
var _a2;
|
|
5221
|
+
if (field.service_id !== void 0 && field.service_id !== null) return true;
|
|
5222
|
+
return !!((_a2 = field.options) == null ? void 0 : _a2.some(
|
|
5223
|
+
(item) => item.service_id !== void 0 && item.service_id !== null
|
|
5224
|
+
));
|
|
5225
|
+
}
|
|
5226
|
+
function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById, services) {
|
|
5227
|
+
var _a2, _b, _c, _d;
|
|
5228
|
+
const serviceMap = {};
|
|
5229
|
+
const visible = new Set(visibleFieldIds);
|
|
5230
|
+
const selectedBaseServices = [];
|
|
5231
|
+
const visits = buildSelectedNodeVisitOrder(selection, fieldById);
|
|
5232
|
+
let index = 0;
|
|
5233
|
+
function addSelectedBaseService(origin, sid) {
|
|
5234
|
+
pushService(serviceMap, origin, sid);
|
|
5235
|
+
selectedBaseServices.push({
|
|
5236
|
+
origin,
|
|
5237
|
+
sid,
|
|
5238
|
+
rate: readServiceRate(services, sid),
|
|
5239
|
+
index: index++
|
|
5240
|
+
});
|
|
5241
|
+
}
|
|
5242
|
+
for (const visit of visits) {
|
|
5243
|
+
if (!visible.has(visit.fieldId)) continue;
|
|
5244
|
+
const field = fieldById.get(visit.fieldId);
|
|
5245
|
+
if (!field) continue;
|
|
5246
|
+
if (visit.kind === "field") {
|
|
5247
|
+
const role2 = (_a2 = field.pricing_role) != null ? _a2 : "base";
|
|
5248
|
+
if (role2 === "utility") continue;
|
|
5249
|
+
if (field.service_id !== void 0 && field.service_id !== null) {
|
|
5250
|
+
addSelectedBaseService(field.id, field.service_id);
|
|
5251
|
+
}
|
|
5252
|
+
continue;
|
|
5253
|
+
}
|
|
5254
|
+
const option = (_b = field.options) == null ? void 0 : _b.find((item) => item.id === visit.optionId);
|
|
5255
|
+
if (!option) continue;
|
|
5256
|
+
const role = (_d = (_c = option.pricing_role) != null ? _c : field.pricing_role) != null ? _d : "base";
|
|
5257
|
+
if (role === "utility") continue;
|
|
5258
|
+
if (option.service_id !== void 0 && option.service_id !== null) {
|
|
5259
|
+
addSelectedBaseService(option.id, option.service_id);
|
|
5260
|
+
}
|
|
5261
|
+
}
|
|
5262
|
+
if (selectedBaseServices.length > 0) {
|
|
5263
|
+
const primary = pickHighestRatePrimary2(selectedBaseServices);
|
|
5264
|
+
const ordered = [
|
|
5265
|
+
primary.sid,
|
|
5266
|
+
...selectedBaseServices.filter((item) => item !== primary).sort((a, b) => a.index - b.index).map((item) => item.sid)
|
|
5267
|
+
];
|
|
5268
|
+
return { serviceMap, servicesList: dedupeByString(ordered) };
|
|
5269
|
+
}
|
|
5270
|
+
const tag = tagById.get(tagId);
|
|
5271
|
+
if ((tag == null ? void 0 : tag.service_id) !== void 0 && tag.service_id !== null) {
|
|
5272
|
+
pushService(serviceMap, tagId, tag.service_id);
|
|
5273
|
+
return { serviceMap, servicesList: [tag.service_id] };
|
|
5274
|
+
}
|
|
5275
|
+
return { serviceMap, servicesList: [] };
|
|
5276
|
+
}
|
|
5277
|
+
function pickHighestRatePrimary2(services) {
|
|
5278
|
+
let best = services[0];
|
|
5279
|
+
for (const item of services.slice(1)) {
|
|
5280
|
+
if (item.rate > best.rate) best = item;
|
|
5281
|
+
}
|
|
5282
|
+
return best;
|
|
5283
|
+
}
|
|
5284
|
+
function getCap2(map, id) {
|
|
5285
|
+
var _a2;
|
|
5286
|
+
return (_a2 = map == null ? void 0 : map[id]) != null ? _a2 : map == null ? void 0 : map[String(id)];
|
|
5287
|
+
}
|
|
5288
|
+
function readServiceRate(services, sid) {
|
|
5289
|
+
var _a2;
|
|
5290
|
+
const rate = Number((_a2 = getCap2(services, sid)) == null ? void 0 : _a2.rate);
|
|
5291
|
+
return Number.isFinite(rate) ? rate : Number.NEGATIVE_INFINITY;
|
|
5292
|
+
}
|
|
5293
|
+
function pushService(map, nodeId, sid) {
|
|
5294
|
+
if (!map[nodeId]) map[nodeId] = [];
|
|
5295
|
+
map[nodeId].push(sid);
|
|
5296
|
+
}
|
|
5297
|
+
function dedupeByString(arr) {
|
|
5298
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5299
|
+
const out = [];
|
|
5300
|
+
for (const value of arr) {
|
|
5301
|
+
const key = String(value);
|
|
5302
|
+
if (seen.has(key)) continue;
|
|
5303
|
+
seen.add(key);
|
|
5304
|
+
out.push(value);
|
|
5305
|
+
}
|
|
5306
|
+
return out;
|
|
5307
|
+
}
|
|
5308
|
+
|
|
5309
|
+
// src/utils/build-order-snapshot/inputs.ts
|
|
5310
|
+
function buildInputs(visibleFieldIds, fieldById, selection, selectedOptionsByFieldId) {
|
|
5229
5311
|
const formValues = {};
|
|
5230
5312
|
const selections = {};
|
|
5231
5313
|
for (const fid of visibleFieldIds) {
|
|
5232
|
-
const
|
|
5233
|
-
if (!
|
|
5234
|
-
const
|
|
5235
|
-
if (
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
if (!name || val === void 0) continue;
|
|
5242
|
-
formValues[name] = val;
|
|
5314
|
+
const field = fieldById.get(fid);
|
|
5315
|
+
if (!field) continue;
|
|
5316
|
+
const selectedOptionIds = selectedOptionsByFieldId[fid];
|
|
5317
|
+
if (selectedOptionIds == null ? void 0 : selectedOptionIds.length) selections[fid] = [...selectedOptionIds];
|
|
5318
|
+
if (!isServiceBased(field)) {
|
|
5319
|
+
const name = field.name;
|
|
5320
|
+
const value = selection.formValuesByFieldId[fid];
|
|
5321
|
+
if (!name || value === void 0) continue;
|
|
5322
|
+
formValues[name] = value;
|
|
5243
5323
|
}
|
|
5244
5324
|
}
|
|
5245
5325
|
return { formValues, selections };
|
|
5246
5326
|
}
|
|
5327
|
+
|
|
5328
|
+
// src/utils/build-order-snapshot/min-max.ts
|
|
5329
|
+
function getCap3(map, id) {
|
|
5330
|
+
var _a2;
|
|
5331
|
+
return (_a2 = map == null ? void 0 : map[id]) != null ? _a2 : map == null ? void 0 : map[String(id)];
|
|
5332
|
+
}
|
|
5333
|
+
function resolveMinMax(servicesList, services) {
|
|
5334
|
+
let min;
|
|
5335
|
+
let max;
|
|
5336
|
+
for (const sid of servicesList) {
|
|
5337
|
+
const cap = getCap3(services, sid);
|
|
5338
|
+
if (!cap) continue;
|
|
5339
|
+
if (typeof cap.min === "number" && Number.isFinite(cap.min)) {
|
|
5340
|
+
min = min === void 0 ? cap.min : Math.min(min, cap.min);
|
|
5341
|
+
}
|
|
5342
|
+
if (typeof cap.max === "number" && Number.isFinite(cap.max)) {
|
|
5343
|
+
max = max === void 0 ? cap.max : Math.max(max, cap.max);
|
|
5344
|
+
}
|
|
5345
|
+
}
|
|
5346
|
+
return { min: min != null ? min : 1, ...max !== void 0 ? { max } : {} };
|
|
5347
|
+
}
|
|
5348
|
+
|
|
5349
|
+
// src/utils/build-order-snapshot/policy.ts
|
|
5350
|
+
function toSnapshotPolicy(settings) {
|
|
5351
|
+
var _a2;
|
|
5352
|
+
return {
|
|
5353
|
+
ratePolicy: normalizeRatePolicy(settings.ratePolicy),
|
|
5354
|
+
requireConstraintFit: (_a2 = settings.requireConstraintFit) != null ? _a2 : true
|
|
5355
|
+
};
|
|
5356
|
+
}
|
|
5357
|
+
|
|
5358
|
+
// src/utils/build-order-snapshot/quantity.ts
|
|
5247
5359
|
function resolveQuantity(visibleFieldIds, fieldById, tagById, selection, tagId, hostDefault) {
|
|
5248
5360
|
var _a2;
|
|
5249
5361
|
for (const fid of visibleFieldIds) {
|
|
5250
|
-
const
|
|
5251
|
-
if (!
|
|
5252
|
-
const rule = readQuantityRule(
|
|
5253
|
-
(_a2 = f.meta) == null ? void 0 : _a2.quantity
|
|
5254
|
-
);
|
|
5362
|
+
const field = fieldById.get(fid);
|
|
5363
|
+
if (!field) continue;
|
|
5364
|
+
const rule = readQuantityRule((_a2 = field.meta) == null ? void 0 : _a2.quantity);
|
|
5255
5365
|
if (!rule) continue;
|
|
5256
5366
|
const raw = selection.formValuesByFieldId[fid];
|
|
5257
5367
|
const evaluated = evaluateQuantityRule(rule, raw);
|
|
5258
5368
|
if (Number.isFinite(evaluated) && evaluated > 0) {
|
|
5259
5369
|
return {
|
|
5260
5370
|
quantity: evaluated,
|
|
5261
|
-
source: { kind: "field", id:
|
|
5371
|
+
source: { kind: "field", id: field.id, rule }
|
|
5262
5372
|
};
|
|
5263
5373
|
}
|
|
5264
5374
|
break;
|
|
@@ -5271,24 +5381,47 @@ function resolveQuantity(visibleFieldIds, fieldById, tagById, selection, tagId,
|
|
|
5271
5381
|
tagId
|
|
5272
5382
|
);
|
|
5273
5383
|
if (nodeDefault) return nodeDefault;
|
|
5274
|
-
return {
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5384
|
+
return { quantity: hostDefault, source: { kind: "default", defaultedFromHost: true } };
|
|
5385
|
+
}
|
|
5386
|
+
function resolveNodeDefaultQuantity(visibleFieldIds, fieldById, tagById, selection, tagId) {
|
|
5387
|
+
var _a2, _b, _c;
|
|
5388
|
+
const visible = new Set(visibleFieldIds);
|
|
5389
|
+
const visits = buildSelectedNodeVisitOrder(selection, fieldById);
|
|
5390
|
+
for (const visit of visits) {
|
|
5391
|
+
if (visit.kind !== "option") continue;
|
|
5392
|
+
if (!visible.has(visit.fieldId)) continue;
|
|
5393
|
+
const field = fieldById.get(visit.fieldId);
|
|
5394
|
+
if (!((_a2 = field == null ? void 0 : field.options) == null ? void 0 : _a2.length)) continue;
|
|
5395
|
+
const option = field.options.find((item) => item.id === visit.optionId);
|
|
5396
|
+
const quantity = readPositiveFiniteNumber((_b = option == null ? void 0 : option.meta) == null ? void 0 : _b.quantityDefault);
|
|
5397
|
+
if (quantity !== void 0) {
|
|
5398
|
+
return { quantity, source: { kind: "option", id: option.id } };
|
|
5399
|
+
}
|
|
5400
|
+
}
|
|
5401
|
+
for (const visit of visits) {
|
|
5402
|
+
if (!visible.has(visit.fieldId)) continue;
|
|
5403
|
+
const field = fieldById.get(visit.fieldId);
|
|
5404
|
+
if (!field) continue;
|
|
5405
|
+
const quantity = readPositiveFiniteNumber(field.quantityDefault);
|
|
5406
|
+
if (quantity !== void 0) {
|
|
5407
|
+
return { quantity, source: { kind: "field", id: field.id } };
|
|
5408
|
+
}
|
|
5409
|
+
}
|
|
5410
|
+
const tag = tagById.get(tagId);
|
|
5411
|
+
const tagQuantity = readPositiveFiniteNumber((_c = tag == null ? void 0 : tag.meta) == null ? void 0 : _c.quantityDefault);
|
|
5412
|
+
if (tagQuantity !== void 0) {
|
|
5413
|
+
return { quantity: tagQuantity, source: { kind: "tag", id: tagId } };
|
|
5414
|
+
}
|
|
5415
|
+
return void 0;
|
|
5278
5416
|
}
|
|
5279
5417
|
function readQuantityRule(v) {
|
|
5280
5418
|
if (!v || typeof v !== "object") return void 0;
|
|
5281
5419
|
const src = v;
|
|
5282
|
-
if (src.valueBy !== "value" && src.valueBy !== "length" && src.valueBy !== "eval")
|
|
5283
|
-
return void 0;
|
|
5420
|
+
if (src.valueBy !== "value" && src.valueBy !== "length" && src.valueBy !== "eval") return void 0;
|
|
5284
5421
|
const out = { valueBy: src.valueBy };
|
|
5285
5422
|
if (src.code && typeof src.code === "string") out.code = src.code;
|
|
5286
|
-
if (typeof src.multiply === "number" && Number.isFinite(src.multiply))
|
|
5287
|
-
|
|
5288
|
-
}
|
|
5289
|
-
if (typeof src.fallback === "number" && Number.isFinite(src.fallback)) {
|
|
5290
|
-
out.fallback = src.fallback;
|
|
5291
|
-
}
|
|
5423
|
+
if (typeof src.multiply === "number" && Number.isFinite(src.multiply)) out.multiply = src.multiply;
|
|
5424
|
+
if (typeof src.fallback === "number" && Number.isFinite(src.fallback)) out.fallback = src.fallback;
|
|
5292
5425
|
if (src.clamp && typeof src.clamp === "object") {
|
|
5293
5426
|
const min = typeof src.clamp.min === "number" && Number.isFinite(src.clamp.min) ? src.clamp.min : void 0;
|
|
5294
5427
|
const max = typeof src.clamp.max === "number" && Number.isFinite(src.clamp.max) ? src.clamp.max : void 0;
|
|
@@ -5359,231 +5492,43 @@ function applyClamp(value, clamp2) {
|
|
|
5359
5492
|
if ((clamp2 == null ? void 0 : clamp2.max) !== void 0) next = Math.min(next, clamp2.max);
|
|
5360
5493
|
return next;
|
|
5361
5494
|
}
|
|
5362
|
-
function
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
for (const { fieldId, optionId } of optionVisit) {
|
|
5366
|
-
if (!visibleFieldIds.includes(fieldId)) continue;
|
|
5367
|
-
const field = fieldById.get(fieldId);
|
|
5368
|
-
const option = (_a2 = field == null ? void 0 : field.options) == null ? void 0 : _a2.find((item) => item.id === optionId);
|
|
5369
|
-
const quantityDefault = readQuantityDefault(
|
|
5370
|
-
(_b = option == null ? void 0 : option.meta) == null ? void 0 : _b.quantityDefault
|
|
5371
|
-
);
|
|
5372
|
-
if (quantityDefault !== void 0) {
|
|
5373
|
-
return {
|
|
5374
|
-
quantity: quantityDefault,
|
|
5375
|
-
source: { kind: "option", id: optionId }
|
|
5376
|
-
};
|
|
5377
|
-
}
|
|
5378
|
-
}
|
|
5379
|
-
for (const fieldId of visibleFieldIds) {
|
|
5380
|
-
const field = fieldById.get(fieldId);
|
|
5381
|
-
if (!field) continue;
|
|
5382
|
-
const isButtonStyle = field.button === true || Array.isArray(field.options) && field.options.length > 0;
|
|
5383
|
-
if (!isButtonStyle) continue;
|
|
5384
|
-
const quantityDefault = readQuantityDefault(
|
|
5385
|
-
field.quantityDefault
|
|
5386
|
-
);
|
|
5387
|
-
if (quantityDefault !== void 0) {
|
|
5388
|
-
return {
|
|
5389
|
-
quantity: quantityDefault,
|
|
5390
|
-
source: { kind: "field", id: field.id }
|
|
5391
|
-
};
|
|
5392
|
-
}
|
|
5393
|
-
}
|
|
5394
|
-
const tagQuantityDefault = readQuantityDefault(
|
|
5395
|
-
(_d = (_c = tagById.get(tagId)) == null ? void 0 : _c.meta) == null ? void 0 : _d.quantityDefault
|
|
5396
|
-
);
|
|
5397
|
-
if (tagQuantityDefault !== void 0) {
|
|
5398
|
-
return {
|
|
5399
|
-
quantity: tagQuantityDefault,
|
|
5400
|
-
source: { kind: "tag", id: tagId }
|
|
5401
|
-
};
|
|
5402
|
-
}
|
|
5403
|
-
return void 0;
|
|
5404
|
-
}
|
|
5405
|
-
function readQuantityDefault(value) {
|
|
5406
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
5407
|
-
}
|
|
5408
|
-
function resolveServices(tagId, visibleFieldIds, selection, tagById, fieldById) {
|
|
5409
|
-
var _a2;
|
|
5410
|
-
const serviceMap = {};
|
|
5411
|
-
const ordered = [];
|
|
5412
|
-
const tag = tagById.get(tagId);
|
|
5413
|
-
let primary;
|
|
5414
|
-
let primaryOrigin;
|
|
5415
|
-
if ((tag == null ? void 0 : tag.service_id) !== void 0) {
|
|
5416
|
-
primary = tag.service_id;
|
|
5417
|
-
primaryOrigin = "tag";
|
|
5418
|
-
}
|
|
5419
|
-
const optionVisit = buildOptionVisitOrder(selection, fieldById);
|
|
5420
|
-
for (const { fieldId, optionId } of optionVisit) {
|
|
5421
|
-
if (!visibleFieldIds.includes(fieldId)) continue;
|
|
5422
|
-
const f = fieldById.get(fieldId);
|
|
5423
|
-
if (!f || !Array.isArray(f.options)) continue;
|
|
5424
|
-
const opt = f.options.find((o) => o.id === optionId);
|
|
5425
|
-
if (!opt) continue;
|
|
5426
|
-
const role = (_a2 = opt.pricing_role) != null ? _a2 : "base";
|
|
5427
|
-
const sid = opt.service_id;
|
|
5428
|
-
if (role === "utility") continue;
|
|
5429
|
-
if (sid !== void 0) {
|
|
5430
|
-
if (primary === void 0 || primaryOrigin === "tag") {
|
|
5431
|
-
primary = sid;
|
|
5432
|
-
primaryOrigin = "option";
|
|
5433
|
-
ordered.length = 0;
|
|
5434
|
-
ordered.push(primary);
|
|
5435
|
-
} else {
|
|
5436
|
-
ordered.push(sid);
|
|
5437
|
-
}
|
|
5438
|
-
pushService(serviceMap, optionId, sid);
|
|
5439
|
-
}
|
|
5440
|
-
}
|
|
5441
|
-
if (primaryOrigin !== "option" && primary !== void 0) {
|
|
5442
|
-
ordered.unshift(primary);
|
|
5443
|
-
pushService(serviceMap, tagId, primary);
|
|
5444
|
-
} else {
|
|
5445
|
-
}
|
|
5446
|
-
const servicesList = dedupeByString(ordered);
|
|
5447
|
-
return { serviceMap, servicesList };
|
|
5448
|
-
}
|
|
5449
|
-
function buildOptionVisitOrder(selection, fieldById) {
|
|
5450
|
-
var _a2;
|
|
5451
|
-
if (selection.optionTraversalOrder && selection.optionTraversalOrder.length) {
|
|
5452
|
-
return selection.optionTraversalOrder.slice();
|
|
5453
|
-
}
|
|
5454
|
-
const out = [];
|
|
5455
|
-
for (const [fid, optIds] of Object.entries(
|
|
5456
|
-
(_a2 = selection.optionSelectionsByFieldId) != null ? _a2 : {}
|
|
5457
|
-
)) {
|
|
5458
|
-
const f = fieldById.get(fid);
|
|
5459
|
-
if (!f) continue;
|
|
5460
|
-
for (const oid of optIds != null ? optIds : [])
|
|
5461
|
-
out.push({ fieldId: fid, optionId: oid });
|
|
5462
|
-
}
|
|
5463
|
-
return out;
|
|
5464
|
-
}
|
|
5465
|
-
function pushService(map, nodeId, sid) {
|
|
5466
|
-
if (!map[nodeId]) map[nodeId] = [];
|
|
5467
|
-
map[nodeId].push(sid);
|
|
5468
|
-
}
|
|
5469
|
-
function dedupeByString(arr) {
|
|
5470
|
-
const s = /* @__PURE__ */ new Set();
|
|
5471
|
-
const out = [];
|
|
5472
|
-
for (const v of arr) {
|
|
5473
|
-
const key = String(v);
|
|
5474
|
-
if (s.has(key)) continue;
|
|
5475
|
-
s.add(key);
|
|
5476
|
-
out.push(v);
|
|
5477
|
-
}
|
|
5478
|
-
return out;
|
|
5479
|
-
}
|
|
5480
|
-
function pruneFallbacksConservative(fallbacks, env, svcMap, policy) {
|
|
5481
|
-
var _a2, _b;
|
|
5482
|
-
if (!fallbacks) return { pruned: void 0, original: void 0 };
|
|
5483
|
-
try {
|
|
5484
|
-
const { props: prunedProps } = pruneInvalidNodeFallbacks(
|
|
5485
|
-
{
|
|
5486
|
-
filters: [],
|
|
5487
|
-
fields: [],
|
|
5488
|
-
schema_version: "1.0",
|
|
5489
|
-
fallbacks
|
|
5490
|
-
},
|
|
5491
|
-
svcMap,
|
|
5492
|
-
policy
|
|
5493
|
-
);
|
|
5494
|
-
return {
|
|
5495
|
-
pruned: prunedProps.fallbacks,
|
|
5496
|
-
original: fallbacks
|
|
5497
|
-
};
|
|
5498
|
-
} catch {
|
|
5499
|
-
const out = {};
|
|
5500
|
-
const requireFit = (_a2 = policy.requireConstraintFit) != null ? _a2 : true;
|
|
5501
|
-
if (fallbacks.nodes) {
|
|
5502
|
-
const keptNodes = {};
|
|
5503
|
-
for (const [nodeId, candidates] of Object.entries(
|
|
5504
|
-
fallbacks.nodes
|
|
5505
|
-
)) {
|
|
5506
|
-
if (!env.serviceMap[nodeId]) continue;
|
|
5507
|
-
const primary = ((_b = env.serviceMap[nodeId]) != null ? _b : [])[0];
|
|
5508
|
-
const kept = [];
|
|
5509
|
-
for (const cand of candidates != null ? candidates : []) {
|
|
5510
|
-
if (!rateOk(svcMap, cand, primary, policy)) continue;
|
|
5511
|
-
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints))
|
|
5512
|
-
continue;
|
|
5513
|
-
kept.push(cand);
|
|
5514
|
-
}
|
|
5515
|
-
if (kept.length) keptNodes[nodeId] = kept;
|
|
5516
|
-
}
|
|
5517
|
-
if (Object.keys(keptNodes).length) out.nodes = keptNodes;
|
|
5518
|
-
}
|
|
5519
|
-
if (fallbacks.global) {
|
|
5520
|
-
const keptGlobal = {};
|
|
5521
|
-
const present = new Set(env.servicesList.map((sid) => String(sid)));
|
|
5522
|
-
for (const [primary, cands] of Object.entries(
|
|
5523
|
-
fallbacks.global
|
|
5524
|
-
)) {
|
|
5525
|
-
if (!present.has(String(primary))) continue;
|
|
5526
|
-
const primId = isFiniteNumber2(primary) ? Number(primary) : primary;
|
|
5527
|
-
const kept = [];
|
|
5528
|
-
for (const cand of cands != null ? cands : []) {
|
|
5529
|
-
if (!rateOk(svcMap, cand, primId, policy)) continue;
|
|
5530
|
-
if (requireFit && env.constraints && !constraintFitOk(svcMap, cand, env.constraints))
|
|
5531
|
-
continue;
|
|
5532
|
-
kept.push(cand);
|
|
5533
|
-
}
|
|
5534
|
-
if (kept.length) keptGlobal[primId] = kept;
|
|
5535
|
-
}
|
|
5536
|
-
if (Object.keys(keptGlobal).length)
|
|
5537
|
-
out.global = keptGlobal;
|
|
5538
|
-
}
|
|
5539
|
-
return {
|
|
5540
|
-
pruned: Object.keys(out).length ? out : void 0,
|
|
5541
|
-
original: fallbacks
|
|
5542
|
-
};
|
|
5543
|
-
}
|
|
5544
|
-
}
|
|
5545
|
-
function isFiniteNumber2(v) {
|
|
5546
|
-
return typeof v === "number" && Number.isFinite(v);
|
|
5495
|
+
function readPositiveFiniteNumber(value) {
|
|
5496
|
+
const n = Number(value);
|
|
5497
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
5547
5498
|
}
|
|
5548
|
-
|
|
5499
|
+
|
|
5500
|
+
// src/utils/build-order-snapshot/utilities.ts
|
|
5501
|
+
function collectUtilityLineItems(visibleFieldIds, fieldById, selection, selectedOptionsByFieldId, quantity) {
|
|
5549
5502
|
var _a2, _b, _c, _d, _e;
|
|
5550
5503
|
const items = [];
|
|
5551
5504
|
for (const fid of visibleFieldIds) {
|
|
5552
|
-
const
|
|
5553
|
-
if (!
|
|
5554
|
-
const isUtilityField = ((_a2 =
|
|
5555
|
-
const marker = readUtilityMarker((_b =
|
|
5505
|
+
const field = fieldById.get(fid);
|
|
5506
|
+
if (!field) continue;
|
|
5507
|
+
const isUtilityField = ((_a2 = field.pricing_role) != null ? _a2 : "base") === "utility";
|
|
5508
|
+
const marker = readUtilityMarker((_b = field.meta) == null ? void 0 : _b.utility);
|
|
5556
5509
|
if (isUtilityField && marker) {
|
|
5557
|
-
const
|
|
5558
|
-
const item = buildUtilityItemFromMarker(
|
|
5559
|
-
f.id,
|
|
5560
|
-
marker,
|
|
5561
|
-
quantity,
|
|
5562
|
-
val
|
|
5563
|
-
);
|
|
5510
|
+
const value = selection.formValuesByFieldId[field.id];
|
|
5511
|
+
const item = buildUtilityItemFromMarker(field.id, marker, quantity, value);
|
|
5564
5512
|
if (item) items.push(item);
|
|
5565
5513
|
}
|
|
5566
|
-
if (Array.isArray(
|
|
5567
|
-
const
|
|
5568
|
-
if (
|
|
5569
|
-
|
|
5570
|
-
|
|
5514
|
+
if (Array.isArray(field.options) && field.options.length) {
|
|
5515
|
+
const selectedOptionIds = (_c = selectedOptionsByFieldId[field.id]) != null ? _c : [];
|
|
5516
|
+
if (!selectedOptionIds.length) continue;
|
|
5517
|
+
const optById = new Map(field.options.map((o) => [o.id, o]));
|
|
5518
|
+
for (const oid of selectedOptionIds) {
|
|
5519
|
+
const option = optById.get(oid);
|
|
5520
|
+
if (!option) continue;
|
|
5521
|
+
if (((_d = option.pricing_role) != null ? _d : "base") !== "utility") continue;
|
|
5522
|
+
const optionMarker = readUtilityMarker((_e = option.meta) == null ? void 0 : _e.utility);
|
|
5523
|
+
if (!optionMarker) continue;
|
|
5524
|
+
const parentValue = selection.formValuesByFieldId[field.id];
|
|
5525
|
+
const item = buildUtilityItemFromMarker(
|
|
5526
|
+
option.id,
|
|
5527
|
+
optionMarker,
|
|
5528
|
+
quantity,
|
|
5529
|
+
parentValue
|
|
5571
5530
|
);
|
|
5572
|
-
|
|
5573
|
-
const opt = optById.get(oid);
|
|
5574
|
-
if (!opt) continue;
|
|
5575
|
-
if (((_d = opt.pricing_role) != null ? _d : "base") !== "utility") continue;
|
|
5576
|
-
const om = readUtilityMarker((_e = opt.meta) == null ? void 0 : _e.utility);
|
|
5577
|
-
if (!om) continue;
|
|
5578
|
-
const parentVal = selection.formValuesByFieldId[f.id];
|
|
5579
|
-
const item = buildUtilityItemFromMarker(
|
|
5580
|
-
opt.id,
|
|
5581
|
-
om,
|
|
5582
|
-
quantity,
|
|
5583
|
-
parentVal
|
|
5584
|
-
);
|
|
5585
|
-
if (item) items.push(item);
|
|
5586
|
-
}
|
|
5531
|
+
if (item) items.push(item);
|
|
5587
5532
|
}
|
|
5588
5533
|
}
|
|
5589
5534
|
}
|
|
@@ -5592,19 +5537,16 @@ function collectUtilityLineItems(visibleFieldIds, fieldById, selection, quantity
|
|
|
5592
5537
|
function readUtilityMarker(v) {
|
|
5593
5538
|
if (!v || typeof v !== "object") return void 0;
|
|
5594
5539
|
const src = v;
|
|
5595
|
-
if (!src.mode || typeof src.rate !== "number" || !Number.isFinite(src.rate))
|
|
5596
|
-
|
|
5597
|
-
if (src.mode !== "flat" && src.mode !== "per_quantity" && src.mode !== "per_value" && src.mode !== "percent")
|
|
5540
|
+
if (!src.mode || typeof src.rate !== "number" || !Number.isFinite(src.rate)) return void 0;
|
|
5541
|
+
if (src.mode !== "flat" && src.mode !== "per_quantity" && src.mode !== "per_value" && src.mode !== "percent") {
|
|
5598
5542
|
return void 0;
|
|
5543
|
+
}
|
|
5599
5544
|
const out = { mode: src.mode, rate: src.rate };
|
|
5600
|
-
if (src.valueBy === "value" || src.valueBy === "length")
|
|
5601
|
-
out.valueBy = src.valueBy;
|
|
5545
|
+
if (src.valueBy === "value" || src.valueBy === "length") out.valueBy = src.valueBy;
|
|
5602
5546
|
if (src.percentBase === "service_total" || src.percentBase === "base_service" || src.percentBase === "all") {
|
|
5603
5547
|
out.percentBase = src.percentBase;
|
|
5604
5548
|
}
|
|
5605
|
-
if (typeof src.label === "string" && src.label.trim())
|
|
5606
|
-
out.label = src.label.trim();
|
|
5607
|
-
}
|
|
5549
|
+
if (typeof src.label === "string" && src.label.trim()) out.label = src.label.trim();
|
|
5608
5550
|
return out;
|
|
5609
5551
|
}
|
|
5610
5552
|
function buildUtilityItemFromMarker(nodeId, marker, quantity, value) {
|
|
@@ -5627,17 +5569,19 @@ function buildUtilityItemFromMarker(nodeId, marker, quantity, value) {
|
|
|
5627
5569
|
}
|
|
5628
5570
|
return base;
|
|
5629
5571
|
}
|
|
5630
|
-
|
|
5572
|
+
|
|
5573
|
+
// src/utils/build-order-snapshot/context.ts
|
|
5574
|
+
function buildNodeContexts(tagId, visibleFieldIds, fieldById, _selection, selectedOptionsByFieldId) {
|
|
5631
5575
|
var _a2;
|
|
5632
5576
|
const ctx = {};
|
|
5633
5577
|
ctx[tagId] = tagId;
|
|
5634
5578
|
for (const fid of visibleFieldIds) {
|
|
5635
|
-
const
|
|
5636
|
-
if (!
|
|
5637
|
-
const binds = normalizeBindIds(
|
|
5579
|
+
const field = fieldById.get(fid);
|
|
5580
|
+
if (!field) continue;
|
|
5581
|
+
const binds = normalizeBindIds(field.bind_id);
|
|
5638
5582
|
const applicable = binds.has(tagId);
|
|
5639
|
-
const
|
|
5640
|
-
for (const oid of
|
|
5583
|
+
const selectedOptionIds = (_a2 = selectedOptionsByFieldId[fid]) != null ? _a2 : [];
|
|
5584
|
+
for (const oid of selectedOptionIds) {
|
|
5641
5585
|
ctx[oid] = applicable ? tagId : null;
|
|
5642
5586
|
}
|
|
5643
5587
|
}
|
|
@@ -5653,66 +5597,159 @@ function normalizeBindIds(bind) {
|
|
|
5653
5597
|
}
|
|
5654
5598
|
return out;
|
|
5655
5599
|
}
|
|
5656
|
-
|
|
5600
|
+
|
|
5601
|
+
// src/utils/build-order-snapshot/warnings.ts
|
|
5602
|
+
function buildDevWarnings(props, svcMap, originalFallbacks, fieldById, visibleFieldIds, selection) {
|
|
5657
5603
|
const out = {};
|
|
5658
5604
|
const maybeCollectFailed = globalThis.collectFailedFallbacks;
|
|
5659
5605
|
try {
|
|
5660
5606
|
if (maybeCollectFailed && originalFallbacks) {
|
|
5661
5607
|
const diags = maybeCollectFailed(
|
|
5662
|
-
{
|
|
5663
|
-
...props,
|
|
5664
|
-
fallbacks: originalFallbacks
|
|
5665
|
-
},
|
|
5608
|
+
{ ...props, fallbacks: originalFallbacks },
|
|
5666
5609
|
svcMap,
|
|
5667
5610
|
{ mode: "dev" }
|
|
5668
5611
|
);
|
|
5669
|
-
if (diags
|
|
5670
|
-
out.fallbacks = diags;
|
|
5671
|
-
}
|
|
5612
|
+
if (diags == null ? void 0 : diags.length) out.fallbacks = diags;
|
|
5672
5613
|
}
|
|
5673
5614
|
} catch {
|
|
5674
5615
|
}
|
|
5675
5616
|
const utilityWarnings = [];
|
|
5676
5617
|
for (const fid of visibleFieldIds) {
|
|
5677
|
-
const
|
|
5678
|
-
if (!
|
|
5679
|
-
const
|
|
5680
|
-
if (
|
|
5618
|
+
const field = fieldById.get(fid);
|
|
5619
|
+
if (!field) continue;
|
|
5620
|
+
const hasValue = selection.formValuesByFieldId[fid] !== void 0;
|
|
5621
|
+
if (hasValue && !field.name && !isOptionBased(field)) {
|
|
5681
5622
|
utilityWarnings.push({
|
|
5682
5623
|
nodeId: fid,
|
|
5683
5624
|
reason: "missing_field_name_for_form_value"
|
|
5684
5625
|
});
|
|
5685
5626
|
}
|
|
5686
5627
|
}
|
|
5687
|
-
if (utilityWarnings.length)
|
|
5688
|
-
out.utility = utilityWarnings;
|
|
5689
|
-
}
|
|
5628
|
+
if (utilityWarnings.length) out.utility = utilityWarnings;
|
|
5690
5629
|
if (!out.fallbacks && !out.utility) return void 0;
|
|
5691
5630
|
return out;
|
|
5692
5631
|
}
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
}
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5632
|
+
|
|
5633
|
+
// src/utils/build-order-snapshot/index.ts
|
|
5634
|
+
function buildOrderSnapshot(props, builder, selection, services, settings = {}) {
|
|
5635
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
5636
|
+
const mode = (_a2 = settings.mode) != null ? _a2 : "prod";
|
|
5637
|
+
const hostDefaultQty = Number.isFinite((_b = settings.hostDefaultQuantity) != null ? _b : 1) ? settings.hostDefaultQuantity : 1;
|
|
5638
|
+
const fbSettings = {
|
|
5639
|
+
requireConstraintFit: true,
|
|
5640
|
+
ratePolicy: { kind: "lte_primary", pct: 5 },
|
|
5641
|
+
selectionStrategy: "priority",
|
|
5642
|
+
mode: mode === "dev" ? "dev" : "strict",
|
|
5643
|
+
...(_c = settings.fallback) != null ? _c : {}
|
|
5644
|
+
};
|
|
5645
|
+
const builtAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5646
|
+
const tagId = selection.activeTagId;
|
|
5647
|
+
const selectedButtonKeys = (_d = selection.selectedKeys) != null ? _d : toSelectedOptionKeys(selection.optionSelectionsByFieldId);
|
|
5648
|
+
const visibleFieldIds = builder.visibleFields(tagId, selectedButtonKeys);
|
|
5649
|
+
const tagById = new Map(((_e = props.filters) != null ? _e : []).map((t) => [t.id, t]));
|
|
5650
|
+
const fieldById = new Map(((_f = props.fields) != null ? _f : []).map((f) => [f.id, f]));
|
|
5651
|
+
const tagConstraints = (_h = (_g = tagById.get(tagId)) == null ? void 0 : _g.constraints) != null ? _h : void 0;
|
|
5652
|
+
const selectedOptionsByFieldId = getSelectedOptionsByFieldId(selection, fieldById);
|
|
5653
|
+
const selectionFields = visibleFieldIds.map((fid) => fieldById.get(fid)).filter((f) => !!f).map((f) => {
|
|
5654
|
+
var _a3;
|
|
5655
|
+
const optionIds = isOptionBased(f) ? (_a3 = selectedOptionsByFieldId[f.id]) != null ? _a3 : [] : void 0;
|
|
5656
|
+
return {
|
|
5657
|
+
id: f.id,
|
|
5658
|
+
type: String(f.type),
|
|
5659
|
+
...optionIds && optionIds.length ? { selectedOptions: optionIds } : {}
|
|
5660
|
+
};
|
|
5661
|
+
});
|
|
5662
|
+
const { formValues, selections } = buildInputs(
|
|
5663
|
+
visibleFieldIds,
|
|
5664
|
+
fieldById,
|
|
5665
|
+
selection,
|
|
5666
|
+
selectedOptionsByFieldId
|
|
5667
|
+
);
|
|
5668
|
+
const qtyRes = resolveQuantity(
|
|
5669
|
+
visibleFieldIds,
|
|
5670
|
+
fieldById,
|
|
5671
|
+
tagById,
|
|
5672
|
+
selection,
|
|
5673
|
+
tagId,
|
|
5674
|
+
hostDefaultQty
|
|
5675
|
+
);
|
|
5676
|
+
const { serviceMap, servicesList } = resolveServices(
|
|
5677
|
+
tagId,
|
|
5678
|
+
visibleFieldIds,
|
|
5679
|
+
selection,
|
|
5680
|
+
tagById,
|
|
5681
|
+
fieldById,
|
|
5682
|
+
services
|
|
5683
|
+
);
|
|
5684
|
+
const { min, max } = resolveMinMax(servicesList, services);
|
|
5685
|
+
const maybeNodeMap = typeof builder.getNodeMap === "function" ? builder.getNodeMap() : void 0;
|
|
5686
|
+
const resolvedOrderKind = resolveOrderKind({
|
|
5687
|
+
props,
|
|
5688
|
+
activeTagId: tagId,
|
|
5689
|
+
selectedTriggerKeys: selectedButtonKeys,
|
|
5690
|
+
nodeMap: maybeNodeMap
|
|
5691
|
+
});
|
|
5692
|
+
const prunedFallbacks = pruneFallbacksConservative(
|
|
5693
|
+
props.fallbacks,
|
|
5694
|
+
{ tagId, constraints: tagConstraints, serviceMap, servicesList },
|
|
5695
|
+
services,
|
|
5696
|
+
fbSettings
|
|
5697
|
+
);
|
|
5698
|
+
const utilities = collectUtilityLineItems(
|
|
5699
|
+
visibleFieldIds,
|
|
5700
|
+
fieldById,
|
|
5701
|
+
selection,
|
|
5702
|
+
selectedOptionsByFieldId,
|
|
5703
|
+
qtyRes.quantity
|
|
5704
|
+
);
|
|
5705
|
+
const warnings = mode === "dev" ? buildDevWarnings(
|
|
5706
|
+
props,
|
|
5707
|
+
services,
|
|
5708
|
+
prunedFallbacks.original,
|
|
5709
|
+
fieldById,
|
|
5710
|
+
visibleFieldIds,
|
|
5711
|
+
selection
|
|
5712
|
+
) : void 0;
|
|
5713
|
+
const meta = {
|
|
5714
|
+
schema_version: props.schema_version,
|
|
5715
|
+
workspaceId: settings.workspaceId,
|
|
5716
|
+
builder: settings.builderCommit ? { commit: settings.builderCommit } : void 0,
|
|
5717
|
+
context: {
|
|
5718
|
+
tag: tagId,
|
|
5719
|
+
constraints: tagConstraints != null ? tagConstraints : {},
|
|
5720
|
+
nodeContexts: buildNodeContexts(
|
|
5721
|
+
tagId,
|
|
5722
|
+
visibleFieldIds,
|
|
5723
|
+
fieldById,
|
|
5724
|
+
selection,
|
|
5725
|
+
selectedOptionsByFieldId
|
|
5726
|
+
),
|
|
5727
|
+
policy: toSnapshotPolicy(fbSettings)
|
|
5713
5728
|
}
|
|
5714
|
-
}
|
|
5715
|
-
return {
|
|
5729
|
+
};
|
|
5730
|
+
return {
|
|
5731
|
+
version: "1",
|
|
5732
|
+
mode,
|
|
5733
|
+
builtAt,
|
|
5734
|
+
selection: {
|
|
5735
|
+
tag: tagId,
|
|
5736
|
+
buttons: selectedButtonKeys,
|
|
5737
|
+
fields: selectionFields
|
|
5738
|
+
},
|
|
5739
|
+
inputs: { form: formValues, selections },
|
|
5740
|
+
min,
|
|
5741
|
+
max: max != null ? max : min,
|
|
5742
|
+
orderKind: resolvedOrderKind.kind,
|
|
5743
|
+
orderKindSource: resolvedOrderKind.source,
|
|
5744
|
+
quantity: qtyRes.quantity,
|
|
5745
|
+
quantitySource: qtyRes.source,
|
|
5746
|
+
services: servicesList,
|
|
5747
|
+
serviceMap,
|
|
5748
|
+
...prunedFallbacks.pruned ? { fallbacks: prunedFallbacks.pruned } : {},
|
|
5749
|
+
...utilities.length ? { utilities } : {},
|
|
5750
|
+
...warnings ? { warnings } : {},
|
|
5751
|
+
meta
|
|
5752
|
+
};
|
|
5716
5753
|
}
|
|
5717
5754
|
|
|
5718
5755
|
// src/core/fallback-editor.ts
|