@timeax/digital-service-engine 0.0.2 → 0.0.4
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 +364 -15
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +323 -200
- package/dist/core/index.d.ts +323 -200
- package/dist/core/index.js +362 -15
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +145 -56
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +407 -254
- package/dist/react/index.d.ts +407 -254
- package/dist/react/index.js +145 -56
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +376 -245
- package/dist/schema/index.d.ts +376 -245
- package/dist/workspace/index.cjs +100 -23
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +165 -140
- package/dist/workspace/index.d.ts +165 -140
- package/dist/workspace/index.js +100 -23
- package/dist/workspace/index.js.map +1 -1
- package/package.json +106 -106
package/dist/core/index.d.cts
CHANGED
|
@@ -1,198 +1,3 @@
|
|
|
1
|
-
type PricingRole = "base" | "utility";
|
|
2
|
-
type FieldType = "custom" | (string & {});
|
|
3
|
-
/** ── Marker types (live inside meta; non-breaking) ───────────────────── */
|
|
4
|
-
type QuantityMark = {
|
|
5
|
-
quantity?: {
|
|
6
|
-
valueBy: "value" | "length" | "eval";
|
|
7
|
-
code?: string;
|
|
8
|
-
multiply?: number;
|
|
9
|
-
clamp?: {
|
|
10
|
-
min?: number;
|
|
11
|
-
max?: number;
|
|
12
|
-
};
|
|
13
|
-
fallback?: number;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
type UtilityMark = {
|
|
17
|
-
utility?: {
|
|
18
|
-
rate: number;
|
|
19
|
-
mode: "flat" | "per_quantity" | "per_value" | "percent";
|
|
20
|
-
valueBy?: "value" | "length";
|
|
21
|
-
percentBase?: "service_total" | "base_service" | "all";
|
|
22
|
-
label?: string;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
type WithQuantityDefault = {
|
|
26
|
-
quantityDefault?: number;
|
|
27
|
-
};
|
|
28
|
-
/** ---------------- Core schema (as you designed) ---------------- */
|
|
29
|
-
interface BaseFieldUI {
|
|
30
|
-
name?: string;
|
|
31
|
-
label: string;
|
|
32
|
-
required?: boolean;
|
|
33
|
-
/** Host-defined prop names → runtime default values (untyped base) */
|
|
34
|
-
defaults?: Record<string, unknown>;
|
|
35
|
-
}
|
|
36
|
-
type FieldOption = {
|
|
37
|
-
id: string;
|
|
38
|
-
label: string;
|
|
39
|
-
value?: string | number;
|
|
40
|
-
service_id?: number;
|
|
41
|
-
pricing_role?: PricingRole;
|
|
42
|
-
meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
|
|
43
|
-
};
|
|
44
|
-
type Field = BaseFieldUI & {
|
|
45
|
-
id: string;
|
|
46
|
-
type: FieldType;
|
|
47
|
-
bind_id?: string | string[];
|
|
48
|
-
name?: string;
|
|
49
|
-
options?: FieldOption[];
|
|
50
|
-
description?: string;
|
|
51
|
-
component?: string;
|
|
52
|
-
pricing_role?: PricingRole;
|
|
53
|
-
meta?: Record<string, unknown> & QuantityMark & UtilityMark & {
|
|
54
|
-
multi?: boolean;
|
|
55
|
-
};
|
|
56
|
-
} & ({
|
|
57
|
-
button?: false;
|
|
58
|
-
service_id?: undefined;
|
|
59
|
-
} | ({
|
|
60
|
-
button: true;
|
|
61
|
-
service_id?: number;
|
|
62
|
-
} & WithQuantityDefault));
|
|
63
|
-
type ConstraintKey = string;
|
|
64
|
-
type Tag = {
|
|
65
|
-
id: string;
|
|
66
|
-
label: string;
|
|
67
|
-
bind_id?: string;
|
|
68
|
-
service_id?: number;
|
|
69
|
-
includes?: string[];
|
|
70
|
-
excludes?: string[];
|
|
71
|
-
meta?: Record<string, unknown> & WithQuantityDefault;
|
|
72
|
-
/**
|
|
73
|
-
* Which flags are set for this tag. If a flag is not set, it's inherited from the nearest ancestor with a value set.
|
|
74
|
-
*/
|
|
75
|
-
constraints?: Partial<Record<ConstraintKey, boolean>>;
|
|
76
|
-
/** Which ancestor defined the *effective* value for each flag (nearest source). */
|
|
77
|
-
constraints_origin?: Partial<Record<ConstraintKey, string>>;
|
|
78
|
-
/**
|
|
79
|
-
* Present only when a child explicitly set a different value but was overridden
|
|
80
|
-
* by an ancestor during normalisation.
|
|
81
|
-
*/
|
|
82
|
-
constraints_overrides?: Partial<Record<ConstraintKey, {
|
|
83
|
-
from: boolean;
|
|
84
|
-
to: boolean;
|
|
85
|
-
origin: string;
|
|
86
|
-
}>>;
|
|
87
|
-
};
|
|
88
|
-
type ServiceProps = {
|
|
89
|
-
order_for_tags?: Record<string, string[]>;
|
|
90
|
-
filters: Tag[];
|
|
91
|
-
fields: Field[];
|
|
92
|
-
includes_for_buttons?: Record<string, string[]>;
|
|
93
|
-
excludes_for_buttons?: Record<string, string[]>;
|
|
94
|
-
schema_version?: string;
|
|
95
|
-
fallbacks?: ServiceFallback;
|
|
96
|
-
name?: string;
|
|
97
|
-
notices?: ServicePropsNotice[];
|
|
98
|
-
};
|
|
99
|
-
type ServiceIdRef = number | string;
|
|
100
|
-
type NodeIdRef = string;
|
|
101
|
-
type ServiceFallback = {
|
|
102
|
-
/** Node-scoped fallbacks: prefer these when that node’s primary service fails */
|
|
103
|
-
nodes?: Record<NodeIdRef, ServiceIdRef[]>;
|
|
104
|
-
/** Primary→fallback list used when no node-scoped entry is present */
|
|
105
|
-
global?: Record<ServiceIdRef, ServiceIdRef[]>;
|
|
106
|
-
};
|
|
107
|
-
type NoticeType = "public" | "private";
|
|
108
|
-
type NoticeSeverity = "info" | "warning" | "error";
|
|
109
|
-
/**
|
|
110
|
-
* “label” is lightweight + UI-friendly (best, sale, hot, etc).
|
|
111
|
-
* Others remain semantic / governance oriented.
|
|
112
|
-
*/
|
|
113
|
-
type NoticeKind = "label" | "warning" | "deprecation" | "compat" | "migration" | "policy";
|
|
114
|
-
type NoticeTarget = {
|
|
115
|
-
scope: "global";
|
|
116
|
-
} | {
|
|
117
|
-
scope: "node";
|
|
118
|
-
node_kind: "tag" | "field" | "option";
|
|
119
|
-
node_id: string;
|
|
120
|
-
};
|
|
121
|
-
interface ServicePropsNotice {
|
|
122
|
-
id: string;
|
|
123
|
-
type: NoticeType;
|
|
124
|
-
kind: NoticeKind;
|
|
125
|
-
severity: NoticeSeverity;
|
|
126
|
-
target: NoticeTarget;
|
|
127
|
-
title: string;
|
|
128
|
-
description?: string;
|
|
129
|
-
reason?: string;
|
|
130
|
-
marked_at?: string;
|
|
131
|
-
icon?: string;
|
|
132
|
-
color?: string;
|
|
133
|
-
meta?: Record<string, unknown>;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
type NodeKind$1 = "tag" | "field" | "comment" | "option";
|
|
137
|
-
type EdgeKind = "child" | "bind" | "include" | "exclude" | "error" | "anchor";
|
|
138
|
-
type GraphNode = {
|
|
139
|
-
id: string;
|
|
140
|
-
kind: NodeKind$1;
|
|
141
|
-
bind_type?: "bound" | "utility" | null;
|
|
142
|
-
errors?: string[];
|
|
143
|
-
label: string;
|
|
144
|
-
};
|
|
145
|
-
type GraphEdge = {
|
|
146
|
-
from: string;
|
|
147
|
-
to: string;
|
|
148
|
-
kind: EdgeKind;
|
|
149
|
-
meta?: Record<string, unknown>;
|
|
150
|
-
};
|
|
151
|
-
type GraphSnapshot = {
|
|
152
|
-
nodes: GraphNode[];
|
|
153
|
-
edges: GraphEdge[];
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
type TimeRangeEstimate = {
|
|
157
|
-
min_seconds?: number;
|
|
158
|
-
max_seconds?: number;
|
|
159
|
-
label?: string;
|
|
160
|
-
meta?: Record<string, unknown>;
|
|
161
|
-
};
|
|
162
|
-
type SpeedEstimate = {
|
|
163
|
-
amount?: number;
|
|
164
|
-
per?: "minute" | "hour" | "day" | "week" | "month";
|
|
165
|
-
unit?: string;
|
|
166
|
-
label?: string;
|
|
167
|
-
meta?: Record<string, unknown>;
|
|
168
|
-
};
|
|
169
|
-
type ServiceEstimates = {
|
|
170
|
-
start?: TimeRangeEstimate;
|
|
171
|
-
speed?: SpeedEstimate;
|
|
172
|
-
average?: TimeRangeEstimate;
|
|
173
|
-
meta?: Record<string, unknown>;
|
|
174
|
-
};
|
|
175
|
-
type ServiceFlag = {
|
|
176
|
-
enabled: boolean;
|
|
177
|
-
description: string;
|
|
178
|
-
meta?: Record<string, unknown>;
|
|
179
|
-
};
|
|
180
|
-
type IdType = string | number;
|
|
181
|
-
type ServiceFlags = Record<string, ServiceFlag>;
|
|
182
|
-
type DgpServiceCapability = {
|
|
183
|
-
id: IdType;
|
|
184
|
-
name?: string;
|
|
185
|
-
rate: number;
|
|
186
|
-
min?: number;
|
|
187
|
-
max?: number;
|
|
188
|
-
category?: string;
|
|
189
|
-
flags?: ServiceFlags;
|
|
190
|
-
estimates?: ServiceEstimates;
|
|
191
|
-
meta?: Record<string, unknown>;
|
|
192
|
-
[x: string]: any;
|
|
193
|
-
};
|
|
194
|
-
type DgpServiceMap = Record<string, DgpServiceCapability> & Record<number, DgpServiceCapability>;
|
|
195
|
-
|
|
196
1
|
interface ButtonValue {
|
|
197
2
|
id: string;
|
|
198
3
|
value: string | number;
|
|
@@ -217,6 +22,7 @@ type UtilityLineItem = {
|
|
|
217
22
|
evalCodeUsed?: boolean;
|
|
218
23
|
};
|
|
219
24
|
};
|
|
25
|
+
type ServiceFallbacks = ServiceFallback;
|
|
220
26
|
type FallbackDiagnostics = {
|
|
221
27
|
scope: "node" | "global";
|
|
222
28
|
nodeId?: string;
|
|
@@ -251,6 +57,7 @@ type OrderSnapshot = {
|
|
|
251
57
|
builtAt: string;
|
|
252
58
|
selection: {
|
|
253
59
|
tag: string;
|
|
60
|
+
buttons: string[];
|
|
254
61
|
fields: Array<{
|
|
255
62
|
id: string;
|
|
256
63
|
type: string;
|
|
@@ -272,10 +79,7 @@ type OrderSnapshot = {
|
|
|
272
79
|
max: number;
|
|
273
80
|
services: Array<string | number>;
|
|
274
81
|
serviceMap: Record<string, Array<string | number>>;
|
|
275
|
-
fallbacks?:
|
|
276
|
-
nodes?: Record<string, Array<string | number>>;
|
|
277
|
-
global?: Record<string | number, Array<string | number>>;
|
|
278
|
-
};
|
|
82
|
+
fallbacks?: ServiceFallbacks;
|
|
279
83
|
utilities?: UtilityLineItem[];
|
|
280
84
|
warnings?: {
|
|
281
85
|
utility?: Array<{
|
|
@@ -294,6 +98,46 @@ type OrderSnapshot = {
|
|
|
294
98
|
};
|
|
295
99
|
};
|
|
296
100
|
|
|
101
|
+
type TimeRangeEstimate = {
|
|
102
|
+
min_seconds?: number;
|
|
103
|
+
max_seconds?: number;
|
|
104
|
+
label?: string;
|
|
105
|
+
meta?: Record<string, unknown>;
|
|
106
|
+
};
|
|
107
|
+
type SpeedEstimate = {
|
|
108
|
+
amount?: number;
|
|
109
|
+
per?: "minute" | "hour" | "day" | "week" | "month";
|
|
110
|
+
unit?: string;
|
|
111
|
+
label?: string;
|
|
112
|
+
meta?: Record<string, unknown>;
|
|
113
|
+
};
|
|
114
|
+
type ServiceEstimates = {
|
|
115
|
+
start?: TimeRangeEstimate;
|
|
116
|
+
speed?: SpeedEstimate;
|
|
117
|
+
average?: TimeRangeEstimate;
|
|
118
|
+
meta?: Record<string, unknown>;
|
|
119
|
+
};
|
|
120
|
+
type ServiceFlag = {
|
|
121
|
+
enabled: boolean;
|
|
122
|
+
description: string;
|
|
123
|
+
meta?: Record<string, unknown>;
|
|
124
|
+
};
|
|
125
|
+
type IdType = string | number;
|
|
126
|
+
type ServiceFlags = Record<string, ServiceFlag>;
|
|
127
|
+
type DgpServiceCapability = {
|
|
128
|
+
id: IdType;
|
|
129
|
+
name?: string;
|
|
130
|
+
rate: number;
|
|
131
|
+
min?: number;
|
|
132
|
+
max?: number;
|
|
133
|
+
category?: string;
|
|
134
|
+
flags?: ServiceFlags;
|
|
135
|
+
estimates?: ServiceEstimates;
|
|
136
|
+
meta?: Record<string, unknown>;
|
|
137
|
+
[x: string]: any;
|
|
138
|
+
};
|
|
139
|
+
type DgpServiceMap = Record<string, DgpServiceCapability> & Record<number, DgpServiceCapability>;
|
|
140
|
+
|
|
297
141
|
type NodeRef = {
|
|
298
142
|
kind: "tag";
|
|
299
143
|
id: string;
|
|
@@ -385,6 +229,246 @@ type FallbackSettings = {
|
|
|
385
229
|
mode?: "strict" | "dev";
|
|
386
230
|
};
|
|
387
231
|
|
|
232
|
+
type ServiceIdRef = number | string;
|
|
233
|
+
type NodeIdRef = string;
|
|
234
|
+
type ServiceFallback = {
|
|
235
|
+
/** Node-scoped fallbacks: prefer these when that node’s primary service fails */
|
|
236
|
+
nodes?: Record<NodeIdRef, ServiceIdRef[]>;
|
|
237
|
+
/** Primary→fallback list used when no node-scoped entry is present */
|
|
238
|
+
global?: Record<ServiceIdRef, ServiceIdRef[]>;
|
|
239
|
+
};
|
|
240
|
+
type FallbackEditorServiceMap = DgpServiceMap;
|
|
241
|
+
type FallbackRegistrationScope = "global" | "node";
|
|
242
|
+
type FallbackScopeRef = {
|
|
243
|
+
scope: "global";
|
|
244
|
+
primary: ServiceIdRef;
|
|
245
|
+
} | {
|
|
246
|
+
scope: "node";
|
|
247
|
+
nodeId: NodeIdRef;
|
|
248
|
+
};
|
|
249
|
+
type FallbackRegistration = {
|
|
250
|
+
scope: FallbackRegistrationScope;
|
|
251
|
+
/**
|
|
252
|
+
* For node scope => node id
|
|
253
|
+
* For global scope => omitted
|
|
254
|
+
*/
|
|
255
|
+
scopeId?: NodeIdRef;
|
|
256
|
+
/**
|
|
257
|
+
* The primary DGP service this registration belongs to.
|
|
258
|
+
* For global scope, this is the global key.
|
|
259
|
+
* For node scope, this is resolved from ServiceProps/snapshot context.
|
|
260
|
+
*/
|
|
261
|
+
primary: ServiceIdRef;
|
|
262
|
+
/** Registered fallback services */
|
|
263
|
+
services: ServiceIdRef[];
|
|
264
|
+
};
|
|
265
|
+
type FallbackCheckReason = "duplicate" | "self_reference" | "unknown_primary" | "unknown_candidate" | "missing_snapshot" | "node_scope_not_supported" | "node_primary_unresolved" | "ambiguous_context" | "invalid_candidate" | "unknown_service" | "no_primary" | "rate_violation" | "constraint_mismatch" | "cycle" | "no_tag_context" | "missing_service_props" | "node_not_found";
|
|
266
|
+
type FallbackCandidateCheck = {
|
|
267
|
+
candidate: ServiceIdRef;
|
|
268
|
+
ok: boolean;
|
|
269
|
+
reasons: FallbackCheckReason[];
|
|
270
|
+
};
|
|
271
|
+
type FallbackCheckResult = {
|
|
272
|
+
context: FallbackScopeRef;
|
|
273
|
+
/**
|
|
274
|
+
* Resolved primary when known.
|
|
275
|
+
* For global scope this should normally equal context.primary.
|
|
276
|
+
*/
|
|
277
|
+
primary?: ServiceIdRef;
|
|
278
|
+
allowed: ServiceIdRef[];
|
|
279
|
+
rejected: FallbackCandidateCheck[];
|
|
280
|
+
warnings: FallbackCheckReason[];
|
|
281
|
+
};
|
|
282
|
+
type FallbackEditorState = {
|
|
283
|
+
original: ServiceFallback;
|
|
284
|
+
current: ServiceFallback;
|
|
285
|
+
changed: boolean;
|
|
286
|
+
};
|
|
287
|
+
type FallbackEditorOptions = {
|
|
288
|
+
/**
|
|
289
|
+
* The editable payload.
|
|
290
|
+
* The editor clones this and never mutates the caller’s object directly.
|
|
291
|
+
*/
|
|
292
|
+
fallbacks?: ServiceFallback;
|
|
293
|
+
/**
|
|
294
|
+
* Optional read-only source used to resolve node→service ownership
|
|
295
|
+
* and validate node-scoped registrations.
|
|
296
|
+
*/
|
|
297
|
+
props?: ServiceProps;
|
|
298
|
+
/**
|
|
299
|
+
* Optional runtime context enhancer.
|
|
300
|
+
* Useful for ambiguous node contexts / diagnostics.
|
|
301
|
+
*/
|
|
302
|
+
snapshot?: OrderSnapshot;
|
|
303
|
+
/**
|
|
304
|
+
* Optional service map used for rate / existence validation.
|
|
305
|
+
*/
|
|
306
|
+
services?: FallbackEditorServiceMap;
|
|
307
|
+
/**
|
|
308
|
+
* Optional fallback policy.
|
|
309
|
+
*/
|
|
310
|
+
settings?: FallbackSettings;
|
|
311
|
+
};
|
|
312
|
+
type FallbackMutationOptions = {
|
|
313
|
+
/**
|
|
314
|
+
* When true, reject candidates failing validation.
|
|
315
|
+
* When false, keep structurally valid values and return warnings.
|
|
316
|
+
*/
|
|
317
|
+
strict?: boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Optional insert position for add/addMany.
|
|
320
|
+
* Omit to append.
|
|
321
|
+
*/
|
|
322
|
+
index?: number;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
type PricingRole = "base" | "utility";
|
|
326
|
+
type FieldType = "custom" | (string & {});
|
|
327
|
+
/** ── Marker types (live inside meta; non-breaking) ───────────────────── */
|
|
328
|
+
type QuantityMark = {
|
|
329
|
+
quantity?: {
|
|
330
|
+
valueBy: "value" | "length" | "eval";
|
|
331
|
+
code?: string;
|
|
332
|
+
multiply?: number;
|
|
333
|
+
clamp?: {
|
|
334
|
+
min?: number;
|
|
335
|
+
max?: number;
|
|
336
|
+
};
|
|
337
|
+
fallback?: number;
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
type UtilityMark = {
|
|
341
|
+
utility?: {
|
|
342
|
+
rate: number;
|
|
343
|
+
mode: "flat" | "per_quantity" | "per_value" | "percent";
|
|
344
|
+
valueBy?: "value" | "length";
|
|
345
|
+
percentBase?: "service_total" | "base_service" | "all";
|
|
346
|
+
label?: string;
|
|
347
|
+
};
|
|
348
|
+
};
|
|
349
|
+
type WithQuantityDefault = {
|
|
350
|
+
quantityDefault?: number;
|
|
351
|
+
};
|
|
352
|
+
/** ---------------- Core schema (as you designed) ---------------- */
|
|
353
|
+
interface BaseFieldUI {
|
|
354
|
+
name?: string;
|
|
355
|
+
label: string;
|
|
356
|
+
required?: boolean;
|
|
357
|
+
/** Host-defined prop names → runtime default values (untyped base) */
|
|
358
|
+
defaults?: Record<string, unknown>;
|
|
359
|
+
}
|
|
360
|
+
type FieldOption = {
|
|
361
|
+
id: string;
|
|
362
|
+
label: string;
|
|
363
|
+
value?: string | number;
|
|
364
|
+
service_id?: number;
|
|
365
|
+
pricing_role?: PricingRole;
|
|
366
|
+
meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
|
|
367
|
+
};
|
|
368
|
+
type Field = BaseFieldUI & {
|
|
369
|
+
id: string;
|
|
370
|
+
type: FieldType;
|
|
371
|
+
bind_id?: string | string[];
|
|
372
|
+
name?: string;
|
|
373
|
+
options?: FieldOption[];
|
|
374
|
+
description?: string;
|
|
375
|
+
component?: string;
|
|
376
|
+
pricing_role?: PricingRole;
|
|
377
|
+
meta?: Record<string, unknown> & QuantityMark & UtilityMark & {
|
|
378
|
+
multi?: boolean;
|
|
379
|
+
};
|
|
380
|
+
} & ({
|
|
381
|
+
button?: false;
|
|
382
|
+
service_id?: undefined;
|
|
383
|
+
} | ({
|
|
384
|
+
button: true;
|
|
385
|
+
service_id?: number;
|
|
386
|
+
} & WithQuantityDefault));
|
|
387
|
+
type ConstraintKey = string;
|
|
388
|
+
type Tag = {
|
|
389
|
+
id: string;
|
|
390
|
+
label: string;
|
|
391
|
+
bind_id?: string;
|
|
392
|
+
service_id?: number;
|
|
393
|
+
includes?: string[];
|
|
394
|
+
excludes?: string[];
|
|
395
|
+
meta?: Record<string, unknown> & WithQuantityDefault;
|
|
396
|
+
/**
|
|
397
|
+
* Which flags are set for this tag. If a flag is not set, it's inherited from the nearest ancestor with a value set.
|
|
398
|
+
*/
|
|
399
|
+
constraints?: Partial<Record<ConstraintKey, boolean>>;
|
|
400
|
+
/** Which ancestor defined the *effective* value for each flag (nearest source). */
|
|
401
|
+
constraints_origin?: Partial<Record<ConstraintKey, string>>;
|
|
402
|
+
/**
|
|
403
|
+
* Present only when a child explicitly set a different value but was overridden
|
|
404
|
+
* by an ancestor during normalisation.
|
|
405
|
+
*/
|
|
406
|
+
constraints_overrides?: Partial<Record<ConstraintKey, {
|
|
407
|
+
from: boolean;
|
|
408
|
+
to: boolean;
|
|
409
|
+
origin: string;
|
|
410
|
+
}>>;
|
|
411
|
+
};
|
|
412
|
+
type ServiceProps = {
|
|
413
|
+
order_for_tags?: Record<string, string[]>;
|
|
414
|
+
filters: Tag[];
|
|
415
|
+
fields: Field[];
|
|
416
|
+
includes_for_buttons?: Record<string, string[]>;
|
|
417
|
+
excludes_for_buttons?: Record<string, string[]>;
|
|
418
|
+
schema_version?: string;
|
|
419
|
+
fallbacks?: ServiceFallback;
|
|
420
|
+
name?: string;
|
|
421
|
+
notices?: ServicePropsNotice[];
|
|
422
|
+
};
|
|
423
|
+
type NoticeType = "public" | "private";
|
|
424
|
+
type NoticeSeverity = "info" | "warning" | "error";
|
|
425
|
+
/**
|
|
426
|
+
* “label” is lightweight + UI-friendly (best, sale, hot, etc).
|
|
427
|
+
* Others remain semantic / governance oriented.
|
|
428
|
+
*/
|
|
429
|
+
type NoticeKind = "label" | "warning" | "deprecation" | "compat" | "migration" | "policy";
|
|
430
|
+
type NoticeTarget = {
|
|
431
|
+
scope: "global";
|
|
432
|
+
} | {
|
|
433
|
+
scope: "node";
|
|
434
|
+
node_kind: "tag" | "field" | "option";
|
|
435
|
+
node_id: string;
|
|
436
|
+
};
|
|
437
|
+
interface ServicePropsNotice {
|
|
438
|
+
id: string;
|
|
439
|
+
type: NoticeType;
|
|
440
|
+
kind: NoticeKind;
|
|
441
|
+
severity: NoticeSeverity;
|
|
442
|
+
target: NoticeTarget;
|
|
443
|
+
title: string;
|
|
444
|
+
description?: string;
|
|
445
|
+
reason?: string;
|
|
446
|
+
marked_at?: string;
|
|
447
|
+
icon?: string;
|
|
448
|
+
color?: string;
|
|
449
|
+
meta?: Record<string, unknown>;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
type NodeKind$1 = "tag" | "field" | "comment" | "option";
|
|
453
|
+
type EdgeKind = "child" | "bind" | "include" | "exclude" | "error" | "anchor";
|
|
454
|
+
type GraphNode = {
|
|
455
|
+
id: string;
|
|
456
|
+
kind: NodeKind$1;
|
|
457
|
+
bind_type?: "bound" | "utility" | null;
|
|
458
|
+
errors?: string[];
|
|
459
|
+
label: string;
|
|
460
|
+
};
|
|
461
|
+
type GraphEdge = {
|
|
462
|
+
from: string;
|
|
463
|
+
to: string;
|
|
464
|
+
kind: EdgeKind;
|
|
465
|
+
meta?: Record<string, unknown>;
|
|
466
|
+
};
|
|
467
|
+
type GraphSnapshot = {
|
|
468
|
+
nodes: GraphNode[];
|
|
469
|
+
edges: GraphEdge[];
|
|
470
|
+
};
|
|
471
|
+
|
|
388
472
|
type NormaliseOptions = {
|
|
389
473
|
/** default pricing role for fields/options when missing */
|
|
390
474
|
defaultPricingRole?: PricingRole;
|
|
@@ -494,6 +578,10 @@ declare function getEligibleFallbacks(params: {
|
|
|
494
578
|
unique?: boolean;
|
|
495
579
|
limit?: number;
|
|
496
580
|
}): ServiceIdRef[];
|
|
581
|
+
declare function getFallbackRegistrationInfo(props: ServiceProps, nodeId: NodeIdRef): {
|
|
582
|
+
primary?: ServiceIdRef;
|
|
583
|
+
tagContexts: string[];
|
|
584
|
+
};
|
|
497
585
|
|
|
498
586
|
type BaseCandidate = {
|
|
499
587
|
kind: "field" | "option";
|
|
@@ -631,6 +719,7 @@ type BuildOrderSelection = {
|
|
|
631
719
|
formValuesByFieldId: Record<string, Scalar | Scalar[]>;
|
|
632
720
|
/** Option selections, keyed by fieldId → optionId[] */
|
|
633
721
|
optionSelectionsByFieldId: Record<string, string[]>;
|
|
722
|
+
selectedKeys?: string[];
|
|
634
723
|
/**
|
|
635
724
|
* Selection visit order for options (optional, improves "first option wins primary" determinism).
|
|
636
725
|
* If omitted, iteration order falls back to Object.entries(optionSelectionsByFieldId).
|
|
@@ -642,4 +731,38 @@ type BuildOrderSelection = {
|
|
|
642
731
|
};
|
|
643
732
|
declare function buildOrderSnapshot(props: ServiceProps, builder: Builder, selection: BuildOrderSelection, services: DgpServiceMap, settings?: BuildOrderSnapshotSettings): OrderSnapshot;
|
|
644
733
|
|
|
645
|
-
|
|
734
|
+
/**
|
|
735
|
+
* Keep the editor contract exactly as discussed:
|
|
736
|
+
* - mutates only ServiceFallback (internal clone)
|
|
737
|
+
* - props are read-only context
|
|
738
|
+
* - get(serviceId) is service-centric
|
|
739
|
+
* - getScope(context) is raw scope access
|
|
740
|
+
*/
|
|
741
|
+
interface FallbackEditor {
|
|
742
|
+
state(): FallbackEditorState;
|
|
743
|
+
value(): ServiceFallback;
|
|
744
|
+
reset(): FallbackEditorState;
|
|
745
|
+
/** Service-centric: all registrations that belong to this primary service */
|
|
746
|
+
get(serviceId: ServiceIdRef): FallbackRegistration[];
|
|
747
|
+
/** Exact/raw scope access */
|
|
748
|
+
getScope(context: FallbackScopeRef): ServiceIdRef[];
|
|
749
|
+
/** Validation preview */
|
|
750
|
+
check(context: FallbackScopeRef, candidates?: ServiceIdRef[]): FallbackCheckResult;
|
|
751
|
+
add(context: FallbackScopeRef, candidate: ServiceIdRef, options?: FallbackMutationOptions): FallbackEditorState;
|
|
752
|
+
addMany(context: FallbackScopeRef, candidates: ServiceIdRef[], options?: FallbackMutationOptions): FallbackEditorState;
|
|
753
|
+
remove(context: FallbackScopeRef, candidate: ServiceIdRef): FallbackEditorState;
|
|
754
|
+
replace(context: FallbackScopeRef, candidates: ServiceIdRef[], options?: FallbackMutationOptions): FallbackEditorState;
|
|
755
|
+
clear(context: FallbackScopeRef): FallbackEditorState;
|
|
756
|
+
/**
|
|
757
|
+
* Optional helper for picker UIs:
|
|
758
|
+
* shows candidates that the core fallback resolver would currently accept.
|
|
759
|
+
*/
|
|
760
|
+
eligible(context: FallbackScopeRef, options?: {
|
|
761
|
+
exclude?: ServiceIdRef[];
|
|
762
|
+
unique?: boolean;
|
|
763
|
+
limit?: number;
|
|
764
|
+
}): ServiceIdRef[];
|
|
765
|
+
}
|
|
766
|
+
declare function createFallbackEditor(options?: FallbackEditorOptions): FallbackEditor;
|
|
767
|
+
|
|
768
|
+
export { type AncestryHit, type AnyNode, type Builder, type BuilderOptions, type FailedFallbackContext, type FallbackEditor, type FieldNode, type NodeIndex, type NodeKind, type NormaliseOptions, type OptionNode, type RateCoherenceDiagnostic, type RelKind, type TagNode, type UnknownNode, type WithAncestry, buildOrderSnapshot, collectFailedFallbacks, createBuilder, createFallbackEditor, createNodeIndex, getEligibleFallbacks, getFallbackRegistrationInfo, normalise, resolveServiceFallback, validate, validateAsync, validateRateCoherenceDeep };
|