@timeax/digital-service-engine 0.0.1

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.
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/schema/index.ts
17
+ var schema_exports = {};
18
+ module.exports = __toCommonJS(schema_exports);
19
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/schema/index.ts"],"sourcesContent":["export * from \"./base\";\r\nexport * from \"./canvas-types\";\r\nexport * from \"./comments\";\r\nexport * from \"./editor\";\r\nexport * from \"./editor.types\";\r\nexport * from \"./graph\";\r\nexport * from \"./order\";\r\nexport * from \"./policies\";\r\nexport * from \"./provider\";\r\nexport * from \"./validation\";\r\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,671 @@
1
+ import { NodeProps } from 'reactflow';
2
+
3
+ type PricingRole = "base" | "utility";
4
+ type FieldType = "custom" | (string & {});
5
+ /** ── Marker types (live inside meta; non-breaking) ───────────────────── */
6
+ type QuantityMark = {
7
+ quantity?: {
8
+ valueBy: "value" | "length" | "eval";
9
+ code?: string;
10
+ multiply?: number;
11
+ clamp?: {
12
+ min?: number;
13
+ max?: number;
14
+ };
15
+ fallback?: number;
16
+ };
17
+ };
18
+ type UtilityMark = {
19
+ utility?: {
20
+ rate: number;
21
+ mode: "flat" | "per_quantity" | "per_value" | "percent";
22
+ valueBy?: "value" | "length";
23
+ percentBase?: "service_total" | "base_service" | "all";
24
+ label?: string;
25
+ };
26
+ };
27
+ type WithQuantityDefault = {
28
+ quantityDefault?: number;
29
+ };
30
+ /** ---------------- Core schema (as you designed) ---------------- */
31
+ interface BaseFieldUI {
32
+ name?: string;
33
+ label: string;
34
+ required?: boolean;
35
+ /** Host-defined prop names → typed UI nodes */
36
+ ui?: Record<string, Ui>;
37
+ /** Host-defined prop names → runtime default values (untyped base) */
38
+ defaults?: Record<string, unknown>;
39
+ }
40
+ type Ui = UiString | UiNumber | UiBoolean | UiAnyOf | UiArray | UiObject;
41
+ /** string */
42
+ interface UiString {
43
+ type: "string";
44
+ enum?: string[];
45
+ minLength?: number;
46
+ maxLength?: number;
47
+ pattern?: string;
48
+ format?: string;
49
+ }
50
+ /** number */
51
+ interface UiNumber {
52
+ type: "number";
53
+ minimum?: number;
54
+ maximum?: number;
55
+ multipleOf?: number;
56
+ }
57
+ /** boolean */
58
+ interface UiBoolean {
59
+ type: "boolean";
60
+ }
61
+ /** enumerated choices */
62
+ interface UiAnyOf {
63
+ type: "anyOf";
64
+ multiple?: boolean;
65
+ items: Array<{
66
+ type: "string" | "number" | "boolean";
67
+ title?: string;
68
+ description?: string;
69
+ value: string | number | boolean;
70
+ }>;
71
+ }
72
+ /** arrays: homogeneous (item) or tuple (items) */
73
+ interface UiArray {
74
+ type: "array";
75
+ item?: Ui;
76
+ items?: Ui[];
77
+ minItems?: number;
78
+ maxItems?: number;
79
+ uniqueItems?: boolean;
80
+ }
81
+ /** objects: nested props */
82
+ interface UiObject {
83
+ type: "object";
84
+ fields: Record<string, Ui>;
85
+ required?: string[];
86
+ order?: string[];
87
+ }
88
+ /** ---------------- Typed defaults helpers ---------------- */
89
+ /**
90
+ * UiValue<U>: given a Ui node U, infer the runtime value type.
91
+ */
92
+ type UiValue<U extends Ui> = U extends {
93
+ type: "string";
94
+ } ? string : U extends {
95
+ type: "number";
96
+ } ? number : U extends {
97
+ type: "boolean";
98
+ } ? boolean : U extends {
99
+ type: "anyOf";
100
+ multiple: true;
101
+ } ? Array<U["items"][number]["value"]> : U extends {
102
+ type: "anyOf";
103
+ } ? U["items"][number]["value"] : U extends {
104
+ type: "array";
105
+ item: infer I extends Ui;
106
+ } ? Array<UiValue<I>> : U extends {
107
+ type: "array";
108
+ items: infer T extends Ui[];
109
+ } ? {
110
+ [K in keyof T]: UiValue<T[K]>;
111
+ } : U extends {
112
+ type: "object";
113
+ fields: infer F extends Record<string, Ui>;
114
+ } ? {
115
+ [K in keyof F]?: UiValue<F[K]>;
116
+ } : unknown;
117
+ /**
118
+ * FieldWithTypedDefaults<T>: same shape as BaseFieldUI, but:
119
+ * - ui is a concrete map T (propName → Ui node)
120
+ * - defaults are auto-typed from T via UiValue
121
+ */
122
+ type FieldWithTypedDefaults<T extends Record<string, Ui>> = Omit<BaseFieldUI, "ui" | "defaults"> & {
123
+ ui: T;
124
+ defaults?: Partial<{
125
+ [K in keyof T]: UiValue<T[K]>;
126
+ }>;
127
+ };
128
+ type FieldOption = {
129
+ id: string;
130
+ label: string;
131
+ value?: string | number;
132
+ service_id?: number;
133
+ pricing_role?: PricingRole;
134
+ meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
135
+ };
136
+ type Field = BaseFieldUI & {
137
+ id: string;
138
+ type: FieldType;
139
+ bind_id?: string | string[];
140
+ name?: string;
141
+ options?: FieldOption[];
142
+ description?: string;
143
+ component?: string;
144
+ pricing_role?: PricingRole;
145
+ meta?: Record<string, unknown> & QuantityMark & UtilityMark & {
146
+ multi?: boolean;
147
+ };
148
+ } & ({
149
+ button?: false;
150
+ service_id?: undefined;
151
+ } | ({
152
+ button: true;
153
+ service_id?: number;
154
+ } & WithQuantityDefault));
155
+ type ConstraintKey = string;
156
+ /**
157
+ * Back-compat alias: older code may still import FlagKey.
158
+ * Keeping this prevents a wave of TS errors while still allowing any string key.
159
+ */
160
+ type FlagKey = ConstraintKey;
161
+ type Tag = {
162
+ id: string;
163
+ label: string;
164
+ bind_id?: string;
165
+ service_id?: number;
166
+ includes?: string[];
167
+ excludes?: string[];
168
+ meta?: Record<string, unknown> & WithQuantityDefault;
169
+ /**
170
+ * Which flags are set for this tag. If a flag is not set, it's inherited from the nearest ancestor with a value set.
171
+ */
172
+ constraints?: Partial<Record<ConstraintKey, boolean>>;
173
+ /** Which ancestor defined the *effective* value for each flag (nearest source). */
174
+ constraints_origin?: Partial<Record<ConstraintKey, string>>;
175
+ /**
176
+ * Present only when a child explicitly set a different value but was overridden
177
+ * by an ancestor during normalisation.
178
+ */
179
+ constraints_overrides?: Partial<Record<ConstraintKey, {
180
+ from: boolean;
181
+ to: boolean;
182
+ origin: string;
183
+ }>>;
184
+ };
185
+ type ServiceProps = {
186
+ order_for_tags?: Record<string, string[]>;
187
+ filters: Tag[];
188
+ fields: Field[];
189
+ includes_for_buttons?: Record<string, string[]>;
190
+ excludes_for_buttons?: Record<string, string[]>;
191
+ schema_version?: string;
192
+ fallbacks?: ServiceFallback;
193
+ };
194
+ type ServiceIdRef = number | string;
195
+ type NodeIdRef = string;
196
+ type ServiceFallback = {
197
+ /** Node-scoped fallbacks: prefer these when that node’s primary service fails */
198
+ nodes?: Record<NodeIdRef, ServiceIdRef[]>;
199
+ /** Primary→fallback list used when no node-scoped entry is present */
200
+ global?: Record<ServiceIdRef, ServiceIdRef[]>;
201
+ };
202
+
203
+ type NodeKind = "tag" | "field" | "comment" | "option";
204
+ type EdgeKind = "child" | "bind" | "include" | "exclude" | "error" | "anchor";
205
+ type GraphNode = {
206
+ id: string;
207
+ kind: NodeKind;
208
+ bind_type?: "bound" | "utility" | null;
209
+ errors?: string[];
210
+ label: string;
211
+ };
212
+ type GraphEdge = {
213
+ from: string;
214
+ to: string;
215
+ kind: EdgeKind;
216
+ meta?: Record<string, unknown>;
217
+ };
218
+ type GraphSnapshot = {
219
+ nodes: GraphNode[];
220
+ edges: GraphEdge[];
221
+ };
222
+ type FlowNode = NodeProps<{
223
+ node: GraphNode;
224
+ [x: string]: any;
225
+ }>;
226
+
227
+ type CommentId = string;
228
+ type ThreadId = string;
229
+ type CommentAnchor = {
230
+ type: "node";
231
+ nodeId: string;
232
+ offset?: {
233
+ dx: number;
234
+ dy: number;
235
+ };
236
+ } | {
237
+ type: "edge";
238
+ edgeId: string;
239
+ t?: number;
240
+ } | {
241
+ type: "free";
242
+ position: {
243
+ x: number;
244
+ y: number;
245
+ };
246
+ };
247
+ type CommentMessage = {
248
+ id: CommentId;
249
+ isMain?: boolean;
250
+ authorId?: string;
251
+ authorName?: string;
252
+ body: string;
253
+ createdAt: number;
254
+ editedAt?: number;
255
+ meta?: Record<string, unknown>;
256
+ };
257
+ type CommentThread = {
258
+ id: ThreadId;
259
+ anchor?: CommentAnchor;
260
+ resolved: boolean;
261
+ createdAt: number;
262
+ updatedAt: number;
263
+ messages: CommentMessage[];
264
+ meta?: Record<string, unknown>;
265
+ _sync?: "pending" | "synced" | "error";
266
+ };
267
+
268
+ type Viewport = {
269
+ x: number;
270
+ y: number;
271
+ zoom: number;
272
+ };
273
+ type NodePos = {
274
+ x: number;
275
+ y: number;
276
+ };
277
+ type NodePositions = Record<string, NodePos>;
278
+ type DraftWire = {
279
+ from: string;
280
+ kind: EdgeKind;
281
+ };
282
+ type CanvasState = {
283
+ graph: GraphSnapshot;
284
+ positions: NodePositions;
285
+ selection: Set<string>;
286
+ highlighted: Set<string>;
287
+ hoverId?: string;
288
+ viewport: Viewport;
289
+ draftWire?: DraftWire;
290
+ version: number;
291
+ };
292
+ type CanvasEvents = {
293
+ "graph:update": GraphSnapshot;
294
+ "state:change": CanvasState;
295
+ "selection:change": {
296
+ ids: string[];
297
+ };
298
+ "viewport:change": Viewport;
299
+ "hover:change": {
300
+ id?: string;
301
+ };
302
+ "wire:preview": {
303
+ from: string;
304
+ to?: string;
305
+ kind: EdgeKind;
306
+ };
307
+ "wire:commit": {
308
+ from: string;
309
+ to: string;
310
+ kind: EdgeKind;
311
+ };
312
+ "wire:cancel": {
313
+ from: string;
314
+ };
315
+ error: {
316
+ message: string;
317
+ code?: string;
318
+ meta?: any;
319
+ };
320
+ "comment:thread:create": {
321
+ thread: CommentThread;
322
+ };
323
+ "comment:thread:update": {
324
+ thread: CommentThread;
325
+ };
326
+ "comment:thread:delete": {
327
+ threadId: string;
328
+ };
329
+ "comment:message:create": {
330
+ threadId: string;
331
+ message: CommentMessage;
332
+ };
333
+ "comment:resolve": {
334
+ thread: CommentThread;
335
+ resolved: boolean;
336
+ };
337
+ "comment:move": {
338
+ thread: CommentThread;
339
+ };
340
+ "comment:select": {
341
+ threadId?: string;
342
+ };
343
+ "edge:change": EdgeKind;
344
+ "comment:sync": {
345
+ op: "create_thread" | "add_message" | "edit_message" | "delete_message" | "move_thread" | "resolve_thread" | "delete_thread";
346
+ threadId: string;
347
+ messageId?: string;
348
+ status: "scheduled" | "retrying" | "succeeded" | "failed" | "cancelled";
349
+ attempt: number;
350
+ nextDelayMs?: number;
351
+ error?: any;
352
+ };
353
+ };
354
+ type NodeView = GraphNode & {
355
+ position?: NodePos;
356
+ };
357
+ type EdgeView = GraphEdge;
358
+ type CanvasOptions = {
359
+ initialViewport?: Partial<Viewport>;
360
+ autoEmitState?: boolean;
361
+ };
362
+
363
+ type CommentNode = {
364
+ id: string;
365
+ text: string;
366
+ status: "open" | "resolved";
367
+ anchor?: {
368
+ kind: "tag" | "field" | "option";
369
+ id: string;
370
+ };
371
+ replies?: Array<{
372
+ id: string;
373
+ text: string;
374
+ created_at: string;
375
+ author?: string;
376
+ }>;
377
+ xy?: {
378
+ x: number;
379
+ y: number;
380
+ };
381
+ meta?: Record<string, unknown>;
382
+ };
383
+ type EdgeRoute = {
384
+ id: string;
385
+ points: Array<{
386
+ x: number;
387
+ y: number;
388
+ }>;
389
+ };
390
+ type LayoutState = {
391
+ canvas: CanvasState;
392
+ edges?: EdgeRoute[];
393
+ };
394
+ type EditorSnapshot = {
395
+ props: ServiceProps;
396
+ layout?: LayoutState;
397
+ comments?: CommentNode[];
398
+ meta?: Record<string, unknown>;
399
+ };
400
+
401
+ type TimeRangeEstimate = {
402
+ min_seconds?: number;
403
+ max_seconds?: number;
404
+ label?: string;
405
+ meta?: Record<string, unknown>;
406
+ };
407
+ type SpeedEstimate = {
408
+ amount?: number;
409
+ per?: "minute" | "hour" | "day" | "week" | "month";
410
+ unit?: string;
411
+ label?: string;
412
+ meta?: Record<string, unknown>;
413
+ };
414
+ type ServiceEstimates = {
415
+ start?: TimeRangeEstimate;
416
+ speed?: SpeedEstimate;
417
+ average?: TimeRangeEstimate;
418
+ meta?: Record<string, unknown>;
419
+ };
420
+ type ServiceFlag = {
421
+ enabled: boolean;
422
+ description: string;
423
+ meta?: Record<string, unknown>;
424
+ };
425
+ type IdType = string | number;
426
+ type ServiceFlags = Record<string, ServiceFlag>;
427
+ type DgpServiceCapability = {
428
+ id: IdType;
429
+ name?: string;
430
+ rate: number;
431
+ min?: number;
432
+ max?: number;
433
+ category?: string;
434
+ flags?: ServiceFlags;
435
+ estimates?: ServiceEstimates;
436
+ meta?: Record<string, unknown>;
437
+ [x: string]: any;
438
+ };
439
+ type DgpServiceMap = Record<string, DgpServiceCapability> & Record<number, DgpServiceCapability>;
440
+
441
+ 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";
442
+ type ValidationError = {
443
+ code: ValidationCode;
444
+ message: string;
445
+ severity: "error" | "warning" | "info";
446
+ nodeId?: string;
447
+ details?: Record<string, unknown> & {
448
+ affectedIds?: string[];
449
+ };
450
+ };
451
+ type ServiceWhereOp = "eq" | "neq" | "in" | "nin" | "exists" | "truthy" | "falsy" | "sw";
452
+ /**
453
+ * Host-extensible service filter clause.
454
+ * `path` should usually be "service.<prop>" or "service.meta.<prop>" etc.
455
+ */
456
+ type ServiceWhereClause = {
457
+ path: string;
458
+ op?: ServiceWhereOp;
459
+ value?: unknown;
460
+ };
461
+ type DynamicRule = {
462
+ id: string;
463
+ label?: string;
464
+ scope: "global" | "visible_group";
465
+ subject: "services";
466
+ /**
467
+ * Package-level filter surface:
468
+ * - role/tag/field are core to the builder schema
469
+ * - where[] allows hosts to filter against extra service properties (handler_id/platform_id/type/key/category_id/etc.)
470
+ */
471
+ filter?: {
472
+ role?: "base" | "utility" | "both";
473
+ tag_id?: string | string[];
474
+ field_id?: string | string[];
475
+ where?: ServiceWhereClause[];
476
+ };
477
+ /**
478
+ * Projection is intentionally open:
479
+ * hosts may project custom service properties.
480
+ */
481
+ projection?: "service.id" | "service.name" | "service.rate" | "service.min" | "service.max" | "service.category" | string;
482
+ op: "all_equal" | "unique" | "no_mix" | "all_true" | "any_true" | "max_count" | "min_count";
483
+ value?: number | boolean;
484
+ severity?: "error" | "warning";
485
+ message?: string;
486
+ };
487
+ type ValidatorOptions = {
488
+ serviceMap?: DgpServiceMap;
489
+ allowUnsafe?: boolean;
490
+ selectedOptionKeys?: string[];
491
+ globalUtilityGuard?: boolean;
492
+ policies?: DynamicRule[];
493
+ fallbackSettings?: FallbackSettings;
494
+ };
495
+ type RatePolicy = {
496
+ kind: "lte_primary";
497
+ } | {
498
+ kind: "within_pct";
499
+ pct: number;
500
+ } | {
501
+ kind: "at_least_pct_lower";
502
+ pct: number;
503
+ };
504
+ type FallbackSettings = {
505
+ /** Require fallbacks to satisfy tag constraints (dripfeed/refill/cancel) when a tag context is known. Default: true */
506
+ requireConstraintFit?: boolean;
507
+ /** Rate rule policy. Default: { kind: 'lte_primary' } i.e. candidate.rate <= primary.rate */
508
+ ratePolicy?: RatePolicy;
509
+ /** When multiple candidates remain, choose first (priority) or cheapest. Default: 'priority' */
510
+ selectionStrategy?: "priority" | "cheapest";
511
+ /** Validation mode: 'strict' → node-scoped violations reported as ValidationError; 'dev' → only collect diagnostics. Default: 'strict' */
512
+ mode?: "strict" | "dev";
513
+ };
514
+
515
+ type Env = "client" | "workspace";
516
+ type SelectionOptions = {
517
+ env?: Env;
518
+ rootTagId?: string;
519
+ /** Resolve service capability from an id (used for `services` array) */
520
+ resolveService?: (id: any) => DgpServiceCapability | undefined;
521
+ };
522
+
523
+ type EditorEvents = {
524
+ "editor:command": {
525
+ name: string;
526
+ payload?: any;
527
+ };
528
+ "editor:change": {
529
+ props: ServiceProps;
530
+ reason: string;
531
+ command?: string;
532
+ };
533
+ "editor:undo": {
534
+ stackSize: number;
535
+ index: number;
536
+ };
537
+ "editor:redo": {
538
+ stackSize: number;
539
+ index: number;
540
+ };
541
+ "editor:error": {
542
+ message: string;
543
+ code?: string;
544
+ meta?: any;
545
+ };
546
+ };
547
+ type Command = {
548
+ name: string;
549
+ do(): void;
550
+ undo(): void;
551
+ };
552
+ type EditorOptions = {
553
+ historyLimit?: number;
554
+ validateAfterEach?: boolean;
555
+ /** Sync existence check; return true if the service exists. */
556
+ serviceExists?: (id: number) => boolean;
557
+ /** Optional local index; used if serviceExists is not provided. */
558
+ serviceMap?: Record<number, unknown>;
559
+ /** Raw policies JSON; will be compiled on demand by filterServicesForVisibleGroup. */
560
+ policiesRaw?: unknown;
561
+ selectionProps?: SelectionOptions;
562
+ };
563
+ type ConnectKind = "bind" | "include" | "exclude";
564
+
565
+ interface ButtonValue {
566
+ id: string;
567
+ value: string | number;
568
+ service_id?: number;
569
+ pricing_role?: "base" | "utility";
570
+ meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
571
+ }
572
+ type Scalar = string | number | boolean | ButtonValue | null;
573
+ type UtilityMode = "flat" | "per_quantity" | "per_value" | "percent";
574
+ type QuantityRule = {
575
+ valueBy: "value" | "length" | "eval";
576
+ code?: string;
577
+ };
578
+ type UtilityLineItem = {
579
+ nodeId: string;
580
+ mode: UtilityMode;
581
+ rate: number;
582
+ inputs: {
583
+ quantity: number;
584
+ value?: Scalar | Scalar[];
585
+ valueBy?: "value" | "length" | "eval";
586
+ evalCodeUsed?: boolean;
587
+ };
588
+ };
589
+ type ServiceFallbacks = {
590
+ nodes?: Record<string, Array<string | number>>;
591
+ global?: Record<string | number, Array<string | number>>;
592
+ };
593
+ type FallbackDiagnostics = {
594
+ scope: "node" | "global";
595
+ nodeId?: string;
596
+ primary: string | number;
597
+ candidate: string | number;
598
+ reasons: Array<"rate_violation" | "constraint_mismatch" | "unknown_service" | "ambiguous_context">;
599
+ };
600
+ type SnapshotContext = {
601
+ /** The single active tag id for this order */
602
+ tag: string;
603
+ /** Effective (post-propagation) constraints on that tag */
604
+ constraints: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
605
+ /**
606
+ * Per-node evaluation context:
607
+ * - For the active tag node itself: the same tag id.
608
+ * - For an option node: parent's field.bind_id must include this tag to be applicable; otherwise null.
609
+ * - For a field node (optional to include later): same rule as option, derived from field.bind_id.
610
+ */
611
+ nodeContexts: Record<string, string | null>;
612
+ /** Client pruning policy used (so server can mirror/compare). */
613
+ policy: {
614
+ ratePolicy: {
615
+ kind: "lte_primary" | "none";
616
+ thresholdPct?: number;
617
+ };
618
+ requireConstraintFit: boolean;
619
+ };
620
+ };
621
+ type OrderSnapshot = {
622
+ version: "1";
623
+ mode: "prod" | "dev";
624
+ builtAt: string;
625
+ selection: {
626
+ tag: string;
627
+ fields: Array<{
628
+ id: string;
629
+ type: string;
630
+ selectedOptions?: string[];
631
+ }>;
632
+ };
633
+ inputs: {
634
+ form: Record<string, Scalar | Scalar[]>;
635
+ selections: Record<string, string[]>;
636
+ };
637
+ quantity: number;
638
+ quantitySource: {
639
+ kind: "field" | "tag" | "option" | "default";
640
+ id?: string;
641
+ rule?: QuantityRule;
642
+ defaultedFromHost?: boolean;
643
+ };
644
+ services: Array<string | number>;
645
+ serviceMap: Record<string, Array<string | number>>;
646
+ fallbacks?: {
647
+ nodes?: Record<string, Array<string | number>>;
648
+ global?: Record<string | number, Array<string | number>>;
649
+ };
650
+ utilities?: UtilityLineItem[];
651
+ warnings?: {
652
+ utility?: Array<{
653
+ nodeId: string;
654
+ reason: string;
655
+ }>;
656
+ fallbacks?: FallbackDiagnostics[];
657
+ };
658
+ meta?: {
659
+ schema_version?: string;
660
+ workspaceId?: string;
661
+ builder?: {
662
+ commit?: string;
663
+ };
664
+ context?: SnapshotContext;
665
+ };
666
+ };
667
+
668
+ /** Exported alias so the schema generator can target an array */
669
+ type AdminPolicies = DynamicRule[];
670
+
671
+ export type { AdminPolicies, BaseFieldUI, ButtonValue, CanvasEvents, CanvasOptions, CanvasState, Command, CommentAnchor, CommentId, CommentMessage, CommentNode, CommentThread, ConnectKind, ConstraintKey, DgpServiceCapability, DgpServiceMap, DraftWire, DynamicRule, EdgeKind, EdgeRoute, EdgeView, EditorEvents, EditorOptions, EditorSnapshot, FallbackDiagnostics, FallbackSettings, Field, FieldOption, FieldType, FieldWithTypedDefaults, FlagKey, FlowNode, GraphEdge, GraphNode, GraphSnapshot, IdType, LayoutState, NodeIdRef, NodeKind, NodePos, NodePositions, NodeView, OrderSnapshot, PricingRole, QuantityMark, QuantityRule, RatePolicy, Scalar, ServiceEstimates, ServiceFallback, ServiceFallbacks, ServiceFlag, ServiceFlags, ServiceIdRef, ServiceProps, ServiceWhereClause, ServiceWhereOp, SnapshotContext, SpeedEstimate, Tag, ThreadId, TimeRangeEstimate, Ui, UiAnyOf, UiArray, UiBoolean, UiNumber, UiObject, UiString, UiValue, UtilityLineItem, UtilityMark, UtilityMode, ValidationCode, ValidationError, ValidatorOptions, Viewport, WithQuantityDefault };