@githolon/dsl 0.102.4 → 0.103.0
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/compile_package.mjs +43 -2
- package/compile_proof.d.mts +47 -0
- package/compile_proof.mjs +343 -0
- package/dart/CHANGELOG.md +7 -0
- package/dart/lib/src/dev_cloud.dart +8 -8
- package/dart/lib/src/nms_generated_runtime.dart +2 -0
- package/dart/lib/src/runner/node-entry.mjs +5504 -1236
- package/dart/lib/src/runner/offline-install.mjs +4578 -528
- package/dart/lib/src/test_harness.dart +206 -152
- package/dart/lib/src/webview_bridge.dart +196 -89
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart/test/acquire_session_credentials_test.dart +4 -3
- package/dart/test/adv_realm_interference_test.dart +7 -6
- package/dart/test/cloud_bound_topology_test.dart +3 -3
- package/dart/test/cluster_births_test.dart +4 -3
- package/dart/test/cluster_device_keyed_acceptance_test.dart +10 -16
- package/dart/test/cluster_local_autosync_test.dart +3 -2
- package/dart/test/cluster_scale_test.dart +3 -2
- package/dart/test/dlq_session_surface_test.dart +7 -6
- package/dart/test/first_app_gauntlet_test.dart +14 -21
- package/dart/test/fixtures/wedge/fake-install.mjs +1 -1
- package/dart/test/four_layer_nested_topology_test.dart +4 -4
- package/dart/test/harness_phase_timeout_test.dart +2 -2
- package/dart/test/local_sync_inert_test.dart +1 -1
- package/dart/test/parent_signer_recovery_test.dart +2 -2
- package/dart/test/sealing_client_test.dart +4 -3
- package/dart/test/session_bound_test.dart +8 -7
- package/dart/test/test_harness_test.dart +13 -12
- package/dart/test/vo_read_typing_test.dart +4 -3
- package/dart/test/watch_after_offer_stall_test.dart +4 -3
- package/dart/test/webview_bridge_test.dart +102 -5
- package/dart_types/CHANGELOG.md +5 -0
- package/dart_types/lib/nomos_types.dart +9 -0
- package/dart_types/lib/src/nomos_ref.dart +20 -0
- package/dart_types/lib/src/optional_ref.dart +85 -0
- package/dart_types/lib/src/sha256_digest.dart +41 -0
- package/dart_types/lib/src/versioned_nomos_ref.dart +81 -0
- package/dart_types/pubspec.yaml +1 -1
- package/dart_types/test/optional_ref_test.dart +44 -0
- package/dart_types/test/sha256_digest_test.dart +18 -0
- package/package.json +9 -5
- package/runtime/generated-application-host.js +5365 -1105
- package/src/aggregate.ts +18 -0
- package/src/application_composition.ts +6 -32
- package/src/attested_core.ts +6 -3
- package/src/birth_meter.ts +1 -0
- package/src/birth_meter_ensure.ts +28 -2
- package/src/births.ts +1 -1
- package/src/build_package.ts +162 -538
- package/src/business_birth.ts +19 -3
- package/src/canonical_json.ts +21 -0
- package/src/check_package_main.ts +76 -35
- package/src/clear_directive.ts +19 -8
- package/src/codegen_dart.ts +305 -22
- package/src/codegen_dart_application.ts +844 -292
- package/src/codegen_dart_client.ts +1084 -407
- package/src/codegen_dart_scenario.ts +12 -12
- package/src/codegen_proof.ts +169 -39
- package/src/codegen_provider_dart.ts +17 -1
- package/src/codegen_ts.ts +298 -106
- package/src/compat_manifest.ts +2 -2
- package/src/compat_package_main.ts +8 -12
- package/src/compile_package_main.ts +1866 -597
- package/src/compose.ts +1 -1
- package/src/directive.ts +208 -15
- package/src/engine_entry.ts +165 -111
- package/src/evolve_preview.ts +43 -81
- package/src/extremum.ts +1 -1
- package/src/fields.ts +183 -4
- package/src/flow_gate.ts +75 -2
- package/src/framework/application_home.ts +2 -0
- package/src/framework/auth_provider_law.ts +2 -2
- package/src/framework/birth_meter.ts +7 -19
- package/src/framework/bootstrap.ts +0 -2
- package/src/framework/business_corrections.ts +9 -5
- package/src/framework/domain_lifecycle.ts +15 -29
- package/src/framework/encryption_scope.ts +2 -1
- package/src/framework/framework_aggregates.ts +2 -0
- package/src/framework/genesis.ts +16 -14
- package/src/framework/home.ts +20 -14
- package/src/framework/owned_custody.ts +9 -3
- package/src/framework/platform_admin.ts +3 -3
- package/src/framework/relations.ts +21 -13
- package/src/framework/signing_identity.ts +45 -40
- package/src/framework/workspace_invariant.ts +245 -0
- package/src/framework/workspaces.ts +23 -29
- package/src/index.ts +36 -16
- package/src/intent.ts +178 -6
- package/src/law_check.ts +32 -11
- package/src/law_graph.ts +2902 -0
- package/src/law_graph_usda.ts +1799 -0
- package/src/law_identity.ts +435 -0
- package/src/law_value_type.ts +230 -0
- package/src/lsp_server.ts +61 -31
- package/src/ops.ts +7 -0
- package/src/package_config.ts +141 -0
- package/src/package_dependencies.ts +108 -0
- package/src/package_dependency_usage.ts +150 -0
- package/src/package_source_imports.ts +71 -0
- package/src/plan_source_slice.ts +335 -0
- package/src/point_guard.ts +192 -0
- package/src/precondition.ts +44 -9
- package/src/read_projection_namespace.ts +1 -1
- package/src/runtime_zod.ts +44 -0
- package/src/secondary_ensure.ts +67 -14
- package/src/shape_compat.ts +1 -1
- package/src/stable_id_identity_bridge.ts +149 -0
- package/src/stable_id_lockfile.ts +278 -0
- package/src/stable_ids.ts +7 -2
- package/src/stable_ids_for_module.ts +348 -0
- package/src/stable_ids_types.ts +1 -1
- package/src/sum.ts +1 -1
- package/src/usd_state.ts +1 -1
- package/src/usda_relationship_integrity.ts +66 -0
- package/src/usda_text.ts +18 -0
- package/src/usdz.ts +78 -0
- package/src/value_object.ts +95 -0
- package/src/wire.ts +19 -0
- package/src/wire_encode.ts +22 -0
- package/src/workspace_sharding.ts +52 -36
- package/src/workspace_sharing.ts +28 -4
- package/src/zod_introspection.ts +1 -1
- package/dart/test/cluster_attested_test.dart +0 -201
- package/src/compile_engine.ts +0 -595
- package/src/manifest.ts +0 -1476
- package/src/read_projection_composition.ts +0 -117
- package/src/read_projection_manifest.ts +0 -115
- package/src/relation_composition.ts +0 -286
- package/src/usd.ts +0 -1967
- package/src/usd_layers.ts +0 -1776
package/src/codegen_dart.ts
CHANGED
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
* generated, so they stay reproducible from the domain definitions.
|
|
30
30
|
*/
|
|
31
31
|
import { z } from "zod";
|
|
32
|
-
import { voMetaOf, collectPayloadValueObjectDescriptors, idOfMetaOf, idOfTargetKindOf, brandedIdMetaOf, NOMOS_UNIT_BRAND } from "./value_object.js";
|
|
32
|
+
import { voMetaOf, collectPayloadValueObjectDescriptors, idOfMetaOf, idOfTargetKindOf, versionedRefOfMetaOf, brandedIdMetaOf, NOMOS_UNIT_BRAND } from "./value_object.js";
|
|
33
33
|
import { recursiveTypeBaseName, zodUnwrapLazy } from "./zod_lazy.js";
|
|
34
34
|
import type { AggregateHandle } from "./aggregate.js";
|
|
35
35
|
import type { WorkspaceInvariantDecl } from "./framework/workspace_invariant.js";
|
|
36
36
|
import type { RelationTypeDecl } from "./relation_schema.js";
|
|
37
|
-
import type
|
|
37
|
+
import { isSha256DigestSchema, type Field, type FieldKind, type ValueObjectDescriptor, type ValueObjectFieldDescriptor } from "./fields.js";
|
|
38
38
|
import { admitsNull, nullMetaOf, nullDocLine } from "./null_meta.js";
|
|
39
39
|
import type { Directive } from "./directive.js";
|
|
40
40
|
import { executeDirectiveToIntent } from "./wire_encode.js";
|
|
@@ -84,6 +84,7 @@ export type ToJsonWrap =
|
|
|
84
84
|
| "voList" // a list of value objects — emit `.map((e) => e.toJson()).toList()`.
|
|
85
85
|
| "wrapped" // a standalone branded-id or unit extension type — emit `.value`.
|
|
86
86
|
| "ref" // an aggregate-specific NomosRef<T> — emit its `.id` wire scalar.
|
|
87
|
+
| "versionedRef" // a publication pin + stable series — emit the atomic address pair.
|
|
87
88
|
| "recipient"; // a framework-created Recipient<User> — emit its private delivery address.
|
|
88
89
|
|
|
89
90
|
export interface PayloadFieldSpec {
|
|
@@ -91,10 +92,20 @@ export interface PayloadFieldSpec {
|
|
|
91
92
|
dartType: string;
|
|
92
93
|
/** Aggregate wire type when this field is a NomosRef<T>. */
|
|
93
94
|
referenceType?: string;
|
|
95
|
+
/** Versioned publication/series metadata for payload decode and framework codegen. */
|
|
96
|
+
versionedRefTarget?: string;
|
|
97
|
+
versionedRefSeries?: string;
|
|
98
|
+
versionedRefCurrentField?: string;
|
|
99
|
+
versionedRefTargetInput?: string;
|
|
100
|
+
versionedRefSeriesInput?: string;
|
|
101
|
+
versionedRefTargetWireType?: string;
|
|
102
|
+
versionedRefSeriesWireType?: string;
|
|
94
103
|
/** for enums: the Dart enum type name + raw values. */
|
|
95
104
|
enumValues?: string[];
|
|
96
105
|
/** how this field serialises into `nmsInternalToPayloadJson()`. */
|
|
97
106
|
toJson: ToJsonWrap;
|
|
107
|
+
/** Wire scalar under a nominal wrapper. Keeps string semantics distinct from numeric units. */
|
|
108
|
+
wrappedScalarKind?: "string" | "number";
|
|
98
109
|
/**
|
|
99
110
|
* Whether the payload field is OPTIONAL (Zod `.optional()`/`.default()`). Optional
|
|
100
111
|
* fields are nullable in Dart and OMITTED from `nmsInternalToPayloadJson()` when null — so the
|
|
@@ -118,6 +129,60 @@ export interface DartBusinessRecordInput {
|
|
|
118
129
|
readonly dartType: string;
|
|
119
130
|
}
|
|
120
131
|
|
|
132
|
+
/**
|
|
133
|
+
* A payload NomosRef whose workspace locator is carried by the sibling field of
|
|
134
|
+
* a declared foreignRef output. The public action accepts the one atomic typed
|
|
135
|
+
* reference; codegen derives both wire fields so tenant code cannot split them.
|
|
136
|
+
*/
|
|
137
|
+
export interface DartForeignReferenceInput {
|
|
138
|
+
readonly idField: string;
|
|
139
|
+
readonly workspaceField: string;
|
|
140
|
+
readonly optional: boolean;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function dartForeignReferenceInputs(
|
|
144
|
+
directive: AnyDirective,
|
|
145
|
+
aggregates: readonly AggregateHandle[],
|
|
146
|
+
): DartForeignReferenceInput[] {
|
|
147
|
+
const specs = introspectPayload(directive.payloadSchema as z.ZodTypeAny, new Map());
|
|
148
|
+
const payloadNames = new Set(specs.map((spec) => spec.name));
|
|
149
|
+
const recordInputIds = new Set((directive.businessRecordInputs ?? []).map((input) => input.field));
|
|
150
|
+
const outputIds = new Set([
|
|
151
|
+
directive.aggregateId,
|
|
152
|
+
...(directive.secondaryOutputs ?? []).map((output) => output.aggregateId),
|
|
153
|
+
]);
|
|
154
|
+
const outputs = aggregates.filter((aggregate) => outputIds.has(aggregate.id));
|
|
155
|
+
|
|
156
|
+
return specs.flatMap((spec) => {
|
|
157
|
+
if (spec.toJson !== "ref" || recordInputIds.has(spec.name)) return [];
|
|
158
|
+
const matches = outputs.flatMap((aggregate) => {
|
|
159
|
+
const field = aggregate.fields[spec.name] as Field | undefined;
|
|
160
|
+
if (
|
|
161
|
+
field?.kind !== "ref" ||
|
|
162
|
+
field.foreignRef === undefined ||
|
|
163
|
+
(spec.referenceType !== undefined && field.foreignRef.targetAggregateId !== spec.referenceType)
|
|
164
|
+
) {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
return [field.foreignRef.workspaceField];
|
|
168
|
+
});
|
|
169
|
+
const workspaceFields = [...new Set(matches)];
|
|
170
|
+
if (workspaceFields.length === 0) return [];
|
|
171
|
+
if (workspaceFields.length > 1) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`${directive.id}: foreign reference payload '${spec.name}' maps to more than one workspace field`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
const workspaceField = workspaceFields[0]!;
|
|
177
|
+
if (!payloadNames.has(workspaceField)) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`${directive.id}: foreign reference payload '${spec.name}' must carry its declared locator '${workspaceField}'`,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
return [{ idField: spec.name, workspaceField, optional: spec.optional }];
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
121
186
|
/**
|
|
122
187
|
* Resolve `.fromRecord(field)` against the directive's target aggregate. The
|
|
123
188
|
* aggregate owns the foreign-reference pairing, so authors name only the
|
|
@@ -378,6 +443,31 @@ function introspectField(
|
|
|
378
443
|
enumDartTypes: Map<string, string>,
|
|
379
444
|
lazyNames?: Map<z.ZodTypeAny, string>,
|
|
380
445
|
): Omit<PayloadFieldSpec, "optional"> {
|
|
446
|
+
const versioned = versionedRefOfMetaOf(zt);
|
|
447
|
+
if (versioned !== undefined) {
|
|
448
|
+
const target = versioned.targetKind === "contract"
|
|
449
|
+
? contractTypeName(versioned.targetAggregateType)
|
|
450
|
+
: concreteClassName(versioned.targetAggregateType);
|
|
451
|
+
const series = versioned.seriesKind === "contract"
|
|
452
|
+
? contractTypeName(versioned.seriesAggregateType)
|
|
453
|
+
: concreteClassName(versioned.seriesAggregateType);
|
|
454
|
+
return {
|
|
455
|
+
name,
|
|
456
|
+
dartType: `VersionedNomosRef<${target}, ${series}>`,
|
|
457
|
+
toJson: "versionedRef",
|
|
458
|
+
versionedRefTarget: target,
|
|
459
|
+
versionedRefSeries: series,
|
|
460
|
+
versionedRefCurrentField: versioned.currentField,
|
|
461
|
+
// The pinned version normally comes from the stable series' compiled
|
|
462
|
+
// current pointer, so it already carries the public contract type.
|
|
463
|
+
versionedRefTargetInput: target,
|
|
464
|
+
versionedRefSeriesInput: versioned.seriesKind === "contract"
|
|
465
|
+
? concreteClassName(versioned.seriesAggregateType)
|
|
466
|
+
: series,
|
|
467
|
+
versionedRefTargetWireType: versioned.targetAggregateType,
|
|
468
|
+
versionedRefSeriesWireType: versioned.seriesAggregateType,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
381
471
|
if (recipientMetaOf(zt) !== undefined) {
|
|
382
472
|
return { name, dartType: "Recipient<User>", toJson: "recipient" };
|
|
383
473
|
}
|
|
@@ -425,10 +515,13 @@ function introspectField(
|
|
|
425
515
|
toJson: "ref",
|
|
426
516
|
};
|
|
427
517
|
}
|
|
518
|
+
if (isSha256DigestSchema(zt)) {
|
|
519
|
+
return { name, dartType: "Sha256Digest", toJson: "wrapped", wrappedScalarKind: "string" };
|
|
520
|
+
}
|
|
428
521
|
// brandedId("SiteId"): a standalone nominal string → the generated extension type.
|
|
429
522
|
const brand = brandedIdMetaOf(zt);
|
|
430
523
|
if (brand !== undefined) {
|
|
431
|
-
return { name, dartType: brand, toJson: "wrapped" };
|
|
524
|
+
return { name, dartType: brand, toJson: "wrapped", wrappedScalarKind: "string" };
|
|
432
525
|
}
|
|
433
526
|
return { name, dartType: "String", toJson: "scalar" };
|
|
434
527
|
}
|
|
@@ -442,7 +535,7 @@ function introspectField(
|
|
|
442
535
|
{
|
|
443
536
|
const unitName = (zt as unknown as Record<symbol, unknown>)[NOMOS_UNIT_BRAND];
|
|
444
537
|
if (typeof unitName === "string") {
|
|
445
|
-
return { name, dartType: unitName, toJson: "wrapped" };
|
|
538
|
+
return { name, dartType: unitName, toJson: "wrapped", wrappedScalarKind: "number" };
|
|
446
539
|
}
|
|
447
540
|
}
|
|
448
541
|
return {
|
|
@@ -531,6 +624,8 @@ interface AggFieldSpec {
|
|
|
531
624
|
wireName: string;
|
|
532
625
|
kind: MaterializedFieldKind;
|
|
533
626
|
dartType: string;
|
|
627
|
+
/** A canonical semantic string wrapper whose wire representation remains String. */
|
|
628
|
+
semanticString?: "sha256";
|
|
534
629
|
enumValues?: string[];
|
|
535
630
|
/** For an own-id string field represented as `NomosRef<TAggregate>`. */
|
|
536
631
|
valueClass?: string;
|
|
@@ -561,6 +656,16 @@ interface AggFieldSpec {
|
|
|
561
656
|
* WORKSPACE id (the locator's `workspace`, dynamic per row). `undefined` for a non-foreignRef field.
|
|
562
657
|
*/
|
|
563
658
|
foreignRefWorkspaceField?: string;
|
|
659
|
+
/** A first-class atomic custody address (`t.nomosRef`). */
|
|
660
|
+
nomosRefTarget?: string;
|
|
661
|
+
/** The target aggregate's domain-qualified wire type. */
|
|
662
|
+
nomosRefAggregateType?: string;
|
|
663
|
+
/** A publication pin + stable series (`t.versionedForeignRef`). */
|
|
664
|
+
versionedRefTarget?: string;
|
|
665
|
+
/** The stable series' generated Dart class. */
|
|
666
|
+
versionedRefSeries?: string;
|
|
667
|
+
/** Compiled field on the series which carries its current publication. */
|
|
668
|
+
versionedRefCurrentField?: string;
|
|
564
669
|
/**
|
|
565
670
|
* Whether the field is OPTIONAL on a folded aggregate — derived from the DSL field
|
|
566
671
|
* schema (GAP 1). A `set`/`map` is a COLLECTION: it is ALWAYS empty-defaultable
|
|
@@ -737,6 +842,9 @@ function readKeyParamSpec(
|
|
|
737
842
|
if (fieldSpec.kind === "int") {
|
|
738
843
|
return { dartType: "int", valueExpr: paramName };
|
|
739
844
|
}
|
|
845
|
+
if (fieldSpec.semanticString === "sha256") {
|
|
846
|
+
return { dartType: "Sha256Digest", valueExpr: `${paramName}.value` };
|
|
847
|
+
}
|
|
740
848
|
return { dartType: "String", valueExpr: paramName };
|
|
741
849
|
}
|
|
742
850
|
|
|
@@ -845,8 +953,13 @@ function aggFieldSpec(
|
|
|
845
953
|
name,
|
|
846
954
|
wireName,
|
|
847
955
|
kind: field.kind,
|
|
848
|
-
dartType: valueClass === undefined
|
|
956
|
+
dartType: valueClass === undefined
|
|
957
|
+
? isSha256DigestSchema(field.zod as z.ZodTypeAny) ? "Sha256Digest" : "String"
|
|
958
|
+
: `NomosRef<${valueClass}>`,
|
|
849
959
|
optional,
|
|
960
|
+
...(valueClass === undefined && isSha256DigestSchema(field.zod as z.ZodTypeAny)
|
|
961
|
+
? { semanticString: "sha256" as const }
|
|
962
|
+
: {}),
|
|
850
963
|
...(valueClass !== undefined && valueAggregateType !== undefined
|
|
851
964
|
? { valueClass, valueAggregateType }
|
|
852
965
|
: {}),
|
|
@@ -876,6 +989,40 @@ function aggFieldSpec(
|
|
|
876
989
|
...(field.jsonShape !== undefined ? { jsonShape: field.jsonShape } : {}),
|
|
877
990
|
};
|
|
878
991
|
case "ref": {
|
|
992
|
+
if (field.versionedForeignRef !== undefined) {
|
|
993
|
+
const version = field.versionedForeignRef.targetIsContract === true
|
|
994
|
+
? contractTypeName(field.versionedForeignRef.targetAggregateId)
|
|
995
|
+
: refIdClassForAggregate(field.versionedForeignRef.targetAggregateId);
|
|
996
|
+
const series = field.versionedForeignRef.seriesIsContract === true
|
|
997
|
+
? contractTypeName(field.versionedForeignRef.seriesAggregateId)
|
|
998
|
+
: refIdClassForAggregate(field.versionedForeignRef.seriesAggregateId);
|
|
999
|
+
return {
|
|
1000
|
+
name,
|
|
1001
|
+
wireName,
|
|
1002
|
+
kind: field.kind,
|
|
1003
|
+
dartType: `VersionedNomosRef<${version}, ${series}>`,
|
|
1004
|
+
optional,
|
|
1005
|
+
versionedRefTarget: version,
|
|
1006
|
+
versionedRefSeries: series,
|
|
1007
|
+
versionedRefCurrentField: field.versionedForeignRef.currentField,
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
if (field.nomosRef !== undefined) {
|
|
1011
|
+
const target = field.nomosRef.targetIsContract === true
|
|
1012
|
+
? contractTypeName(field.nomosRef.targetAggregateId)
|
|
1013
|
+
: refIdClassForAggregate(field.nomosRef.targetAggregateId);
|
|
1014
|
+
return {
|
|
1015
|
+
name,
|
|
1016
|
+
wireName,
|
|
1017
|
+
kind: field.kind,
|
|
1018
|
+
dartType: `NomosRef<${target}>`,
|
|
1019
|
+
optional,
|
|
1020
|
+
nomosRefTarget: target,
|
|
1021
|
+
nomosRefAggregateType: aggregateWireTypeForAggregate(
|
|
1022
|
+
field.nomosRef.targetAggregateId,
|
|
1023
|
+
),
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
879
1026
|
// A `t.foreignRef` field is a TYPED CROSS-WORKSPACE LOCATOR (not an atomic FK): surface it as
|
|
880
1027
|
// `ForeignRef<Target>` (the shared `nomos_types` runtime type) — the raw stored id + the sibling
|
|
881
1028
|
// workspace field give the app `resolve`/`watch`/`attest` on demand, without cloning the other holon.
|
|
@@ -1708,7 +1855,7 @@ function dartTypeOfVoField(f: ValueObjectFieldDescriptor, voName: string, fieldN
|
|
|
1708
1855
|
case "string":
|
|
1709
1856
|
return f.idOf !== undefined
|
|
1710
1857
|
? `NomosRef<${f.idOfContract === true ? contractTypeName(f.idOf) : concreteClassName(f.idOf)}>`
|
|
1711
|
-
: f.
|
|
1858
|
+
: f.digest === "sha256" ? "Sha256Digest" : f.brand ?? "String";
|
|
1712
1859
|
case "number":
|
|
1713
1860
|
// a UNIT-tagged number is the generated zero-cost extension type; `.int()` is Dart int.
|
|
1714
1861
|
if (f.unit !== undefined) return f.unit;
|
|
@@ -1745,6 +1892,7 @@ function voFromExpr(
|
|
|
1745
1892
|
const target = f.idOfContract === true ? contractTypeName(f.idOf) : concreteClassName(f.idOf);
|
|
1746
1893
|
return `NmsInternalNomosRefs.create<${target}>(workspace: '', type: '${f.idOf}', id: ${expr} as String)`;
|
|
1747
1894
|
}
|
|
1895
|
+
if (f.digest === "sha256") return `Sha256Digest(${expr} as String)`;
|
|
1748
1896
|
return f.brand !== undefined ? `${f.brand}(${expr} as String)` : `${expr} as String`;
|
|
1749
1897
|
case "enum":
|
|
1750
1898
|
// TOLERANT typed decode — an unknown wire value becomes the sentinel case.
|
|
@@ -1777,6 +1925,7 @@ function voToJsonExpr(f: ValueObjectFieldDescriptor, expr: string, depth = 0): s
|
|
|
1777
1925
|
return f.unit !== undefined ? `${expr}.value` : expr;
|
|
1778
1926
|
case "string":
|
|
1779
1927
|
if (f.idOf !== undefined) return `NmsInternalNomosRefs.id(${expr})`;
|
|
1928
|
+
if (f.digest === "sha256") return `${expr}.value`;
|
|
1780
1929
|
return f.brand !== undefined ? `${expr}.value` : expr; // a brandedId extension type → its wire string
|
|
1781
1930
|
case "boolean":
|
|
1782
1931
|
case "literal":
|
|
@@ -2759,6 +2908,26 @@ function foreignRefExpr(s: AggFieldSpec, aggregate: string): string {
|
|
|
2759
2908
|
: build(idReader);
|
|
2760
2909
|
}
|
|
2761
2910
|
|
|
2911
|
+
function atomicNomosRefExpr(s: AggFieldSpec): string {
|
|
2912
|
+
const target = s.nomosRefTarget as string;
|
|
2913
|
+
const raw = `data['${s.wireName}']`;
|
|
2914
|
+
return s.optional
|
|
2915
|
+
? `() { final v = ${raw}; return v == null ? null : NmsInternalNomosRefs.fromJson<${target}>(v); }()`
|
|
2916
|
+
: `NmsInternalNomosRefs.fromJson<${target}>(${raw})`;
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
function versionedNomosRefExpr(s: AggFieldSpec): string {
|
|
2920
|
+
const version = s.versionedRefTarget as string;
|
|
2921
|
+
const series = s.versionedRefSeries as string;
|
|
2922
|
+
const currentField = JSON.stringify(s.versionedRefCurrentField);
|
|
2923
|
+
const build = (value: string): string =>
|
|
2924
|
+
`() { final m = (${value} as Map).cast<String, Object?>(); return NmsInternalVersionedNomosRefs.create<${version}, ${series}>(pinned: NmsInternalNomosRefs.fromJson<${version}>(m['pinned']), series: NmsInternalNomosRefs.fromJson<${series}>(m['series']), currentField: ${currentField}); }()`;
|
|
2925
|
+
const raw = `data['${s.wireName}']`;
|
|
2926
|
+
return s.optional
|
|
2927
|
+
? `() { final v = ${raw}; return v == null ? null : ${build("v")}; }()`
|
|
2928
|
+
: build(raw);
|
|
2929
|
+
}
|
|
2930
|
+
|
|
2762
2931
|
function parseField(s: AggFieldSpec, aggregate: string): string {
|
|
2763
2932
|
// A `.optional()` scalar reads through the `…OrNull` tolerant reader (returns null
|
|
2764
2933
|
// when the flat `data` lacks it — a freshly-folded aggregate need not have folded
|
|
@@ -2767,6 +2936,8 @@ function parseField(s: AggFieldSpec, aggregate: string): string {
|
|
|
2767
2936
|
const opt = s.optional;
|
|
2768
2937
|
switch (s.kind) {
|
|
2769
2938
|
case "ref": {
|
|
2939
|
+
if (s.versionedRefTarget !== undefined) return versionedNomosRefExpr(s);
|
|
2940
|
+
if (s.nomosRefTarget !== undefined) return atomicNomosRefExpr(s);
|
|
2770
2941
|
// A `t.foreignRef` field decodes to the shared `ForeignRef<Target>` locator (raw id + sibling
|
|
2771
2942
|
// workspace field + the target `fromJson`), not a same-workspace NomosRef.
|
|
2772
2943
|
if (s.foreignRefTarget !== undefined) return foreignRefExpr(s, aggregate);
|
|
@@ -2794,9 +2965,17 @@ function parseField(s: AggFieldSpec, aggregate: string): string {
|
|
|
2794
2965
|
? `() { final v = ${reader}; return v == null ? null : NmsInternalNomosRefs.create<${s.valueClass}>(workspace: _location, type: '${s.valueAggregateType}', id: v); }()`
|
|
2795
2966
|
: `NmsInternalNomosRefs.create<${s.valueClass}>(workspace: _location, type: '${s.valueAggregateType}', id: ${reader})`;
|
|
2796
2967
|
}
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2968
|
+
{
|
|
2969
|
+
const reader = opt
|
|
2970
|
+
? `readStrOrNull(data, '${s.wireName}')`
|
|
2971
|
+
: `readStr(data, '${aggregate}', '${s.wireName}')`;
|
|
2972
|
+
if (s.semanticString === "sha256") {
|
|
2973
|
+
return opt
|
|
2974
|
+
? `() { final v = ${reader}; return v == null ? null : Sha256Digest(v); }()`
|
|
2975
|
+
: `Sha256Digest(${reader})`;
|
|
2976
|
+
}
|
|
2977
|
+
return reader;
|
|
2978
|
+
}
|
|
2800
2979
|
case "json":
|
|
2801
2980
|
// A NAMED VALUE OBJECT reads the projection's decoded object and wraps it in its
|
|
2802
2981
|
// generated class (the EvidenceRef pattern). A plain `json`-kind field is typed
|
|
@@ -2855,6 +3034,15 @@ function parseField(s: AggFieldSpec, aggregate: string): string {
|
|
|
2855
3034
|
function slotDecodeCallback(s: AggFieldSpec, mode: "aggregate" | "readModel"): string {
|
|
2856
3035
|
switch (s.kind) {
|
|
2857
3036
|
case "ref":
|
|
3037
|
+
if (s.versionedRefTarget !== undefined) {
|
|
3038
|
+
const version = s.versionedRefTarget;
|
|
3039
|
+
const series = s.versionedRefSeries as string;
|
|
3040
|
+
const currentField = JSON.stringify(s.versionedRefCurrentField);
|
|
3041
|
+
return `(v) { final m = (v as Map).cast<String, Object?>(); return NmsInternalVersionedNomosRefs.create<${version}, ${series}>(pinned: NmsInternalNomosRefs.fromJson<${version}>(m['pinned']), series: NmsInternalNomosRefs.fromJson<${series}>(m['series']), currentField: ${currentField}); }`;
|
|
3042
|
+
}
|
|
3043
|
+
if (s.nomosRefTarget !== undefined) {
|
|
3044
|
+
return `(v) => NmsInternalNomosRefs.fromJson<${s.nomosRefTarget}>(v)`;
|
|
3045
|
+
}
|
|
2858
3046
|
// A null-admitting `t.foreignRef` (exotic): the sibling workspace field is not reachable from this
|
|
2859
3047
|
// single leaf, so the locator carries the raw id with an empty workspace (resolves to not-found until
|
|
2860
3048
|
// read through the normal field path). A plain ref keeps its typed-id decode.
|
|
@@ -2867,8 +3055,11 @@ function slotDecodeCallback(s: AggFieldSpec, mode: "aggregate" | "readModel"): s
|
|
|
2867
3055
|
: `(v) => v as String`;
|
|
2868
3056
|
case "position":
|
|
2869
3057
|
case "string":
|
|
2870
|
-
|
|
2871
|
-
|
|
3058
|
+
if (s.valueClass !== undefined) {
|
|
3059
|
+
return `(v) => NmsInternalNomosRefs.create<${s.valueClass}>(workspace: _location, type: '${s.valueAggregateType}', id: v as String)`;
|
|
3060
|
+
}
|
|
3061
|
+
return s.semanticString === "sha256"
|
|
3062
|
+
? `(v) => Sha256Digest(v as String)`
|
|
2872
3063
|
: `(v) => v as String`;
|
|
2873
3064
|
case "json":
|
|
2874
3065
|
if (s.voClass !== undefined) {
|
|
@@ -2919,6 +3110,7 @@ export function readModelClassName(aggregateType: string): string {
|
|
|
2919
3110
|
function readModelDartType(s: AggFieldSpec): string {
|
|
2920
3111
|
switch (s.kind) {
|
|
2921
3112
|
case "ref":
|
|
3113
|
+
if (s.versionedRefTarget !== undefined || s.nomosRefTarget !== undefined) return s.dartType;
|
|
2922
3114
|
// A `t.foreignRef` field surfaces as the typed cross-workspace `ForeignRef<Target>` locator; a plain
|
|
2923
3115
|
// same-workspace ref stays `NomosRef<Target>` (or a bare String when the target is unknown).
|
|
2924
3116
|
if (s.foreignRefTarget !== undefined) return `ForeignRef<${s.foreignRefTarget}>`;
|
|
@@ -2936,7 +3128,7 @@ function readModelDartType(s: AggFieldSpec): string {
|
|
|
2936
3128
|
// so these labels are unreachable at runtime — present for FieldKind exhaustiveness.
|
|
2937
3129
|
case "position":
|
|
2938
3130
|
case "string":
|
|
2939
|
-
return s.valueClass === undefined ?
|
|
3131
|
+
return s.valueClass === undefined ? s.dartType : `NomosRef<${s.valueClass}>`;
|
|
2940
3132
|
case "counter":
|
|
2941
3133
|
case "int":
|
|
2942
3134
|
return "int";
|
|
@@ -2984,6 +3176,8 @@ function parseReadModelField(s: AggFieldSpec, aggregate: string): string {
|
|
|
2984
3176
|
const opt = s.optional;
|
|
2985
3177
|
switch (s.kind) {
|
|
2986
3178
|
case "ref": {
|
|
3179
|
+
if (s.versionedRefTarget !== undefined) return versionedNomosRefExpr(s);
|
|
3180
|
+
if (s.nomosRefTarget !== undefined) return atomicNomosRefExpr(s);
|
|
2987
3181
|
// A `t.foreignRef` field decodes to the shared `ForeignRef<Target>` locator (same as the aggregate
|
|
2988
3182
|
// class); a plain same-workspace ref stays `NomosRef<Target>`.
|
|
2989
3183
|
if (s.foreignRefTarget !== undefined) return foreignRefExpr(s, aggregate);
|
|
@@ -3005,9 +3199,17 @@ function parseReadModelField(s: AggFieldSpec, aggregate: string): string {
|
|
|
3005
3199
|
? `() { final v = ${reader}; return v == null ? null : NmsInternalNomosRefs.create<${s.valueClass}>(workspace: _location, type: '${s.valueAggregateType}', id: v); }()`
|
|
3006
3200
|
: `NmsInternalNomosRefs.create<${s.valueClass}>(workspace: _location, type: '${s.valueAggregateType}', id: ${reader})`;
|
|
3007
3201
|
}
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3202
|
+
{
|
|
3203
|
+
const reader = opt
|
|
3204
|
+
? `readStrOrNull(data, '${s.wireName}')`
|
|
3205
|
+
: `readStr(data, '${aggregate}', '${s.wireName}')`;
|
|
3206
|
+
if (s.semanticString === "sha256") {
|
|
3207
|
+
return opt
|
|
3208
|
+
? `() { final v = ${reader}; return v == null ? null : Sha256Digest(v); }()`
|
|
3209
|
+
: `Sha256Digest(${reader})`;
|
|
3210
|
+
}
|
|
3211
|
+
return reader;
|
|
3212
|
+
}
|
|
3011
3213
|
case "json":
|
|
3012
3214
|
// An OBJECT-asserted leaf (`t.jsonObject()`, e.g. `location`): the read engine has
|
|
3013
3215
|
// decoded the stored JSON into a structured object — surface it as a STRICT
|
|
@@ -3216,12 +3418,21 @@ function emitDirective(
|
|
|
3216
3418
|
const className = dartActionInputClassName(d);
|
|
3217
3419
|
const specs = introspectPayload(d.payloadSchema as z.ZodTypeAny, enumDartTypes, lazyNames);
|
|
3218
3420
|
const recordInputs = dartBusinessRecordInputs(d, aggregates);
|
|
3421
|
+
const foreignReferenceInputs = dartForeignReferenceInputs(d, aggregates);
|
|
3422
|
+
const foreignReferenceIds = new Set(foreignReferenceInputs.map((input) => input.idField));
|
|
3219
3423
|
const principalField = d.businessPrincipalField;
|
|
3220
3424
|
const derivedFields = new Set([
|
|
3221
3425
|
...recordInputs.flatMap((input) => [input.idField, input.workspaceField]),
|
|
3426
|
+
...foreignReferenceInputs.map((input) => input.workspaceField),
|
|
3222
3427
|
...(principalField === undefined ? [] : [principalField]),
|
|
3223
3428
|
]);
|
|
3224
3429
|
const publicSpecs = specs.filter((spec) => !derivedFields.has(spec.name));
|
|
3430
|
+
// Optional first-class relationships are OPTIONAL on the wire but REQUIRED
|
|
3431
|
+
// choices at the application boundary. A plain nullable constructor argument
|
|
3432
|
+
// makes an accidentally forgotten relationship indistinguishable from a
|
|
3433
|
+
// deliberate omission. The generated sum type keeps those meanings apart.
|
|
3434
|
+
const isOptionalReferenceChoice = (spec: PayloadFieldSpec): boolean =>
|
|
3435
|
+
spec.optional && spec.toJson === "ref";
|
|
3225
3436
|
const internalPayloadArguments = [
|
|
3226
3437
|
...(principalField === undefined ? [] : ["required String nmsInternalPrincipal"]),
|
|
3227
3438
|
...(recordInputs.length === 0
|
|
@@ -3242,6 +3453,8 @@ function emitDirective(
|
|
|
3242
3453
|
.map((s) =>
|
|
3243
3454
|
s.nullAdmits === true
|
|
3244
3455
|
? ` final NomosSlot<${stripNullable(s.dartType)}> ${s.name};`
|
|
3456
|
+
: isOptionalReferenceChoice(s)
|
|
3457
|
+
? ` final NomosOptionalRef<${s.dartType.replace(/^NomosRef<(.*)>$/, "$1")}> ${s.name};`
|
|
3245
3458
|
: ` final ${s.dartType}${s.optional ? "?" : ""} ${s.name};`,
|
|
3246
3459
|
),
|
|
3247
3460
|
...recordInputs.map((input) => ` final ${input.dartType} ${input.argument};`),
|
|
@@ -3253,6 +3466,8 @@ function emitDirective(
|
|
|
3253
3466
|
// an optional field defaults to null; a required field is `required`.
|
|
3254
3467
|
s.nullAdmits === true
|
|
3255
3468
|
? ` this.${s.name} = const NomosSlot.omitted(),`
|
|
3469
|
+
: isOptionalReferenceChoice(s)
|
|
3470
|
+
? ` required this.${s.name},`
|
|
3256
3471
|
: ` ${s.optional ? "" : "required "}this.${s.name},`,
|
|
3257
3472
|
),
|
|
3258
3473
|
...recordInputs.map((input) => ` required this.${input.argument},`),
|
|
@@ -3270,10 +3485,20 @@ function emitDirective(
|
|
|
3270
3485
|
// fields are written only when present (mirrors the engine's Zod: ops are emitted
|
|
3271
3486
|
// only for present fields).
|
|
3272
3487
|
const requiredEntries = specs
|
|
3273
|
-
.filter((s) =>
|
|
3488
|
+
.filter((s) =>
|
|
3489
|
+
!derivedFields.has(s.name) &&
|
|
3490
|
+
!foreignReferenceIds.has(s.name) &&
|
|
3491
|
+
!s.optional &&
|
|
3492
|
+
s.nullAdmits !== true
|
|
3493
|
+
)
|
|
3274
3494
|
.map((s) => ` '${s.name}': ${toJsonExpr(s, s.name)},`);
|
|
3275
3495
|
const optionalLines = specs
|
|
3276
|
-
.filter((s) =>
|
|
3496
|
+
.filter((s) =>
|
|
3497
|
+
!derivedFields.has(s.name) &&
|
|
3498
|
+
s.optional &&
|
|
3499
|
+
s.nullAdmits !== true &&
|
|
3500
|
+
!isOptionalReferenceChoice(s)
|
|
3501
|
+
)
|
|
3277
3502
|
.map(
|
|
3278
3503
|
(s) =>
|
|
3279
3504
|
` if (${s.name} != null) '${s.name}': ${toJsonExpr(s, `${s.name}!`)},`,
|
|
@@ -3284,7 +3509,57 @@ function emitDirective(
|
|
|
3284
3509
|
const slotWriteLines = slotSpecs.map(
|
|
3285
3510
|
(s) => ` ${s.name}.writeTo(data, '${s.name}', (v) => ${toJsonExpr(s, "v")});`,
|
|
3286
3511
|
);
|
|
3287
|
-
const
|
|
3512
|
+
const optionalReferenceSpecs = specs.filter(
|
|
3513
|
+
(s) =>
|
|
3514
|
+
!derivedFields.has(s.name) &&
|
|
3515
|
+
!foreignReferenceIds.has(s.name) &&
|
|
3516
|
+
isOptionalReferenceChoice(s),
|
|
3517
|
+
);
|
|
3518
|
+
const optionalReferenceWriteLines = optionalReferenceSpecs.map(
|
|
3519
|
+
(s) => ` ${s.name}.writeTo(data, '${s.name}', (reference) => NmsInternalNomosRefs.id(reference));`,
|
|
3520
|
+
);
|
|
3521
|
+
const requiredForeignReferenceInputs = foreignReferenceInputs.filter((input) => !input.optional);
|
|
3522
|
+
const requiredWorkspaceSources = new Map<string, DartForeignReferenceInput>();
|
|
3523
|
+
const requiredForeignReferenceEntries = requiredForeignReferenceInputs.flatMap((input) => {
|
|
3524
|
+
const first = requiredWorkspaceSources.get(input.workspaceField);
|
|
3525
|
+
if (first === undefined) requiredWorkspaceSources.set(input.workspaceField, input);
|
|
3526
|
+
return [
|
|
3527
|
+
...(first === undefined
|
|
3528
|
+
? [` '${input.workspaceField}': NmsInternalNomosRefs.workspace(${input.idField}),`]
|
|
3529
|
+
: []),
|
|
3530
|
+
` '${input.idField}': NmsInternalNomosRefs.id(${input.idField}),`,
|
|
3531
|
+
];
|
|
3532
|
+
});
|
|
3533
|
+
const requiredForeignReferenceValidationLines = requiredForeignReferenceInputs.flatMap((input) => {
|
|
3534
|
+
const first = requiredWorkspaceSources.get(input.workspaceField)!;
|
|
3535
|
+
if (first.idField === input.idField) return [];
|
|
3536
|
+
return [
|
|
3537
|
+
` if (NmsInternalNomosRefs.workspace(${input.idField}) != NmsInternalNomosRefs.workspace(${first.idField})) {`,
|
|
3538
|
+
` throw ArgumentError('Foreign references for ${input.workspaceField} must belong to the same workspace.');`,
|
|
3539
|
+
` }`,
|
|
3540
|
+
];
|
|
3541
|
+
});
|
|
3542
|
+
const optionalForeignReferenceWriteLines = foreignReferenceInputs
|
|
3543
|
+
.filter((input) => input.optional)
|
|
3544
|
+
.flatMap((input) => [
|
|
3545
|
+
` ${input.idField}.when(`,
|
|
3546
|
+
` absent: () {},`,
|
|
3547
|
+
` present: (reference) {`,
|
|
3548
|
+
` final workspace = NmsInternalNomosRefs.workspace(reference);`,
|
|
3549
|
+
` final existingWorkspace = data['${input.workspaceField}'];`,
|
|
3550
|
+
` if (existingWorkspace != null && existingWorkspace != workspace) {`,
|
|
3551
|
+
` throw ArgumentError('Foreign references for ${input.workspaceField} must belong to the same workspace.');`,
|
|
3552
|
+
` }`,
|
|
3553
|
+
` data['${input.workspaceField}'] = workspace;`,
|
|
3554
|
+
` data['${input.idField}'] = NmsInternalNomosRefs.id(reference);`,
|
|
3555
|
+
` },`,
|
|
3556
|
+
` );`,
|
|
3557
|
+
]);
|
|
3558
|
+
const hasPostWrites =
|
|
3559
|
+
slotSpecs.length > 0 ||
|
|
3560
|
+
optionalReferenceSpecs.length > 0 ||
|
|
3561
|
+
requiredForeignReferenceValidationLines.length > 0 ||
|
|
3562
|
+
optionalForeignReferenceWriteLines.length > 0;
|
|
3288
3563
|
|
|
3289
3564
|
const docFirst = directiveDoc(d);
|
|
3290
3565
|
|
|
@@ -3302,11 +3577,12 @@ function emitDirective(
|
|
|
3302
3577
|
``,
|
|
3303
3578
|
` /// Nomos implementation seam used only by the generated application package.`,
|
|
3304
3579
|
` /// Tenant code should pass this object to the generated domain application instead.`,
|
|
3305
|
-
...(
|
|
3580
|
+
...(hasPostWrites
|
|
3306
3581
|
? [
|
|
3307
3582
|
` Map<String, Object?> nmsInternalToPayloadJson(${internalPayloadSignature}) {`,
|
|
3308
3583
|
` final data = <String, Object?>{`,
|
|
3309
3584
|
...requiredEntries,
|
|
3585
|
+
...requiredForeignReferenceEntries,
|
|
3310
3586
|
...optionalLines,
|
|
3311
3587
|
...(principalField === undefined ? [] : [` '${principalField}': nmsInternalPrincipal,`]),
|
|
3312
3588
|
...recordInputs.flatMap((input) => [
|
|
@@ -3314,13 +3590,17 @@ function emitDirective(
|
|
|
3314
3590
|
` '${input.idField}': nmsInternalIdOf(${input.argument}),`,
|
|
3315
3591
|
]),
|
|
3316
3592
|
` };`,
|
|
3593
|
+
...requiredForeignReferenceValidationLines,
|
|
3317
3594
|
...slotWriteLines,
|
|
3595
|
+
...optionalReferenceWriteLines,
|
|
3596
|
+
...optionalForeignReferenceWriteLines,
|
|
3318
3597
|
` return data;`,
|
|
3319
3598
|
` }`,
|
|
3320
3599
|
]
|
|
3321
3600
|
: [
|
|
3322
3601
|
` Map<String, Object?> nmsInternalToPayloadJson(${internalPayloadSignature}) => <String, Object?>{`,
|
|
3323
3602
|
...requiredEntries,
|
|
3603
|
+
...requiredForeignReferenceEntries,
|
|
3324
3604
|
...optionalLines,
|
|
3325
3605
|
...(principalField === undefined ? [] : [` '${principalField}': nmsInternalPrincipal,`]),
|
|
3326
3606
|
...recordInputs.flatMap((input) => [
|
|
@@ -3350,6 +3630,8 @@ export function toJsonExpr(spec: PayloadFieldSpec, accessor: string): string {
|
|
|
3350
3630
|
return `${accessor}.value`;
|
|
3351
3631
|
case "ref":
|
|
3352
3632
|
return `NmsInternalNomosRefs.id(${accessor})`;
|
|
3633
|
+
case "versionedRef":
|
|
3634
|
+
return `{'pinned': NmsInternalNomosRefs.toJson(${accessor}.pinned), 'series': NmsInternalNomosRefs.toJson(${accessor}.series)}`;
|
|
3353
3635
|
case "recipient":
|
|
3354
3636
|
return `NmsInternalRecipients.address(${accessor})`;
|
|
3355
3637
|
}
|
|
@@ -3413,6 +3695,7 @@ export function synthesizeRecursivePayloadTypes(
|
|
|
3413
3695
|
}
|
|
3414
3696
|
switch (zodTypeName(zt)) {
|
|
3415
3697
|
case "ZodString": {
|
|
3698
|
+
if (isSha256DigestSchema(zt)) return { type: "string", digest: "sha256" };
|
|
3416
3699
|
const b = brandedIdMetaOf(zt);
|
|
3417
3700
|
if (b !== undefined) return { type: "string", brand: b };
|
|
3418
3701
|
const idAgg = idOfMetaOf(zt);
|
|
@@ -4026,7 +4309,7 @@ function buildProbePayload(
|
|
|
4026
4309
|
zt = zodInnerType(zt);
|
|
4027
4310
|
}
|
|
4028
4311
|
const sentinel = fieldBySentinel.get(name);
|
|
4029
|
-
out[name] = sentinel !== undefined && zodTypeName(zt) === "ZodString"
|
|
4312
|
+
out[name] = sentinel !== undefined && zodTypeName(zt) === "ZodString" && !isSha256DigestSchema(zt)
|
|
4030
4313
|
? sentinel
|
|
4031
4314
|
: sampleFromZod(zt);
|
|
4032
4315
|
}
|
|
@@ -4041,7 +4324,7 @@ function sampleFromZod(zt: z.ZodTypeAny): unknown {
|
|
|
4041
4324
|
}
|
|
4042
4325
|
switch (zodTypeName(t)) {
|
|
4043
4326
|
case "ZodString":
|
|
4044
|
-
return "x";
|
|
4327
|
+
return isSha256DigestSchema(t) ? "0".repeat(64) : "x";
|
|
4045
4328
|
case "ZodNumber":
|
|
4046
4329
|
return 1;
|
|
4047
4330
|
case "ZodBoolean":
|
|
@@ -4506,7 +4789,7 @@ export function generateDartDomain(mod: DomainModule, opts: GenerateDartDomainOp
|
|
|
4506
4789
|
try {
|
|
4507
4790
|
for (const spec of introspectPayload(schema as z.ZodTypeAny, new Map())) {
|
|
4508
4791
|
// A wrapped spec whose brand a VO descriptor already registered is a brandedId, not a unit.
|
|
4509
|
-
if (spec.toJson === "wrapped" &&
|
|
4792
|
+
if (spec.toJson === "wrapped" && spec.wrappedScalarKind === "number") {
|
|
4510
4793
|
unitNames.add(spec.dartType);
|
|
4511
4794
|
}
|
|
4512
4795
|
}
|