@timeax/digital-service-engine 0.0.3 → 0.0.5
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 +349 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +321 -200
- package/dist/core/index.d.ts +321 -200
- package/dist/core/index.js +347 -0
- package/dist/core/index.js.map +1 -1
- package/dist/react/index.cjs +1914 -2
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +587 -379
- package/dist/react/index.d.ts +587 -379
- package/dist/react/index.js +1898 -1
- package/dist/react/index.js.map +1 -1
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +376 -246
- package/dist/schema/index.d.ts +376 -246
- package/dist/workspace/index.cjs.map +1 -1
- package/dist/workspace/index.d.cts +140 -139
- package/dist/workspace/index.d.ts +140 -139
- package/dist/workspace/index.js.map +1 -1
- package/package.json +2 -2
package/dist/schema/index.d.ts
CHANGED
|
@@ -1,5 +1,380 @@
|
|
|
1
1
|
import { NodeProps } from 'reactflow';
|
|
2
2
|
|
|
3
|
+
interface ButtonValue {
|
|
4
|
+
id: string;
|
|
5
|
+
value: string | number;
|
|
6
|
+
service_id?: number;
|
|
7
|
+
pricing_role?: "base" | "utility";
|
|
8
|
+
meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
|
|
9
|
+
}
|
|
10
|
+
type Scalar = string | number | boolean | ButtonValue | null;
|
|
11
|
+
type UtilityMode = "flat" | "per_quantity" | "per_value" | "percent";
|
|
12
|
+
type QuantityRule = {
|
|
13
|
+
valueBy: "value" | "length" | "eval";
|
|
14
|
+
code?: string;
|
|
15
|
+
};
|
|
16
|
+
type UtilityLineItem = {
|
|
17
|
+
nodeId: string;
|
|
18
|
+
mode: UtilityMode;
|
|
19
|
+
rate: number;
|
|
20
|
+
inputs: {
|
|
21
|
+
quantity: number;
|
|
22
|
+
value?: Scalar | Scalar[];
|
|
23
|
+
valueBy?: "value" | "length" | "eval";
|
|
24
|
+
evalCodeUsed?: boolean;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
type ServiceFallbacks = ServiceFallback;
|
|
28
|
+
type FallbackDiagnostics = {
|
|
29
|
+
scope: "node" | "global";
|
|
30
|
+
nodeId?: string;
|
|
31
|
+
primary: string | number;
|
|
32
|
+
candidate: string | number;
|
|
33
|
+
reasons: Array<"rate_violation" | "constraint_mismatch" | "unknown_service" | "ambiguous_context">;
|
|
34
|
+
};
|
|
35
|
+
type SnapshotContext = {
|
|
36
|
+
/** The single active tag id for this order */
|
|
37
|
+
tag: string;
|
|
38
|
+
/** Effective (post-propagation) constraints on that tag */
|
|
39
|
+
constraints: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
|
|
40
|
+
/**
|
|
41
|
+
* Per-node evaluation context:
|
|
42
|
+
* - For the active tag node itself: the same tag id.
|
|
43
|
+
* - For an option node: parent's field.bind_id must include this tag to be applicable; otherwise null.
|
|
44
|
+
* - For a field node (optional to include later): same rule as option, derived from field.bind_id.
|
|
45
|
+
*/
|
|
46
|
+
nodeContexts: Record<string, string | null>;
|
|
47
|
+
/** Client pruning policy used (so server can mirror/compare). */
|
|
48
|
+
policy: {
|
|
49
|
+
ratePolicy: {
|
|
50
|
+
kind: "lte_primary" | "none";
|
|
51
|
+
thresholdPct?: number;
|
|
52
|
+
};
|
|
53
|
+
requireConstraintFit: boolean;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
type OrderSnapshot = {
|
|
57
|
+
version: "1";
|
|
58
|
+
mode: "prod" | "dev";
|
|
59
|
+
builtAt: string;
|
|
60
|
+
selection: {
|
|
61
|
+
tag: string;
|
|
62
|
+
buttons: string[];
|
|
63
|
+
fields: Array<{
|
|
64
|
+
id: string;
|
|
65
|
+
type: string;
|
|
66
|
+
selectedOptions?: string[];
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
inputs: {
|
|
70
|
+
form: Record<string, Scalar | Scalar[]>;
|
|
71
|
+
selections: Record<string, string[]>;
|
|
72
|
+
};
|
|
73
|
+
quantity: number;
|
|
74
|
+
quantitySource: {
|
|
75
|
+
kind: "field" | "tag" | "option" | "default";
|
|
76
|
+
id?: string;
|
|
77
|
+
rule?: QuantityRule;
|
|
78
|
+
defaultedFromHost?: boolean;
|
|
79
|
+
};
|
|
80
|
+
min: number;
|
|
81
|
+
max: number;
|
|
82
|
+
services: Array<string | number>;
|
|
83
|
+
serviceMap: Record<string, Array<string | number>>;
|
|
84
|
+
fallbacks?: ServiceFallbacks;
|
|
85
|
+
utilities?: UtilityLineItem[];
|
|
86
|
+
warnings?: {
|
|
87
|
+
utility?: Array<{
|
|
88
|
+
nodeId: string;
|
|
89
|
+
reason: string;
|
|
90
|
+
}>;
|
|
91
|
+
fallbacks?: FallbackDiagnostics[];
|
|
92
|
+
};
|
|
93
|
+
meta?: {
|
|
94
|
+
schema_version?: string;
|
|
95
|
+
workspaceId?: string;
|
|
96
|
+
builder?: {
|
|
97
|
+
commit?: string;
|
|
98
|
+
};
|
|
99
|
+
context?: SnapshotContext;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
type TimeRangeEstimate = {
|
|
104
|
+
min_seconds?: number;
|
|
105
|
+
max_seconds?: number;
|
|
106
|
+
label?: string;
|
|
107
|
+
meta?: Record<string, unknown>;
|
|
108
|
+
};
|
|
109
|
+
type SpeedEstimate = {
|
|
110
|
+
amount?: number;
|
|
111
|
+
per?: "minute" | "hour" | "day" | "week" | "month";
|
|
112
|
+
unit?: string;
|
|
113
|
+
label?: string;
|
|
114
|
+
meta?: Record<string, unknown>;
|
|
115
|
+
};
|
|
116
|
+
type ServiceEstimates = {
|
|
117
|
+
start?: TimeRangeEstimate;
|
|
118
|
+
speed?: SpeedEstimate;
|
|
119
|
+
average?: TimeRangeEstimate;
|
|
120
|
+
meta?: Record<string, unknown>;
|
|
121
|
+
};
|
|
122
|
+
type ServiceFlag = {
|
|
123
|
+
enabled: boolean;
|
|
124
|
+
description: string;
|
|
125
|
+
meta?: Record<string, unknown>;
|
|
126
|
+
};
|
|
127
|
+
type IdType = string | number;
|
|
128
|
+
type ServiceFlags = Record<string, ServiceFlag>;
|
|
129
|
+
type DgpServiceCapability = {
|
|
130
|
+
id: IdType;
|
|
131
|
+
name?: string;
|
|
132
|
+
rate: number;
|
|
133
|
+
min?: number;
|
|
134
|
+
max?: number;
|
|
135
|
+
category?: string;
|
|
136
|
+
flags?: ServiceFlags;
|
|
137
|
+
estimates?: ServiceEstimates;
|
|
138
|
+
meta?: Record<string, unknown>;
|
|
139
|
+
[x: string]: any;
|
|
140
|
+
};
|
|
141
|
+
type DgpServiceMap = Record<string, DgpServiceCapability> & Record<number, DgpServiceCapability>;
|
|
142
|
+
|
|
143
|
+
type NodeRef = {
|
|
144
|
+
kind: "tag";
|
|
145
|
+
id: string;
|
|
146
|
+
node: Tag;
|
|
147
|
+
} | {
|
|
148
|
+
kind: "field";
|
|
149
|
+
id: string;
|
|
150
|
+
node: Field;
|
|
151
|
+
} | {
|
|
152
|
+
kind: "option";
|
|
153
|
+
id: string;
|
|
154
|
+
node: FieldOption;
|
|
155
|
+
fieldId: string;
|
|
156
|
+
};
|
|
157
|
+
type NodeMap = Map<string, NodeRef>;
|
|
158
|
+
|
|
159
|
+
type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context";
|
|
160
|
+
type ValidationError = {
|
|
161
|
+
code: ValidationCode;
|
|
162
|
+
message: string;
|
|
163
|
+
severity: "error" | "warning" | "info";
|
|
164
|
+
nodeId?: string;
|
|
165
|
+
details?: Record<string, unknown> & {
|
|
166
|
+
affectedIds?: string[];
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
type ServiceWhereOp = "eq" | "neq" | "in" | "nin" | "exists" | "truthy" | "falsy" | "sw";
|
|
170
|
+
/**
|
|
171
|
+
* Host-extensible service filter clause.
|
|
172
|
+
* `path` should usually be "service.<prop>" or "service.meta.<prop>" etc.
|
|
173
|
+
*/
|
|
174
|
+
type ServiceWhereClause = {
|
|
175
|
+
path: string;
|
|
176
|
+
op?: ServiceWhereOp;
|
|
177
|
+
value?: unknown;
|
|
178
|
+
};
|
|
179
|
+
type DynamicRule = {
|
|
180
|
+
id: string;
|
|
181
|
+
label?: string;
|
|
182
|
+
scope: "global" | "visible_group";
|
|
183
|
+
subject: "services";
|
|
184
|
+
/**
|
|
185
|
+
* Package-level filter surface:
|
|
186
|
+
* - role/tag/field are core to the builder schema
|
|
187
|
+
* - where[] allows hosts to filter against extra service properties (handler_id/platform_id/type/key/category_id/etc.)
|
|
188
|
+
*/
|
|
189
|
+
filter?: {
|
|
190
|
+
role?: "base" | "utility" | "both";
|
|
191
|
+
tag_id?: string | string[];
|
|
192
|
+
field_id?: string | string[];
|
|
193
|
+
where?: ServiceWhereClause[];
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Projection is intentionally open:
|
|
197
|
+
* hosts may project custom service properties.
|
|
198
|
+
*/
|
|
199
|
+
projection?: "service.id" | "service.name" | "service.rate" | "service.min" | "service.max" | "service.category" | string;
|
|
200
|
+
op: "all_equal" | "unique" | "no_mix" | "all_true" | "any_true" | "max_count" | "min_count";
|
|
201
|
+
value?: number | boolean;
|
|
202
|
+
severity?: "error" | "warning";
|
|
203
|
+
message?: string;
|
|
204
|
+
};
|
|
205
|
+
type ValidatorOptions = {
|
|
206
|
+
serviceMap?: DgpServiceMap;
|
|
207
|
+
nodeMap?: NodeMap;
|
|
208
|
+
allowUnsafe?: boolean;
|
|
209
|
+
selectedOptionKeys?: string[];
|
|
210
|
+
globalUtilityGuard?: boolean;
|
|
211
|
+
policies?: DynamicRule[];
|
|
212
|
+
fallbackSettings?: FallbackSettings;
|
|
213
|
+
};
|
|
214
|
+
type RatePolicy = {
|
|
215
|
+
kind: "lte_primary";
|
|
216
|
+
} | {
|
|
217
|
+
kind: "within_pct";
|
|
218
|
+
pct: number;
|
|
219
|
+
} | {
|
|
220
|
+
kind: "at_least_pct_lower";
|
|
221
|
+
pct: number;
|
|
222
|
+
};
|
|
223
|
+
type FallbackSettings = {
|
|
224
|
+
/** Require fallbacks to satisfy tag constraints (dripfeed/refill/cancel) when a tag context is known. Default: true */
|
|
225
|
+
requireConstraintFit?: boolean;
|
|
226
|
+
/** Rate rule policy. Default: { kind: 'lte_primary' } i.e. candidate.rate <= primary.rate */
|
|
227
|
+
ratePolicy?: RatePolicy;
|
|
228
|
+
/** When multiple candidates remain, choose first (priority) or cheapest. Default: 'priority' */
|
|
229
|
+
selectionStrategy?: "priority" | "cheapest";
|
|
230
|
+
/** Validation mode: 'strict' → node-scoped violations reported as ValidationError; 'dev' → only collect diagnostics. Default: 'strict' */
|
|
231
|
+
mode?: "strict" | "dev";
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
type ServiceIdRef = number | string;
|
|
235
|
+
type NodeIdRef = string;
|
|
236
|
+
type ServiceFallback = {
|
|
237
|
+
/** Node-scoped fallbacks: prefer these when that node’s primary service fails */
|
|
238
|
+
nodes?: Record<NodeIdRef, ServiceIdRef[]>;
|
|
239
|
+
/** Primary→fallback list used when no node-scoped entry is present */
|
|
240
|
+
global?: Record<ServiceIdRef, ServiceIdRef[]>;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* Optional service-map shape.
|
|
244
|
+
* Keep this loose for now so the editor can be reused by host apps.
|
|
245
|
+
*/
|
|
246
|
+
type FallbackEditorServiceRecord = {
|
|
247
|
+
id: ServiceIdRef;
|
|
248
|
+
rate?: number;
|
|
249
|
+
service_id?: ServiceIdRef;
|
|
250
|
+
[key: string]: unknown;
|
|
251
|
+
};
|
|
252
|
+
type FallbackEditorServiceMap = DgpServiceMap;
|
|
253
|
+
type FallbackRegistrationScope = "global" | "node";
|
|
254
|
+
type FallbackScopeRef = {
|
|
255
|
+
scope: "global";
|
|
256
|
+
primary: ServiceIdRef;
|
|
257
|
+
} | {
|
|
258
|
+
scope: "node";
|
|
259
|
+
nodeId: NodeIdRef;
|
|
260
|
+
};
|
|
261
|
+
type FallbackRegistration = {
|
|
262
|
+
scope: FallbackRegistrationScope;
|
|
263
|
+
/**
|
|
264
|
+
* For node scope => node id
|
|
265
|
+
* For global scope => omitted
|
|
266
|
+
*/
|
|
267
|
+
scopeId?: NodeIdRef;
|
|
268
|
+
/**
|
|
269
|
+
* The primary DGP service this registration belongs to.
|
|
270
|
+
* For global scope, this is the global key.
|
|
271
|
+
* For node scope, this is resolved from ServiceProps/snapshot context.
|
|
272
|
+
*/
|
|
273
|
+
primary: ServiceIdRef;
|
|
274
|
+
/** Registered fallback services */
|
|
275
|
+
services: ServiceIdRef[];
|
|
276
|
+
};
|
|
277
|
+
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";
|
|
278
|
+
type FallbackCandidateCheck = {
|
|
279
|
+
candidate: ServiceIdRef;
|
|
280
|
+
ok: boolean;
|
|
281
|
+
reasons: FallbackCheckReason[];
|
|
282
|
+
};
|
|
283
|
+
type FallbackCheckResult = {
|
|
284
|
+
context: FallbackScopeRef;
|
|
285
|
+
/**
|
|
286
|
+
* Resolved primary when known.
|
|
287
|
+
* For global scope this should normally equal context.primary.
|
|
288
|
+
*/
|
|
289
|
+
primary?: ServiceIdRef;
|
|
290
|
+
allowed: ServiceIdRef[];
|
|
291
|
+
rejected: FallbackCandidateCheck[];
|
|
292
|
+
warnings: FallbackCheckReason[];
|
|
293
|
+
};
|
|
294
|
+
type FallbackEditorState = {
|
|
295
|
+
original: ServiceFallback;
|
|
296
|
+
current: ServiceFallback;
|
|
297
|
+
changed: boolean;
|
|
298
|
+
};
|
|
299
|
+
type FallbackEditorOptions = {
|
|
300
|
+
/**
|
|
301
|
+
* The editable payload.
|
|
302
|
+
* The editor clones this and never mutates the caller’s object directly.
|
|
303
|
+
*/
|
|
304
|
+
fallbacks?: ServiceFallback;
|
|
305
|
+
/**
|
|
306
|
+
* Optional read-only source used to resolve node→service ownership
|
|
307
|
+
* and validate node-scoped registrations.
|
|
308
|
+
*/
|
|
309
|
+
props?: ServiceProps;
|
|
310
|
+
/**
|
|
311
|
+
* Optional runtime context enhancer.
|
|
312
|
+
* Useful for ambiguous node contexts / diagnostics.
|
|
313
|
+
*/
|
|
314
|
+
snapshot?: OrderSnapshot;
|
|
315
|
+
/**
|
|
316
|
+
* Optional service map used for rate / existence validation.
|
|
317
|
+
*/
|
|
318
|
+
services?: FallbackEditorServiceMap;
|
|
319
|
+
/**
|
|
320
|
+
* Optional fallback policy.
|
|
321
|
+
*/
|
|
322
|
+
settings?: FallbackSettings;
|
|
323
|
+
};
|
|
324
|
+
type FallbackMutationOptions = {
|
|
325
|
+
/**
|
|
326
|
+
* When true, reject candidates failing validation.
|
|
327
|
+
* When false, keep structurally valid values and return warnings.
|
|
328
|
+
*/
|
|
329
|
+
strict?: boolean;
|
|
330
|
+
/**
|
|
331
|
+
* Optional insert position for add/addMany.
|
|
332
|
+
* Omit to append.
|
|
333
|
+
*/
|
|
334
|
+
index?: number;
|
|
335
|
+
};
|
|
336
|
+
interface FallbackEditor {
|
|
337
|
+
/** Returns original + current editable state */
|
|
338
|
+
state(): FallbackEditorState;
|
|
339
|
+
/** Returns the current editable fallback payload */
|
|
340
|
+
value(): ServiceFallback;
|
|
341
|
+
/** Restores current back to original */
|
|
342
|
+
reset(): FallbackEditorState;
|
|
343
|
+
/**
|
|
344
|
+
* Returns all registrations belonging to a given primary DGP service.
|
|
345
|
+
*
|
|
346
|
+
* With ServiceProps:
|
|
347
|
+
* - includes global registrations
|
|
348
|
+
* - includes node registrations whose node resolves to this primary
|
|
349
|
+
*
|
|
350
|
+
* Without ServiceProps:
|
|
351
|
+
* - global registrations only
|
|
352
|
+
*/
|
|
353
|
+
get(serviceId: ServiceIdRef): FallbackRegistration[];
|
|
354
|
+
/**
|
|
355
|
+
* Direct/raw scope lookup.
|
|
356
|
+
* - global => current.global[primary] ?? []
|
|
357
|
+
* - node => current.nodes[nodeId] ?? []
|
|
358
|
+
*/
|
|
359
|
+
getScope(context: FallbackScopeRef): ServiceIdRef[];
|
|
360
|
+
/**
|
|
361
|
+
* Pure validation/preview.
|
|
362
|
+
* If candidates omitted, validates the currently stored scope value.
|
|
363
|
+
*/
|
|
364
|
+
check(context: FallbackScopeRef, candidates?: ServiceIdRef[]): FallbackCheckResult;
|
|
365
|
+
/** Adds one candidate to an exact scope */
|
|
366
|
+
add(context: FallbackScopeRef, candidate: ServiceIdRef, options?: FallbackMutationOptions): FallbackEditorState;
|
|
367
|
+
/** Adds many candidates to an exact scope */
|
|
368
|
+
addMany(context: FallbackScopeRef, candidates: ServiceIdRef[], options?: FallbackMutationOptions): FallbackEditorState;
|
|
369
|
+
/** Removes one candidate from an exact scope */
|
|
370
|
+
remove(context: FallbackScopeRef, candidate: ServiceIdRef): FallbackEditorState;
|
|
371
|
+
/** Replaces the exact scope value */
|
|
372
|
+
replace(context: FallbackScopeRef, candidates: ServiceIdRef[], options?: FallbackMutationOptions): FallbackEditorState;
|
|
373
|
+
/** Clears one exact scope value */
|
|
374
|
+
clear(context: FallbackScopeRef): FallbackEditorState;
|
|
375
|
+
}
|
|
376
|
+
declare function createFallbackEditor(options?: FallbackEditorOptions): FallbackEditor;
|
|
377
|
+
|
|
3
378
|
type PricingRole = "base" | "utility";
|
|
4
379
|
type FieldType = "custom" | (string & {});
|
|
5
380
|
/** ── Marker types (live inside meta; non-breaking) ───────────────────── */
|
|
@@ -212,14 +587,6 @@ type ServiceProps = {
|
|
|
212
587
|
name?: string;
|
|
213
588
|
notices?: ServicePropsNotice[];
|
|
214
589
|
};
|
|
215
|
-
type ServiceIdRef = number | string;
|
|
216
|
-
type NodeIdRef = string;
|
|
217
|
-
type ServiceFallback = {
|
|
218
|
-
/** Node-scoped fallbacks: prefer these when that node’s primary service fails */
|
|
219
|
-
nodes?: Record<NodeIdRef, ServiceIdRef[]>;
|
|
220
|
-
/** Primary→fallback list used when no node-scoped entry is present */
|
|
221
|
-
global?: Record<ServiceIdRef, ServiceIdRef[]>;
|
|
222
|
-
};
|
|
223
590
|
type NoticeType = "public" | "private";
|
|
224
591
|
type NoticeSeverity = "info" | "warning" | "error";
|
|
225
592
|
/**
|
|
@@ -447,243 +814,6 @@ type EditorSnapshot = {
|
|
|
447
814
|
meta?: Record<string, unknown>;
|
|
448
815
|
};
|
|
449
816
|
|
|
450
|
-
type TimeRangeEstimate = {
|
|
451
|
-
min_seconds?: number;
|
|
452
|
-
max_seconds?: number;
|
|
453
|
-
label?: string;
|
|
454
|
-
meta?: Record<string, unknown>;
|
|
455
|
-
};
|
|
456
|
-
type SpeedEstimate = {
|
|
457
|
-
amount?: number;
|
|
458
|
-
per?: "minute" | "hour" | "day" | "week" | "month";
|
|
459
|
-
unit?: string;
|
|
460
|
-
label?: string;
|
|
461
|
-
meta?: Record<string, unknown>;
|
|
462
|
-
};
|
|
463
|
-
type ServiceEstimates = {
|
|
464
|
-
start?: TimeRangeEstimate;
|
|
465
|
-
speed?: SpeedEstimate;
|
|
466
|
-
average?: TimeRangeEstimate;
|
|
467
|
-
meta?: Record<string, unknown>;
|
|
468
|
-
};
|
|
469
|
-
type ServiceFlag = {
|
|
470
|
-
enabled: boolean;
|
|
471
|
-
description: string;
|
|
472
|
-
meta?: Record<string, unknown>;
|
|
473
|
-
};
|
|
474
|
-
type IdType = string | number;
|
|
475
|
-
type ServiceFlags = Record<string, ServiceFlag>;
|
|
476
|
-
type DgpServiceCapability = {
|
|
477
|
-
id: IdType;
|
|
478
|
-
name?: string;
|
|
479
|
-
rate: number;
|
|
480
|
-
min?: number;
|
|
481
|
-
max?: number;
|
|
482
|
-
category?: string;
|
|
483
|
-
flags?: ServiceFlags;
|
|
484
|
-
estimates?: ServiceEstimates;
|
|
485
|
-
meta?: Record<string, unknown>;
|
|
486
|
-
[x: string]: any;
|
|
487
|
-
};
|
|
488
|
-
type DgpServiceMap = Record<string, DgpServiceCapability> & Record<number, DgpServiceCapability>;
|
|
489
|
-
|
|
490
|
-
type NodeRef = {
|
|
491
|
-
kind: "tag";
|
|
492
|
-
id: string;
|
|
493
|
-
node: Tag;
|
|
494
|
-
} | {
|
|
495
|
-
kind: "field";
|
|
496
|
-
id: string;
|
|
497
|
-
node: Field;
|
|
498
|
-
} | {
|
|
499
|
-
kind: "option";
|
|
500
|
-
id: string;
|
|
501
|
-
node: FieldOption;
|
|
502
|
-
fieldId: string;
|
|
503
|
-
};
|
|
504
|
-
type NodeMap = Map<string, NodeRef>;
|
|
505
|
-
|
|
506
|
-
type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context";
|
|
507
|
-
type ValidationError = {
|
|
508
|
-
code: ValidationCode;
|
|
509
|
-
message: string;
|
|
510
|
-
severity: "error" | "warning" | "info";
|
|
511
|
-
nodeId?: string;
|
|
512
|
-
details?: Record<string, unknown> & {
|
|
513
|
-
affectedIds?: string[];
|
|
514
|
-
};
|
|
515
|
-
};
|
|
516
|
-
type ServiceWhereOp = "eq" | "neq" | "in" | "nin" | "exists" | "truthy" | "falsy" | "sw";
|
|
517
|
-
/**
|
|
518
|
-
* Host-extensible service filter clause.
|
|
519
|
-
* `path` should usually be "service.<prop>" or "service.meta.<prop>" etc.
|
|
520
|
-
*/
|
|
521
|
-
type ServiceWhereClause = {
|
|
522
|
-
path: string;
|
|
523
|
-
op?: ServiceWhereOp;
|
|
524
|
-
value?: unknown;
|
|
525
|
-
};
|
|
526
|
-
type DynamicRule = {
|
|
527
|
-
id: string;
|
|
528
|
-
label?: string;
|
|
529
|
-
scope: "global" | "visible_group";
|
|
530
|
-
subject: "services";
|
|
531
|
-
/**
|
|
532
|
-
* Package-level filter surface:
|
|
533
|
-
* - role/tag/field are core to the builder schema
|
|
534
|
-
* - where[] allows hosts to filter against extra service properties (handler_id/platform_id/type/key/category_id/etc.)
|
|
535
|
-
*/
|
|
536
|
-
filter?: {
|
|
537
|
-
role?: "base" | "utility" | "both";
|
|
538
|
-
tag_id?: string | string[];
|
|
539
|
-
field_id?: string | string[];
|
|
540
|
-
where?: ServiceWhereClause[];
|
|
541
|
-
};
|
|
542
|
-
/**
|
|
543
|
-
* Projection is intentionally open:
|
|
544
|
-
* hosts may project custom service properties.
|
|
545
|
-
*/
|
|
546
|
-
projection?: "service.id" | "service.name" | "service.rate" | "service.min" | "service.max" | "service.category" | string;
|
|
547
|
-
op: "all_equal" | "unique" | "no_mix" | "all_true" | "any_true" | "max_count" | "min_count";
|
|
548
|
-
value?: number | boolean;
|
|
549
|
-
severity?: "error" | "warning";
|
|
550
|
-
message?: string;
|
|
551
|
-
};
|
|
552
|
-
type ValidatorOptions = {
|
|
553
|
-
serviceMap?: DgpServiceMap;
|
|
554
|
-
nodeMap?: NodeMap;
|
|
555
|
-
allowUnsafe?: boolean;
|
|
556
|
-
selectedOptionKeys?: string[];
|
|
557
|
-
globalUtilityGuard?: boolean;
|
|
558
|
-
policies?: DynamicRule[];
|
|
559
|
-
fallbackSettings?: FallbackSettings;
|
|
560
|
-
};
|
|
561
|
-
type RatePolicy = {
|
|
562
|
-
kind: "lte_primary";
|
|
563
|
-
} | {
|
|
564
|
-
kind: "within_pct";
|
|
565
|
-
pct: number;
|
|
566
|
-
} | {
|
|
567
|
-
kind: "at_least_pct_lower";
|
|
568
|
-
pct: number;
|
|
569
|
-
};
|
|
570
|
-
type FallbackSettings = {
|
|
571
|
-
/** Require fallbacks to satisfy tag constraints (dripfeed/refill/cancel) when a tag context is known. Default: true */
|
|
572
|
-
requireConstraintFit?: boolean;
|
|
573
|
-
/** Rate rule policy. Default: { kind: 'lte_primary' } i.e. candidate.rate <= primary.rate */
|
|
574
|
-
ratePolicy?: RatePolicy;
|
|
575
|
-
/** When multiple candidates remain, choose first (priority) or cheapest. Default: 'priority' */
|
|
576
|
-
selectionStrategy?: "priority" | "cheapest";
|
|
577
|
-
/** Validation mode: 'strict' → node-scoped violations reported as ValidationError; 'dev' → only collect diagnostics. Default: 'strict' */
|
|
578
|
-
mode?: "strict" | "dev";
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
interface ButtonValue {
|
|
582
|
-
id: string;
|
|
583
|
-
value: string | number;
|
|
584
|
-
service_id?: number;
|
|
585
|
-
pricing_role?: "base" | "utility";
|
|
586
|
-
meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
|
|
587
|
-
}
|
|
588
|
-
type Scalar = string | number | boolean | ButtonValue | null;
|
|
589
|
-
type UtilityMode = "flat" | "per_quantity" | "per_value" | "percent";
|
|
590
|
-
type QuantityRule = {
|
|
591
|
-
valueBy: "value" | "length" | "eval";
|
|
592
|
-
code?: string;
|
|
593
|
-
};
|
|
594
|
-
type UtilityLineItem = {
|
|
595
|
-
nodeId: string;
|
|
596
|
-
mode: UtilityMode;
|
|
597
|
-
rate: number;
|
|
598
|
-
inputs: {
|
|
599
|
-
quantity: number;
|
|
600
|
-
value?: Scalar | Scalar[];
|
|
601
|
-
valueBy?: "value" | "length" | "eval";
|
|
602
|
-
evalCodeUsed?: boolean;
|
|
603
|
-
};
|
|
604
|
-
};
|
|
605
|
-
type ServiceFallbacks = {
|
|
606
|
-
nodes?: Record<string, Array<string | number>>;
|
|
607
|
-
global?: Record<string | number, Array<string | number>>;
|
|
608
|
-
};
|
|
609
|
-
type FallbackDiagnostics = {
|
|
610
|
-
scope: "node" | "global";
|
|
611
|
-
nodeId?: string;
|
|
612
|
-
primary: string | number;
|
|
613
|
-
candidate: string | number;
|
|
614
|
-
reasons: Array<"rate_violation" | "constraint_mismatch" | "unknown_service" | "ambiguous_context">;
|
|
615
|
-
};
|
|
616
|
-
type SnapshotContext = {
|
|
617
|
-
/** The single active tag id for this order */
|
|
618
|
-
tag: string;
|
|
619
|
-
/** Effective (post-propagation) constraints on that tag */
|
|
620
|
-
constraints: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
|
|
621
|
-
/**
|
|
622
|
-
* Per-node evaluation context:
|
|
623
|
-
* - For the active tag node itself: the same tag id.
|
|
624
|
-
* - For an option node: parent's field.bind_id must include this tag to be applicable; otherwise null.
|
|
625
|
-
* - For a field node (optional to include later): same rule as option, derived from field.bind_id.
|
|
626
|
-
*/
|
|
627
|
-
nodeContexts: Record<string, string | null>;
|
|
628
|
-
/** Client pruning policy used (so server can mirror/compare). */
|
|
629
|
-
policy: {
|
|
630
|
-
ratePolicy: {
|
|
631
|
-
kind: "lte_primary" | "none";
|
|
632
|
-
thresholdPct?: number;
|
|
633
|
-
};
|
|
634
|
-
requireConstraintFit: boolean;
|
|
635
|
-
};
|
|
636
|
-
};
|
|
637
|
-
type OrderSnapshot = {
|
|
638
|
-
version: "1";
|
|
639
|
-
mode: "prod" | "dev";
|
|
640
|
-
builtAt: string;
|
|
641
|
-
selection: {
|
|
642
|
-
tag: string;
|
|
643
|
-
buttons: string[];
|
|
644
|
-
fields: Array<{
|
|
645
|
-
id: string;
|
|
646
|
-
type: string;
|
|
647
|
-
selectedOptions?: string[];
|
|
648
|
-
}>;
|
|
649
|
-
};
|
|
650
|
-
inputs: {
|
|
651
|
-
form: Record<string, Scalar | Scalar[]>;
|
|
652
|
-
selections: Record<string, string[]>;
|
|
653
|
-
};
|
|
654
|
-
quantity: number;
|
|
655
|
-
quantitySource: {
|
|
656
|
-
kind: "field" | "tag" | "option" | "default";
|
|
657
|
-
id?: string;
|
|
658
|
-
rule?: QuantityRule;
|
|
659
|
-
defaultedFromHost?: boolean;
|
|
660
|
-
};
|
|
661
|
-
min: number;
|
|
662
|
-
max: number;
|
|
663
|
-
services: Array<string | number>;
|
|
664
|
-
serviceMap: Record<string, Array<string | number>>;
|
|
665
|
-
fallbacks?: {
|
|
666
|
-
nodes?: Record<string, Array<string | number>>;
|
|
667
|
-
global?: Record<string | number, Array<string | number>>;
|
|
668
|
-
};
|
|
669
|
-
utilities?: UtilityLineItem[];
|
|
670
|
-
warnings?: {
|
|
671
|
-
utility?: Array<{
|
|
672
|
-
nodeId: string;
|
|
673
|
-
reason: string;
|
|
674
|
-
}>;
|
|
675
|
-
fallbacks?: FallbackDiagnostics[];
|
|
676
|
-
};
|
|
677
|
-
meta?: {
|
|
678
|
-
schema_version?: string;
|
|
679
|
-
workspaceId?: string;
|
|
680
|
-
builder?: {
|
|
681
|
-
commit?: string;
|
|
682
|
-
};
|
|
683
|
-
context?: SnapshotContext;
|
|
684
|
-
};
|
|
685
|
-
};
|
|
686
|
-
|
|
687
817
|
type Env = "client" | "workspace";
|
|
688
818
|
type SelectionOptions = {
|
|
689
819
|
env?: Env;
|
|
@@ -737,4 +867,4 @@ type ConnectKind = "bind" | "include" | "exclude";
|
|
|
737
867
|
/** Exported alias so the schema generator can target an array */
|
|
738
868
|
type AdminPolicies = DynamicRule[];
|
|
739
869
|
|
|
740
|
-
export type
|
|
870
|
+
export { type AdminPolicies, type BaseFieldUI, type ButtonValue, type CanvasEvents, type CanvasOptions, type CanvasState, type Command, type CommentAnchor, type CommentId, type CommentMessage, type CommentNode, type CommentThread, type ConnectKind, type ConstraintKey, type DgpServiceCapability, type DgpServiceMap, type DraftWire, type DynamicRule, type EdgeKind, type EdgeRoute, type EdgeView, type EditorEvents, type EditorOptions, type EditorSnapshot, type FallbackCandidateCheck, type FallbackCheckReason, type FallbackCheckResult, type FallbackDiagnostics, type FallbackEditor, type FallbackEditorOptions, type FallbackEditorServiceMap, type FallbackEditorServiceRecord, type FallbackEditorState, type FallbackMutationOptions, type FallbackRegistration, type FallbackRegistrationScope, type FallbackScopeRef, type FallbackSettings, type Field, type FieldOption, type FieldType, type FieldWithTypedDefaults, type FlagKey, type FlowNode, type GraphEdge, type GraphNode, type GraphSnapshot, type IdType, type LayoutState, type NodeIdRef, type NodeKind, type NodePos, type NodePositions, type NodeView, type NoticeKind, type NoticeSeverity, type NoticeTarget, type NoticeType, type OrderSnapshot, type PricingRole, type QuantityMark, type QuantityRule, type RatePolicy, type Scalar, type ServiceEstimates, type ServiceFallback, type ServiceFallbacks, type ServiceFlag, type ServiceFlags, type ServiceIdRef, type ServiceProps, type ServicePropsNotice, type ServiceWhereClause, type ServiceWhereOp, type SnapshotContext, type SpeedEstimate, type Tag, type ThreadId, type TimeRangeEstimate, type Ui, type UiAnyOf, type UiArray, type UiBoolean, type UiNumber, type UiObject, type UiString, type UiValue, type UtilityLineItem, type UtilityMark, type UtilityMode, type ValidationCode, type ValidationError, type ValidatorOptions, type Viewport, type WithQuantityDefault, createFallbackEditor };
|