@githolon/dsl 0.114.0 → 0.116.2
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/assets/operation-contract.wasm +0 -0
- package/dart/CHANGELOG.md +55 -0
- package/dart/lib/src/application_framework_calls.dart +7 -1
- package/dart/lib/src/console_enrolment.dart +7 -0
- package/dart/lib/src/console_http_io.dart +22 -15
- package/dart/lib/src/dev_cloud.dart +62 -0
- package/dart/lib/src/nms_generated_runtime.dart +1 -0
- package/dart/lib/src/operation_receipts.dart +74 -7
- package/dart/lib/src/reception/dart_reception.dart +26 -6
- package/dart/lib/src/result_usda.dart +64 -27
- package/dart/lib/src/runner/node-entry.mjs +4733 -1534
- package/dart/lib/src/runtime_v2_transport.dart +3 -0
- package/dart/lib/src/sync_status_projection.dart +11 -0
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart/test/console_enrolment_test.dart +47 -0
- package/dart/test/kernel_refused_follow_test.dart +36 -0
- package/dart/test/model_adoption_test.dart +49 -0
- package/dart/test/result_usda_test.dart +67 -0
- package/dart/test/runtime_projections_test.dart +41 -0
- package/dart_types/CHANGELOG.md +30 -0
- package/dart_types/lib/src/approved_model.dart +78 -1
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +528 -2
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +24 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +1897 -112
- package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +98 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +11 -1
- package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +16 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +43 -2
- package/dart_types/lib/src/vo_canonical.dart +185 -0
- package/dart_types/pubspec.lock +1 -1
- package/dart_types/pubspec.yaml +3 -1
- package/dart_types/test/vo_canonical_test.dart +91 -0
- package/package.json +4 -2
- package/src/aggregate.ts +95 -0
- package/src/anonymous_value_interning.ts +205 -0
- package/src/baseline.ts +27 -0
- package/src/baseline_export.ts +432 -0
- package/src/baseline_import.ts +312 -0
- package/src/baseline_usda.ts +185 -0
- package/src/birth_key_rule.ts +472 -0
- package/src/births.ts +207 -24
- package/src/build_package.ts +47 -7
- package/src/build_provenance.ts +10 -0
- package/src/business_birth.ts +50 -4
- package/src/check_package_main.ts +50 -6
- package/src/codegen_call_proto.ts +5 -18
- package/src/codegen_call_usda.ts +6 -3
- package/src/codegen_dart.ts +114 -60
- package/src/codegen_dart_client.ts +52 -6
- package/src/codegen_dart_facade.ts +57 -35
- package/src/codegen_dart_framework_calls.ts +20 -1
- package/src/codegen_proof.ts +5 -2
- package/src/codegen_result_proto.ts +8 -6
- package/src/codegen_result_usda.ts +12 -4
- package/src/codegen_ts.ts +109 -10
- package/src/compatibility_graph.ts +41 -4
- package/src/compatibility_usda.ts +11 -1
- package/src/compile_package_main.ts +222 -52
- package/src/composed_wire_identity.ts +24 -0
- package/src/directive.ts +6 -0
- package/src/domain_requirements.ts +75 -0
- package/src/engine_entry.ts +12 -4
- package/src/engine_javascript.ts +12 -6
- package/src/fields.ts +109 -0
- package/src/identity_usda.ts +80 -103
- package/src/index.ts +35 -1
- package/src/intent.ts +33 -3
- package/src/law_check.ts +34 -0
- package/src/law_graph.ts +142 -1
- package/src/law_graph_usda.ts +27 -144
- package/src/law_layer_prims.ts +174 -0
- package/src/law_unit_selection.ts +45 -0
- package/src/law_units.ts +7 -6
- package/src/law_version.ts +108 -0
- package/src/package_config.ts +44 -0
- package/src/package_dependencies.ts +8 -0
- package/src/point_guard.ts +5 -1
- package/src/release_inspection.ts +6 -4
- package/src/release_publication.ts +6 -5
- package/src/usda_text.ts +78 -3
- package/src/value_identity.ts +355 -0
- package/src/value_object.ts +35 -4
- package/src/wire.ts +2 -0
- package/src/wire_paths.ts +17 -0
- package/src/workspace_routing.ts +1 -1
package/src/codegen_call_usda.ts
CHANGED
|
@@ -200,7 +200,8 @@ export const TS_CALL_USDA_PRELUDE = [
|
|
|
200
200
|
` else if (character === "\\t") out += "\\\\t";`,
|
|
201
201
|
` else if (character === "\\b") out += "\\\\b";`,
|
|
202
202
|
` else if (character === "\\f") out += "\\\\f";`,
|
|
203
|
-
` else if (point < 0x20 ||
|
|
203
|
+
` else if (point < 0x20 || point === 0x7f) out += "\\\\x" + point.toString(16).padStart(2, "0");`,
|
|
204
|
+
` else if (point >= 0xd800 && point <= 0xdfff) throw new TypeError("Nomos USDA strings cannot carry a lone surrogate");`,
|
|
204
205
|
` else out += character;`,
|
|
205
206
|
` }`,
|
|
206
207
|
` return out + "\\\"";`,
|
|
@@ -254,8 +255,10 @@ export const DART_CALL_USDA_PRELUDE = [
|
|
|
254
255
|
` case 0x08: out.write(r'\\b');`,
|
|
255
256
|
` case 0x0c: out.write(r'\\f');`,
|
|
256
257
|
` default:`,
|
|
257
|
-
` if (point < 0x20 ||
|
|
258
|
-
` out.write('\\\\
|
|
258
|
+
` if (point < 0x20 || point == 0x7f) {`,
|
|
259
|
+
` out.write('\\\\x\${point.toRadixString(16).padLeft(2, '0')}');`,
|
|
260
|
+
` } else if (point >= 0xd800 && point <= 0xdfff) {`,
|
|
261
|
+
` throw ArgumentError.value(value, 'value', 'Nomos USDA strings cannot carry a lone surrogate');`,
|
|
259
262
|
` } else {`,
|
|
260
263
|
` out.write(String.fromCharCode(point));`,
|
|
261
264
|
` }`,
|
package/src/codegen_dart.ts
CHANGED
|
@@ -699,6 +699,8 @@ export interface AggFieldSpec {
|
|
|
699
699
|
dartType: string;
|
|
700
700
|
/** A canonical semantic string wrapper whose wire representation remains String. */
|
|
701
701
|
semanticString?: "sha256" | "git-object-id";
|
|
702
|
+
/** A typed id (`t.brandedId(Name)` / `t.uuid()`): the zero-cost extension type wrapping the wire String. */
|
|
703
|
+
brandedId?: string;
|
|
702
704
|
enumValues?: string[];
|
|
703
705
|
/** For an own-id string field represented as `NomosRef<TAggregate>`. */
|
|
704
706
|
valueClass?: string;
|
|
@@ -923,6 +925,9 @@ function readKeyParamSpec(
|
|
|
923
925
|
if (fieldSpec.semanticString === "git-object-id") {
|
|
924
926
|
return { dartType: "GitObjectId", valueExpr: `${paramName}.value` };
|
|
925
927
|
}
|
|
928
|
+
if (fieldSpec.brandedId !== undefined) {
|
|
929
|
+
return { dartType: fieldSpec.brandedId, valueExpr: `${paramName}.value` };
|
|
930
|
+
}
|
|
926
931
|
return { dartType: "String", valueExpr: paramName };
|
|
927
932
|
}
|
|
928
933
|
|
|
@@ -1032,7 +1037,9 @@ function aggFieldSpec(
|
|
|
1032
1037
|
// field schema marked them `.optional()`.
|
|
1033
1038
|
const optional = isCollectionKind(field.kind) ? false : field.isOptional;
|
|
1034
1039
|
switch (field.kind) {
|
|
1035
|
-
case "string":
|
|
1040
|
+
case "string": {
|
|
1041
|
+
// A TYPED ID field (`t.brandedId(Name)` / `t.uuid()`) reads as its extension type, never a String.
|
|
1042
|
+
const brand = valueClass === undefined ? brandedIdMetaOf(field.zod as z.ZodTypeAny) : undefined;
|
|
1036
1043
|
return {
|
|
1037
1044
|
name,
|
|
1038
1045
|
wireName,
|
|
@@ -1042,9 +1049,10 @@ function aggFieldSpec(
|
|
|
1042
1049
|
? "Sha256Digest"
|
|
1043
1050
|
: isGitObjectIdSchema(field.zod as z.ZodTypeAny)
|
|
1044
1051
|
? "GitObjectId"
|
|
1045
|
-
: "String"
|
|
1052
|
+
: brand ?? "String"
|
|
1046
1053
|
: `NomosRef<${valueClass}>`,
|
|
1047
1054
|
optional,
|
|
1055
|
+
...(brand !== undefined ? { brandedId: brand } : {}),
|
|
1048
1056
|
...(valueClass === undefined && isSha256DigestSchema(field.zod as z.ZodTypeAny)
|
|
1049
1057
|
? { semanticString: "sha256" as const }
|
|
1050
1058
|
: {}),
|
|
@@ -1055,6 +1063,7 @@ function aggFieldSpec(
|
|
|
1055
1063
|
? { valueClass, valueAggregateType }
|
|
1056
1064
|
: {}),
|
|
1057
1065
|
};
|
|
1066
|
+
}
|
|
1058
1067
|
case "json":
|
|
1059
1068
|
// A NAMED VALUE OBJECT (`ValueObject.field()`) types as its generated Dart class
|
|
1060
1069
|
// (typed decode via `.fromProjected`, the EvidenceRef pattern). Otherwise
|
|
@@ -2124,54 +2133,16 @@ function voToJsonExpr(f: ValueObjectFieldDescriptor, expr: string, depth = 0): s
|
|
|
2124
2133
|
}
|
|
2125
2134
|
}
|
|
2126
2135
|
|
|
2127
|
-
/**
|
|
2128
|
-
* per file when
|
|
2129
|
-
|
|
2136
|
+
/** File-level helpers for generated VO classes — the copyWith absent-vs-null sentinel, emitted ONCE
|
|
2137
|
+
* per file when a VO class needs it. Value equality is NOT emitted here: every VO's `==` / `hashCode`
|
|
2138
|
+
* call `NmsInternalValueIdentity` (nomos_types), the Dart implementation of the law's
|
|
2139
|
+
* `nomos.vo-canonical.v1` encoding (CAP-853) — one definition across runtimes. */
|
|
2140
|
+
function emitVoHelpers(): string {
|
|
2130
2141
|
return [
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
`/// value; an explicit \`null\` clears it. (Dart cannot distinguish the two otherwise.)`,
|
|
2135
|
-
`const Object _voUnset = Object();`,
|
|
2136
|
-
``,
|
|
2137
|
-
]
|
|
2138
|
-
: []),
|
|
2139
|
-
`/// Deep json equality for generated value-object classes (toJson-based).`,
|
|
2140
|
-
`bool _voJsonEq(Object? a, Object? b) {`,
|
|
2141
|
-
` if (a is Map && b is Map) {`,
|
|
2142
|
-
` if (a.length != b.length) {`,
|
|
2143
|
-
` return false;`,
|
|
2144
|
-
` }`,
|
|
2145
|
-
` for (final k in a.keys) {`,
|
|
2146
|
-
` if (!b.containsKey(k) || !_voJsonEq(a[k], b[k])) {`,
|
|
2147
|
-
` return false;`,
|
|
2148
|
-
` }`,
|
|
2149
|
-
` }`,
|
|
2150
|
-
` return true;`,
|
|
2151
|
-
` }`,
|
|
2152
|
-
` if (a is List && b is List) {`,
|
|
2153
|
-
` if (a.length != b.length) {`,
|
|
2154
|
-
` return false;`,
|
|
2155
|
-
` }`,
|
|
2156
|
-
` for (var i = 0; i < a.length; i++) {`,
|
|
2157
|
-
` if (!_voJsonEq(a[i], b[i])) {`,
|
|
2158
|
-
` return false;`,
|
|
2159
|
-
` }`,
|
|
2160
|
-
` }`,
|
|
2161
|
-
` return true;`,
|
|
2162
|
-
` }`,
|
|
2163
|
-
` return a == b;`,
|
|
2164
|
-
`}`,
|
|
2142
|
+
`/// The copyWith ABSENT-vs-null sentinel: an omitted optional param keeps the current`,
|
|
2143
|
+
`/// value; an explicit \`null\` clears it. (Dart cannot distinguish the two otherwise.)`,
|
|
2144
|
+
`const Object _voUnset = Object();`,
|
|
2165
2145
|
``,
|
|
2166
|
-
`/// Deep json hash for generated value-object classes (toJson-based).`,
|
|
2167
|
-
`int _voJsonHash(Object? v) {`,
|
|
2168
|
-
` if (v is Map) {`,
|
|
2169
|
-
` return Object.hashAllUnordered(`,
|
|
2170
|
-
` v.entries.map((e) => Object.hash(e.key, _voJsonHash(e.value))));`,
|
|
2171
|
-
` }`,
|
|
2172
|
-
` if (v is List) return Object.hashAll(v.map(_voJsonHash));`,
|
|
2173
|
-
` return v.hashCode;`,
|
|
2174
|
-
`}`,
|
|
2175
2146
|
].join("\n");
|
|
2176
2147
|
}
|
|
2177
2148
|
|
|
@@ -2252,9 +2223,9 @@ function emitUnionClasses(d: ValueObjectDescriptor): string {
|
|
|
2252
2223
|
` /// A copy with [value] replaced.`,
|
|
2253
2224
|
` ${cls} copyWith({${arm.ref}? value}) => ${cls}(value ?? this.value);`,
|
|
2254
2225
|
` @override`,
|
|
2255
|
-
` bool operator ==(Object other) => other is ${cls} &&
|
|
2226
|
+
` bool operator ==(Object other) => other is ${cls} && NmsInternalValueIdentity.equals(other.toJson(), toJson());`,
|
|
2256
2227
|
` @override`,
|
|
2257
|
-
` int get hashCode =>
|
|
2228
|
+
` int get hashCode => NmsInternalValueIdentity.hash(toJson());`,
|
|
2258
2229
|
`}`,
|
|
2259
2230
|
].join("\n");
|
|
2260
2231
|
}
|
|
@@ -2304,9 +2275,9 @@ function emitUnionClasses(d: ValueObjectDescriptor): string {
|
|
|
2304
2275
|
``,
|
|
2305
2276
|
...emitCopyWith(cls, fields.map((x) => ({ member: x.member, dartType: dartTypeOfVoField(x.f, cls, x.wireName), optional: x.optional || x.f.nullable === true }))),
|
|
2306
2277
|
` @override`,
|
|
2307
|
-
` bool operator ==(Object other) => other is ${cls} &&
|
|
2278
|
+
` bool operator ==(Object other) => other is ${cls} && NmsInternalValueIdentity.equals(other.toJson(), toJson());`,
|
|
2308
2279
|
` @override`,
|
|
2309
|
-
` int get hashCode =>
|
|
2280
|
+
` int get hashCode => NmsInternalValueIdentity.hash(toJson());`,
|
|
2310
2281
|
`}`,
|
|
2311
2282
|
].join("\n");
|
|
2312
2283
|
});
|
|
@@ -2323,9 +2294,9 @@ function emitUnionClasses(d: ValueObjectDescriptor): string {
|
|
|
2323
2294
|
` @override`,
|
|
2324
2295
|
` Map<String, Object?> toJson() => raw;`,
|
|
2325
2296
|
` @override`,
|
|
2326
|
-
` bool operator ==(Object other) => other is ${d.name}Unknown &&
|
|
2297
|
+
` bool operator ==(Object other) => other is ${d.name}Unknown && NmsInternalValueIdentity.equals(other.raw, raw);`,
|
|
2327
2298
|
` @override`,
|
|
2328
|
-
` int get hashCode =>
|
|
2299
|
+
` int get hashCode => NmsInternalValueIdentity.hash(raw);`,
|
|
2329
2300
|
`}`,
|
|
2330
2301
|
].join("\n");
|
|
2331
2302
|
|
|
@@ -2423,10 +2394,10 @@ function emitValueObjectClass(d: ValueObjectDescriptor): string {
|
|
|
2423
2394
|
``,
|
|
2424
2395
|
` @override`,
|
|
2425
2396
|
` bool operator ==(Object other) =>`,
|
|
2426
|
-
` other is ${d.name} &&
|
|
2397
|
+
` other is ${d.name} && NmsInternalValueIdentity.equals(other.toJson(), toJson());`,
|
|
2427
2398
|
``,
|
|
2428
2399
|
` @override`,
|
|
2429
|
-
` int get hashCode =>
|
|
2400
|
+
` int get hashCode => NmsInternalValueIdentity.hash(toJson());`,
|
|
2430
2401
|
`}`,
|
|
2431
2402
|
].join("\n");
|
|
2432
2403
|
}
|
|
@@ -2489,10 +2460,10 @@ function emitValueObjectClass(d: ValueObjectDescriptor): string {
|
|
|
2489
2460
|
``,
|
|
2490
2461
|
` @override`,
|
|
2491
2462
|
` bool operator ==(Object other) =>`,
|
|
2492
|
-
` other is ${d.name} &&
|
|
2463
|
+
` other is ${d.name} && NmsInternalValueIdentity.equals(other.toJson(), toJson());`,
|
|
2493
2464
|
``,
|
|
2494
2465
|
` @override`,
|
|
2495
|
-
` int get hashCode =>
|
|
2466
|
+
` int get hashCode => NmsInternalValueIdentity.hash(toJson());`,
|
|
2496
2467
|
`}`,
|
|
2497
2468
|
].join("\n");
|
|
2498
2469
|
}
|
|
@@ -3172,6 +3143,11 @@ function parseField(s: AggFieldSpec, aggregate: string): string {
|
|
|
3172
3143
|
? `() { final v = ${reader}; return v == null ? null : GitObjectId(v); }()`
|
|
3173
3144
|
: `GitObjectId(${reader})`;
|
|
3174
3145
|
}
|
|
3146
|
+
if (s.brandedId !== undefined) {
|
|
3147
|
+
return opt
|
|
3148
|
+
? `() { final v = ${reader}; return v == null ? null : ${s.brandedId}(v); }()`
|
|
3149
|
+
: `${s.brandedId}(${reader})`;
|
|
3150
|
+
}
|
|
3175
3151
|
return reader;
|
|
3176
3152
|
}
|
|
3177
3153
|
case "json":
|
|
@@ -3260,7 +3236,9 @@ function slotDecodeCallback(s: AggFieldSpec, mode: "aggregate" | "readModel"): s
|
|
|
3260
3236
|
? `(v) => Sha256Digest(v as String)`
|
|
3261
3237
|
: s.semanticString === "git-object-id"
|
|
3262
3238
|
? `(v) => GitObjectId(v as String)`
|
|
3263
|
-
:
|
|
3239
|
+
: s.brandedId !== undefined
|
|
3240
|
+
? `(v) => ${s.brandedId}(v as String)`
|
|
3241
|
+
: `(v) => v as String`;
|
|
3264
3242
|
case "json":
|
|
3265
3243
|
if (s.voClass !== undefined) {
|
|
3266
3244
|
return `(v) => ${s.voClass}.fromProjected((v as Map).cast<String, Object?>())`;
|
|
@@ -3413,6 +3391,11 @@ function parseReadModelField(s: AggFieldSpec, aggregate: string): string {
|
|
|
3413
3391
|
? `() { final v = ${reader}; return v == null ? null : GitObjectId(v); }()`
|
|
3414
3392
|
: `GitObjectId(${reader})`;
|
|
3415
3393
|
}
|
|
3394
|
+
if (s.brandedId !== undefined) {
|
|
3395
|
+
return opt
|
|
3396
|
+
? `() { final v = ${reader}; return v == null ? null : ${s.brandedId}(v); }()`
|
|
3397
|
+
: `${s.brandedId}(${reader})`;
|
|
3398
|
+
}
|
|
3416
3399
|
return reader;
|
|
3417
3400
|
}
|
|
3418
3401
|
case "json":
|
|
@@ -4993,6 +4976,65 @@ export interface GenerateDartDomainOptions {
|
|
|
4993
4976
|
* because it was present in the composed law.
|
|
4994
4977
|
*/
|
|
4995
4978
|
readonly additionalValueObjects?: readonly ValueObjectDescriptor[];
|
|
4979
|
+
/** Branded-id extension types another file (the package's `nomos_framework.dart`) declares because ≥2
|
|
4980
|
+
* domains use them; this domain references them via {@link frameworkImportUri}. */
|
|
4981
|
+
readonly skipBrandNames?: ReadonlySet<string>;
|
|
4982
|
+
/** Branded-id extension types this file declares for the package (the framework file's shared set). */
|
|
4983
|
+
readonly extraBrandNames?: readonly string[];
|
|
4984
|
+
}
|
|
4985
|
+
|
|
4986
|
+
/**
|
|
4987
|
+
* Every branded-id name (`brandedId(...)`, `t.brandedId(...)`, `t.uuid()`) whose Dart extension type this
|
|
4988
|
+
* domain's generated types reference: typed-id aggregate fields, top-level payload fields of its public
|
|
4989
|
+
* directives (business births render their public payload), and value-object fields. The package counts
|
|
4990
|
+
* these per domain so a brand used by two domains is declared ONCE, in the framework file.
|
|
4991
|
+
*/
|
|
4992
|
+
export function dartBrandNamesForModule(mod: DomainModule): Set<string> {
|
|
4993
|
+
const brands = new Set<string>();
|
|
4994
|
+
const publicAggregates = mod.aggregates.filter(
|
|
4995
|
+
(a) => (a as { businessBirthInternal?: unknown }).businessBirthInternal !== true,
|
|
4996
|
+
);
|
|
4997
|
+
for (const agg of publicAggregates) {
|
|
4998
|
+
for (const f of Object.values(agg.fields as Record<string, Field>)) {
|
|
4999
|
+
if (f.kind !== "string") continue;
|
|
5000
|
+
const b = brandedIdMetaOf(f.zod as z.ZodTypeAny);
|
|
5001
|
+
if (b !== undefined) brands.add(b);
|
|
5002
|
+
}
|
|
5003
|
+
}
|
|
5004
|
+
const directives = (mod.applicationIntents ?? mod.directives)
|
|
5005
|
+
.filter((d) => (d as { businessBirthInternal?: unknown }).businessBirthInternal !== true)
|
|
5006
|
+
.map((d) => {
|
|
5007
|
+
const birth = (d as { businessBirth?: { publicPayloadSchema?: z.ZodTypeAny } }).businessBirth;
|
|
5008
|
+
return birth?.publicPayloadSchema === undefined ? d : { ...d, payloadSchema: birth.publicPayloadSchema };
|
|
5009
|
+
});
|
|
5010
|
+
for (const dir of directives) {
|
|
5011
|
+
const schema = (dir as { payloadSchema?: unknown }).payloadSchema;
|
|
5012
|
+
if (!schema || typeof schema !== "object" || zodTypeName(schema as z.ZodTypeAny) !== "ZodObject") continue;
|
|
5013
|
+
const rawShape = (zodDef(schema as z.ZodTypeAny) as { shape?: Record<string, z.ZodTypeAny> | (() => Record<string, z.ZodTypeAny>) }).shape;
|
|
5014
|
+
const shp = typeof rawShape === "function" ? rawShape() : rawShape ?? {};
|
|
5015
|
+
for (let zt of Object.values(shp)) {
|
|
5016
|
+
for (let hops = 0; hops < 8 && (zodTypeName(zt) === "ZodOptional" || zodTypeName(zt) === "ZodDefault" || zodTypeName(zt) === "ZodArray"); hops++) {
|
|
5017
|
+
zt = zodTypeName(zt) === "ZodArray" ? zodArrayElement(zt) : zodInnerType(zt);
|
|
5018
|
+
}
|
|
5019
|
+
const b = brandedIdMetaOf(zt);
|
|
5020
|
+
if (b !== undefined) brands.add(b);
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
const walk = (f: ValueObjectFieldDescriptor): void => {
|
|
5024
|
+
if (f.type === "string" && f.brand !== undefined && f.idOf === undefined) brands.add(f.brand);
|
|
5025
|
+
else if (f.type === "array") walk(f.items);
|
|
5026
|
+
else if (f.type === "map") walk(f.values);
|
|
5027
|
+
};
|
|
5028
|
+
for (const d of [
|
|
5029
|
+
...collectValueObjectDescriptors(publicAggregates),
|
|
5030
|
+
...collectPayloadValueObjectDescriptors(directives),
|
|
5031
|
+
]) {
|
|
5032
|
+
for (const f of Object.values(d.fields ?? {})) walk(f);
|
|
5033
|
+
for (const arm of Object.values(d.union ?? {})) {
|
|
5034
|
+
if ("fields" in arm) for (const f of Object.values(arm.fields)) walk(f);
|
|
5035
|
+
}
|
|
5036
|
+
}
|
|
5037
|
+
return brands;
|
|
4996
5038
|
}
|
|
4997
5039
|
|
|
4998
5040
|
/** Generate the full Dart source for one domain module. */
|
|
@@ -5098,6 +5140,16 @@ export function generateDartDomain(mod: DomainModule, opts: GenerateDartDomainOp
|
|
|
5098
5140
|
else if (f.type === "array") walkUnitField(f.items);
|
|
5099
5141
|
else if (f.type === "map") walkUnitField(f.values);
|
|
5100
5142
|
};
|
|
5143
|
+
// TYPED-ID aggregate fields (`t.brandedId(Name)` / `t.uuid()`) declare their extension type with the
|
|
5144
|
+
// aggregate that owns them (skipping aggregates another file declares).
|
|
5145
|
+
for (const agg of mod.aggregates) {
|
|
5146
|
+
if (opts.skipAggregateIds?.has(agg.id) === true) continue;
|
|
5147
|
+
for (const f of Object.values(agg.fields as Record<string, Field>)) {
|
|
5148
|
+
if (f.kind !== "string") continue;
|
|
5149
|
+
const b = brandedIdMetaOf(f.zod as z.ZodTypeAny);
|
|
5150
|
+
if (b !== undefined) brandNames.add(b);
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
5101
5153
|
for (const d of localValueObjects) {
|
|
5102
5154
|
for (const f of Object.values(d.fields ?? {})) walkUnitField(f);
|
|
5103
5155
|
for (const arm of Object.values(d.union ?? {})) {
|
|
@@ -5128,6 +5180,8 @@ export function generateDartDomain(mod: DomainModule, opts: GenerateDartDomainOp
|
|
|
5128
5180
|
} catch { /* an unsupported payload shape is reported by the payload emitter, not here */ }
|
|
5129
5181
|
}
|
|
5130
5182
|
}
|
|
5183
|
+
for (const b of opts.skipBrandNames ?? []) brandNames.delete(b);
|
|
5184
|
+
for (const b of opts.extraBrandNames ?? []) brandNames.add(b);
|
|
5131
5185
|
const unitBlock = [...unitNames].sort().map((u) => [
|
|
5132
5186
|
`/// UNIT \`${u}\` — a ZERO-COST wrapper over the wire's plain JSON number (Dart extension`,
|
|
5133
5187
|
`/// type): passing a bare double (or another unit) where [${u}] is required is a COMPILE`,
|
|
@@ -5150,7 +5204,7 @@ export function generateDartDomain(mod: DomainModule, opts: GenerateDartDomainOp
|
|
|
5150
5204
|
...(brandBlock !== "" ? [brandBlock] : []),
|
|
5151
5205
|
...(localValueObjects.length > 0
|
|
5152
5206
|
? [
|
|
5153
|
-
emitVoHelpers(
|
|
5207
|
+
...(needsVoCopyWithSentinel ? [emitVoHelpers()] : []),
|
|
5154
5208
|
...localValueObjects.flatMap((d) => [
|
|
5155
5209
|
...voEnumFields(d)
|
|
5156
5210
|
.filter((e) => e.declaredName === undefined)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { BUSINESS_BIRTH_KEY_PAYLOAD_FIELD } from "./births.js";
|
|
1
2
|
import { dartRefusalDecoders } from "./codegen_refusal.js";
|
|
2
3
|
// NOMOS — Nomos Sovereign: participants act · verify · remember LOCALLY; hosted
|
|
3
4
|
// remotes are replaceable custody/transport, not truth. ⇒ ONE Nomos GitHolon
|
|
@@ -99,7 +100,7 @@ import { publicClientInterface, type DomainInterface } from "./compatibility_gra
|
|
|
99
100
|
import { emitApplicationCompatibilityUsda } from "./compatibility_usda.js";
|
|
100
101
|
import { BUSINESS_CORRECTION_DIRECTIVE } from "./framework/business_corrections.js";
|
|
101
102
|
import { deriveDirectiveRecordTarget } from "./workspace_routing.js";
|
|
102
|
-
import { voMetaOf } from "./value_object.js";
|
|
103
|
+
import { brandedIdMetaOf, voMetaOf } from "./value_object.js";
|
|
103
104
|
import {
|
|
104
105
|
buildNomosDescribeModel,
|
|
105
106
|
type NomosDescribeModel,
|
|
@@ -389,6 +390,11 @@ function dartKeyType(
|
|
|
389
390
|
if (f?.kind === "string" && isSha256DigestSchema(f.zod as z.ZodTypeAny)) {
|
|
390
391
|
return "Sha256Digest";
|
|
391
392
|
}
|
|
393
|
+
// A typed-id key (`t.brandedId(Name)` / `t.uuid()`) is its extension type, never a bare String.
|
|
394
|
+
if (f?.kind === "string" && !key.includes(".")) {
|
|
395
|
+
const brand = brandedIdMetaOf(f.zod as z.ZodTypeAny);
|
|
396
|
+
if (brand !== undefined) return brand;
|
|
397
|
+
}
|
|
392
398
|
if (f?.kind === "string" && isGitObjectIdSchema(f.zod as z.ZodTypeAny)) {
|
|
393
399
|
return "GitObjectId";
|
|
394
400
|
}
|
|
@@ -435,6 +441,13 @@ function dartKeyExpr(agg: AggregateHandle | undefined, key: string): string {
|
|
|
435
441
|
) {
|
|
436
442
|
return `${param}.value`;
|
|
437
443
|
}
|
|
444
|
+
if (
|
|
445
|
+
field?.kind === "string" &&
|
|
446
|
+
!key.includes(".") &&
|
|
447
|
+
brandedIdMetaOf(field.zod as z.ZodTypeAny) !== undefined
|
|
448
|
+
) {
|
|
449
|
+
return `${param}.value`;
|
|
450
|
+
}
|
|
438
451
|
if (field?.kind !== "ref") return param;
|
|
439
452
|
return field.foreignRef !== undefined
|
|
440
453
|
? `NmsInternalNomosRefs.id(${param}.ref)`
|
|
@@ -491,6 +504,8 @@ function dartUsdaBasePresentValue(
|
|
|
491
504
|
? `Sha256Digest(${value})`
|
|
492
505
|
: spec.semanticString === "git-object-id"
|
|
493
506
|
? `GitObjectId(${value})`
|
|
507
|
+
: spec.brandedId !== undefined
|
|
508
|
+
? `${spec.brandedId}(${value})`
|
|
494
509
|
: value;
|
|
495
510
|
}
|
|
496
511
|
case "ref": {
|
|
@@ -1305,7 +1320,7 @@ export function generateDartDomainClient(
|
|
|
1305
1320
|
const compilerInternal = sourceTrustViaIds.has(directive.id);
|
|
1306
1321
|
const businessBirth = (
|
|
1307
1322
|
directive as unknown as {
|
|
1308
|
-
businessBirth?: { publicPayloadSchema: z.ZodTypeAny };
|
|
1323
|
+
businessBirth?: { publicPayloadSchema: z.ZodTypeAny; keyField?: string };
|
|
1309
1324
|
}
|
|
1310
1325
|
).businessBirth;
|
|
1311
1326
|
const specs = introspectPayload(
|
|
@@ -1360,6 +1375,15 @@ export function generateDartDomainClient(
|
|
|
1360
1375
|
arguments_.push("principal", "bornAt");
|
|
1361
1376
|
access.set("principal", { value: "nmsInternalBirthPrincipal" });
|
|
1362
1377
|
access.set("bornAt", { value: "nmsInternalBornAt" });
|
|
1378
|
+
// A minted birth's law admits a key the client reserved ahead of dispatch (CAP-804).
|
|
1379
|
+
if (businessBirth.keyField === undefined) {
|
|
1380
|
+
extraParameters.push("String? nmsInternalBirthKey");
|
|
1381
|
+
arguments_.push("nmsInternalBirthKey");
|
|
1382
|
+
access.set(BUSINESS_BIRTH_KEY_PAYLOAD_FIELD, {
|
|
1383
|
+
value: "nmsInternalBirthKey!",
|
|
1384
|
+
present: "nmsInternalBirthKey != null",
|
|
1385
|
+
});
|
|
1386
|
+
}
|
|
1363
1387
|
}
|
|
1364
1388
|
for (const input of dartBusinessRecordInputs(directive, mod.aggregates)) {
|
|
1365
1389
|
const origin = `NmsInternalRecordOrigins.require(payload.${input.argument})`;
|
|
@@ -1954,7 +1978,8 @@ export function generateDartDomainClient(
|
|
|
1954
1978
|
domain: string;
|
|
1955
1979
|
rootId: string;
|
|
1956
1980
|
namespace: string;
|
|
1957
|
-
keyField
|
|
1981
|
+
keyField?: string;
|
|
1982
|
+
keyType?: { type: string; brand: string };
|
|
1958
1983
|
seedDirectiveId?: string;
|
|
1959
1984
|
genesisDirectiveIds?: readonly string[];
|
|
1960
1985
|
publicPayloadSchema: z.ZodTypeAny;
|
|
@@ -2010,6 +2035,18 @@ export function generateDartDomainClient(
|
|
|
2010
2035
|
const birthSpecsByName = new Map(
|
|
2011
2036
|
birthSpecs.map((spec) => [spec.name, spec])
|
|
2012
2037
|
);
|
|
2038
|
+
// A minted birth (the default) has no business key; an owned one seals to the child's address
|
|
2039
|
+
// before dispatch, so it reserves its key from the kernel's own minter and hands it to the law.
|
|
2040
|
+
const mintedBirth = businessBirth.keyField === undefined;
|
|
2041
|
+
const birthKeyPrelude = !mintedBirth
|
|
2042
|
+
? []
|
|
2043
|
+
: ownedBirthDescriptor === undefined
|
|
2044
|
+
? [` const String? nmsInternalBirthKey = null;`]
|
|
2045
|
+
: [
|
|
2046
|
+
` final String? nmsInternalBirthKey = await session.mintId(${dartStr(
|
|
2047
|
+
businessBirth.aggregateId
|
|
2048
|
+
)});`,
|
|
2049
|
+
];
|
|
2013
2050
|
const ownedBirthPrelude =
|
|
2014
2051
|
ownedBirthDescriptor === undefined
|
|
2015
2052
|
? []
|
|
@@ -2017,9 +2054,17 @@ export function generateDartDomainClient(
|
|
|
2017
2054
|
` final nmsInternalOwnedKey = await session.nomosOwnedBirthScopeKey(`,
|
|
2018
2055
|
` ${dartStr(ownedBirthDescriptor.scope)}, ${dartStr(
|
|
2019
2056
|
businessBirth.namespace
|
|
2020
|
-
)},
|
|
2021
|
-
|
|
2022
|
-
|
|
2057
|
+
)}, ${
|
|
2058
|
+
mintedBirth
|
|
2059
|
+
? "nmsInternalBirthKey!"
|
|
2060
|
+
: `payload.${dartMemberName(businessBirth.keyField!)}${
|
|
2061
|
+
businessBirth.keyType?.type === "brandedId" || businessBirth.keyType?.type === "uuid"
|
|
2062
|
+
? ".value"
|
|
2063
|
+
: ""
|
|
2064
|
+
}`
|
|
2065
|
+
}, ${dartStr(birthRuntimeType!)}, ${dartStr(
|
|
2066
|
+
businessBirth.rootId
|
|
2067
|
+
)});`,
|
|
2023
2068
|
` final nmsInternalOwnedKeySubject = nmsInternalOwnedKey.ownedKeySubject;`,
|
|
2024
2069
|
` if (nmsInternalOwnedKeySubject == null || nmsInternalOwnedKeySubject.isEmpty) {`,
|
|
2025
2070
|
` throw StateError('Nomos did not return the framework-owned device identity for .owned() custody');`,
|
|
@@ -2148,6 +2193,7 @@ export function generateDartDomainClient(
|
|
|
2148
2193
|
),
|
|
2149
2194
|
]),
|
|
2150
2195
|
` final bornAt = DateTime.now().toUtc().toIso8601String();`,
|
|
2196
|
+
...birthKeyPrelude,
|
|
2151
2197
|
...ownedBirthPrelude,
|
|
2152
2198
|
...birthSealPrelude,
|
|
2153
2199
|
...(birthEncryption === undefined
|
|
@@ -5,6 +5,7 @@ import { refusalContracts, refusalType, refusalDecoder } from "./codegen_refusal
|
|
|
5
5
|
// application contract: business inputs in, business ids/models out. It deliberately has no public
|
|
6
6
|
// session/session/workspace/actor/sync surface.
|
|
7
7
|
import type { z } from "zod";
|
|
8
|
+
import { brandedIdMetaOf } from "./value_object.js";
|
|
8
9
|
|
|
9
10
|
import type { AggregateHandle } from "./aggregate.js";
|
|
10
11
|
import type { Directive } from "./directive.js";
|
|
@@ -153,6 +154,11 @@ function keyType(
|
|
|
153
154
|
) {
|
|
154
155
|
return "GitObjectId";
|
|
155
156
|
}
|
|
157
|
+
// A typed-id key (`t.brandedId(Name)` / `t.uuid()`) is its extension type, never a bare String.
|
|
158
|
+
if (field?.kind === "string" && !key.includes(".")) {
|
|
159
|
+
const brand = brandedIdMetaOf(field.zod as z.ZodTypeAny);
|
|
160
|
+
if (brand !== undefined) return brand;
|
|
161
|
+
}
|
|
156
162
|
return "String";
|
|
157
163
|
}
|
|
158
164
|
|
|
@@ -381,7 +387,7 @@ export function generateDartApplication(
|
|
|
381
387
|
const source = aggregate.fields[name]!;
|
|
382
388
|
const value = source.kind === "enum" ? `${access}?.wire`
|
|
383
389
|
: source.kind === "ref" ? `${access}?.id`
|
|
384
|
-
: source.kind === "string" && (isSha256DigestSchema(source.zod) || isGitObjectIdSchema(source.zod)) ? `${access}?.value`
|
|
390
|
+
: source.kind === "string" && (isSha256DigestSchema(source.zod) || isGitObjectIdSchema(source.zod) || brandedIdMetaOf(source.zod as z.ZodTypeAny) !== undefined) ? `${access}?.value`
|
|
385
391
|
: access;
|
|
386
392
|
return ` ${member(name)}: ${value},`;
|
|
387
393
|
}),
|
|
@@ -900,7 +906,9 @@ export function generateDartApplication(
|
|
|
900
906
|
aggregateId: string;
|
|
901
907
|
namespace: string;
|
|
902
908
|
rootId: string;
|
|
903
|
-
|
|
909
|
+
keyMode?: "minted" | "field";
|
|
910
|
+
keyField?: string;
|
|
911
|
+
keyType?: { type: string; brand: string };
|
|
904
912
|
};
|
|
905
913
|
birthsChild?: boolean;
|
|
906
914
|
}
|
|
@@ -993,39 +1001,53 @@ export function generateDartApplication(
|
|
|
993
1001
|
` return _nmsReception.fetchWorkspace(reference.workspace);`,
|
|
994
1002
|
` }`,
|
|
995
1003
|
``,
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
`
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1004
|
+
// Open/fetch BY KEY exist only for a birth keyed by a declared business fact. A minted birth
|
|
1005
|
+
// (the default) has no business key: its address is the NomosRef its birth returned.
|
|
1006
|
+
// The key param is the key field's TYPED ID (its extension type, declared with the birth payload in
|
|
1007
|
+
// this domain's types); `.value` is its wire string.
|
|
1008
|
+
...(birth.keyField === undefined
|
|
1009
|
+
? []
|
|
1010
|
+
: (() => {
|
|
1011
|
+
const typedKey = birth.keyType !== undefined &&
|
|
1012
|
+
(birth.keyType.type === "brandedId" || birth.keyType.type === "uuid");
|
|
1013
|
+
const keyParam = typedKey ? `${birth.keyType!.brand} key` : "String key";
|
|
1014
|
+
const keyWire = typedKey ? "key.value" : "key";
|
|
1015
|
+
return [
|
|
1016
|
+
` /// Open the ${birth.aggregateId} whose ${birth.keyField} is [key].`,
|
|
1017
|
+
` /// THE OFFICE NAMES THE WORKSPACE this key addresses: the derivation is law,`,
|
|
1018
|
+
` /// and a generated copy of it would silently address a different workspace`,
|
|
1019
|
+
` /// the moment either side moved.`,
|
|
1020
|
+
` Future<${targetApplication}> open(${keyParam}) async => _nmsOpenReference(`,
|
|
1021
|
+
` NmsInternalNomosRefs.create<${rootType}>(`,
|
|
1022
|
+
` workspace: await _nmsReception.keyedBirthWorkspace(`,
|
|
1023
|
+
` namespace: ${JSON.stringify(birth.namespace)}, key: ${keyWire},`,
|
|
1024
|
+
` ),`,
|
|
1025
|
+
` type: ${JSON.stringify(birth.aggregateId)},`,
|
|
1026
|
+
` id: ${JSON.stringify(birth.rootId)},`,
|
|
1027
|
+
` ),`,
|
|
1028
|
+
` );`,
|
|
1029
|
+
``,
|
|
1030
|
+
` /// Fetch the ${birth.aggregateId} whose ${birth.keyField} is [key] onto this device now,`,
|
|
1031
|
+
` /// opening and reading nothing: its placement's follow mounts the provider's head in`,
|
|
1032
|
+
` /// the background. Completes once that follow exists (e.g. prefetching every workspace`,
|
|
1033
|
+
` /// a list names, all at once, so each is local before it is tapped).`,
|
|
1034
|
+
` Future<void> fetch(${keyParam}) async => _nmsReception.fetchWorkspace(`,
|
|
1035
|
+
` await _nmsReception.keyedBirthWorkspace(`,
|
|
1036
|
+
` namespace: ${JSON.stringify(birth.namespace)}, key: ${keyWire},`,
|
|
1037
|
+
` ),`,
|
|
1038
|
+
` );`,
|
|
1039
|
+
``,
|
|
1040
|
+
` /// Kernel-owned progress updates while [open] prepares this workspace.`,
|
|
1041
|
+
` /// ONE LANE: the stream is the whole surface. A synchronous snapshot`,
|
|
1042
|
+
` /// would have to answer before the office has named the workspace, so`,
|
|
1043
|
+
` /// it could only ever answer null or hold a cached name of its own.`,
|
|
1044
|
+
` Stream<ApplicationWorkspaceOpenProgress> watchOpenProgress(${keyParam}) =>`,
|
|
1045
|
+
` Stream<String>.fromFuture(_nmsReception.keyedBirthWorkspace(`,
|
|
1046
|
+
` namespace: ${JSON.stringify(birth.namespace)}, key: ${keyWire},`,
|
|
1047
|
+
` )).asyncExpand(_nmsReception.streams.workspaceOpenProgress);`,
|
|
1048
|
+
``,
|
|
1049
|
+
];
|
|
1050
|
+
})()),
|
|
1029
1051
|
]);
|
|
1030
1052
|
addCollectionMember(birth.aggregateId, "mine", [
|
|
1031
1053
|
` /// The ${birth.aggregateId} lives founded by the signed-in person.`,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { assertDomainRequirements, type DomainUnitRequirement } from "./domain_requirements.js";
|
|
1
2
|
import type { z } from "zod";
|
|
2
3
|
|
|
3
4
|
import type { Directive } from "./directive.js";
|
|
@@ -177,6 +178,12 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
177
178
|
readonly lawUnitSet: string;
|
|
178
179
|
/** The compiled package closure (`build/<name>.law.usdz`): the bytes a device stages. Not what a target serves. */
|
|
179
180
|
readonly lawPackageSha256: string;
|
|
181
|
+
/**
|
|
182
|
+
* THE PER-DOMAIN REQUIREMENTS (CAP-666): per application domain key, its unit hash and the identity of its
|
|
183
|
+
* generated compatibility requirement. Absent or empty emits an empty table (a package with no application
|
|
184
|
+
* interface); the getter itself is always emitted, since the runtime interface is exhaustive.
|
|
185
|
+
*/
|
|
186
|
+
readonly domainRequirements?: readonly DomainUnitRequirement[];
|
|
180
187
|
},
|
|
181
188
|
): string | undefined {
|
|
182
189
|
for (const [name, value] of [["law unit set", descriptor.lawUnitSet], ["package", descriptor.lawPackageSha256]] as const) {
|
|
@@ -184,6 +191,8 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
184
191
|
throw new Error(`Dart framework call codegen: the application's ${name} identity must be 64 lowercase hex, not '${value}'`);
|
|
185
192
|
}
|
|
186
193
|
}
|
|
194
|
+
const domainRequirements = [...(descriptor.domainRequirements ?? [])].sort((a, b) => a.domainKey < b.domainKey ? -1 : a.domainKey > b.domainKey ? 1 : 0);
|
|
195
|
+
assertDomainRequirements(domainRequirements);
|
|
187
196
|
const frameworkEnumDartTypes = collectFixedFrameworkDartEnums().dartTypes;
|
|
188
197
|
const fixedEmitted = FIXED_CALLS.flatMap((definition) => laws.flatMap((law) => {
|
|
189
198
|
const declares = law.graph.nodes.some((node) =>
|
|
@@ -622,7 +631,7 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
622
631
|
`import 'package:fixnum/fixnum.dart' show Int64;`,
|
|
623
632
|
`import 'operation_payloads.pb.dart' as _nmsop;`,
|
|
624
633
|
`import 'package:nomos_types/nomos_kernel_protocol.dart' show BirthCertificate;`,
|
|
625
|
-
`import 'package:nomos_types/nomos_types.dart' show NomosSlot, Sha256Digest;`,
|
|
634
|
+
`import 'package:nomos_types/nomos_types.dart' show NomosDomainRequirement, NomosSlot, Sha256Digest;`,
|
|
626
635
|
`import 'package:nomos_client/src/application_framework_calls.dart';`,
|
|
627
636
|
`import 'package:nomos_client/src/generated_call.dart';`,
|
|
628
637
|
``,
|
|
@@ -651,6 +660,16 @@ export function generateDartApplicationFrameworkCalls(
|
|
|
651
660
|
` String get lawUnitSet => ${JSON.stringify(descriptor.lawUnitSet)};`,
|
|
652
661
|
` @override`,
|
|
653
662
|
` String get lawPackageSha256 => ${JSON.stringify(descriptor.lawPackageSha256)};`,
|
|
663
|
+
` @override`,
|
|
664
|
+
...(domainRequirements.length === 0
|
|
665
|
+
? [` Map<String, NomosDomainRequirement> get domainRequirements => const {};`]
|
|
666
|
+
: [
|
|
667
|
+
` Map<String, NomosDomainRequirement> get domainRequirements => const {`,
|
|
668
|
+
...domainRequirements.map((requirement) =>
|
|
669
|
+
` ${JSON.stringify(requirement.domainKey)}: NomosDomainRequirement(domainKey: ${JSON.stringify(requirement.domainKey)}, `
|
|
670
|
+
+ `unitSha256: ${JSON.stringify(requirement.unitSha256)}, requirementSha256: ${JSON.stringify(requirement.requirementSha256)}),`),
|
|
671
|
+
` };`,
|
|
672
|
+
]),
|
|
654
673
|
``,
|
|
655
674
|
...methods,
|
|
656
675
|
`}`,
|