@prisma-next/contract 0.12.0 → 0.13.0-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apply-specifier-default-control-policy.d.mts +7 -0
- package/dist/apply-specifier-default-control-policy.d.mts.map +1 -0
- package/dist/apply-specifier-default-control-policy.mjs +12 -0
- package/dist/apply-specifier-default-control-policy.mjs.map +1 -0
- package/dist/{canonicalization-DFE0HJkI.d.mts → canonicalization-BqYzAeWE.d.mts} +2 -2
- package/dist/canonicalization-BqYzAeWE.d.mts.map +1 -0
- package/dist/{canonicalization-path-match-b2jFuEso.mjs → canonicalization-path-match-CNgHuwM_.mjs} +1 -1
- package/dist/{canonicalization-path-match-b2jFuEso.mjs.map → canonicalization-path-match-CNgHuwM_.mjs.map} +1 -1
- package/dist/contract-types-CtIh62PH.d.mts +82 -0
- package/dist/contract-types-CtIh62PH.d.mts.map +1 -0
- package/dist/{contract-validation-error-ClZaKqMW.mjs → contract-validation-error-BFA66rwU.mjs} +1 -1
- package/dist/{contract-validation-error-ClZaKqMW.mjs.map → contract-validation-error-BFA66rwU.mjs.map} +1 -1
- package/dist/{contract-validation-error-T5LH4DW-.d.mts → contract-validation-error-D7g0kmcc.d.mts} +1 -1
- package/dist/{contract-validation-error-T5LH4DW-.d.mts.map → contract-validation-error-D7g0kmcc.d.mts.map} +1 -1
- package/dist/contract-validation-error.d.mts +1 -1
- package/dist/contract-validation-error.mjs +1 -1
- package/dist/default-namespace-D5X_k6hJ.d.mts +25 -0
- package/dist/default-namespace-D5X_k6hJ.d.mts.map +1 -0
- package/dist/default-namespace-rpdJeUMq.mjs +33 -0
- package/dist/default-namespace-rpdJeUMq.mjs.map +1 -0
- package/dist/default-namespace.d.mts +2 -0
- package/dist/default-namespace.mjs +2 -0
- package/dist/domain-envelope-DKOnhO5d.d.mts +352 -0
- package/dist/domain-envelope-DKOnhO5d.d.mts.map +1 -0
- package/dist/enum-accessor.d.mts +77 -0
- package/dist/enum-accessor.d.mts.map +1 -0
- package/dist/enum-accessor.mjs +45 -0
- package/dist/enum-accessor.mjs.map +1 -0
- package/dist/hashing-utils.d.mts +1 -1
- package/dist/hashing-utils.d.mts.map +1 -1
- package/dist/hashing-utils.mjs +5 -4
- package/dist/hashing-utils.mjs.map +1 -1
- package/dist/hashing.d.mts +2 -2
- package/dist/hashing.d.mts.map +1 -1
- package/dist/hashing.mjs +38 -11
- package/dist/hashing.mjs.map +1 -1
- package/dist/{namespace-id-CVpkSFUK.mjs → namespace-id-CUxYd4KL.mjs} +1 -1
- package/dist/{namespace-id-CVpkSFUK.mjs.map → namespace-id-CUxYd4KL.mjs.map} +1 -1
- package/dist/resolve-domain-model-BovPAsW2.mjs +20 -0
- package/dist/resolve-domain-model-BovPAsW2.mjs.map +1 -0
- package/dist/resolve-domain-model-CSEqpByI.d.mts +17 -0
- package/dist/resolve-domain-model-CSEqpByI.d.mts.map +1 -0
- package/dist/resolve-domain-model.d.mts +2 -0
- package/dist/resolve-domain-model.mjs +2 -0
- package/dist/types.d.mts +21 -4
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +40 -30
- package/dist/types.mjs.map +1 -1
- package/dist/validate-domain.d.mts +1 -1
- package/dist/validate-domain.mjs +6 -3
- package/dist/validate-domain.mjs.map +1 -1
- package/package.json +10 -6
- package/src/apply-specifier-default-control-policy.ts +12 -0
- package/src/canonicalization-storage-sort.ts +8 -1
- package/src/canonicalization.ts +13 -4
- package/src/contract-types.ts +9 -5
- package/src/control-policy.ts +25 -0
- package/src/cross-reference.ts +15 -3
- package/src/default-namespace.ts +36 -0
- package/src/domain-envelope.ts +3 -61
- package/src/domain-namespace-access.ts +32 -0
- package/src/domain-types.ts +32 -1
- package/src/enum-accessor.ts +173 -0
- package/src/exports/apply-specifier-default-control-policy.ts +1 -0
- package/src/exports/default-namespace.ts +1 -0
- package/src/exports/enum-accessor.ts +11 -0
- package/src/exports/resolve-domain-model.ts +1 -0
- package/src/exports/types.ts +16 -7
- package/src/hashing.ts +42 -13
- package/src/resolve-domain-model.ts +27 -0
- package/src/types.ts +18 -2
- package/src/validate-domain.ts +6 -0
- package/src/value-set-ref.ts +26 -0
- package/dist/canonicalization-DFE0HJkI.d.mts.map +0 -1
- package/dist/contract-types-xgwKtd7y.d.mts +0 -233
- package/dist/contract-types-xgwKtd7y.d.mts.map +0 -1
- package/dist/domain-envelope-4hyFtJ4_.d.mts +0 -110
- package/dist/domain-envelope-4hyFtJ4_.d.mts.map +0 -1
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { t as Contract } from "./contract-types-CtIh62PH.mjs";
|
|
2
|
+
import { U as JsonValue, o as ContractEnum } from "./domain-envelope-DKOnhO5d.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/enum-accessor.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Runtime view of a domain enum, built at the client from the emitted
|
|
7
|
+
* `ContractEnum` JSON (codec-encoded `JsonValue` members, literal types erased).
|
|
8
|
+
*
|
|
9
|
+
* This deliberately mirrors the accessor shape of the authoring-time
|
|
10
|
+
* `EnumTypeHandle` (in `contract-ts`) rather than reusing it: that handle carries
|
|
11
|
+
* the literal value generics and lives in the authoring layer, which the
|
|
12
|
+
* foundation layer cannot depend on. The two are the same surface seen from the
|
|
13
|
+
* two planes — authoring (typed) and runtime (validated JSON).
|
|
14
|
+
*/
|
|
15
|
+
interface EnumAccessor {
|
|
16
|
+
readonly values: readonly JsonValue[];
|
|
17
|
+
readonly names: readonly string[];
|
|
18
|
+
readonly members: Readonly<Record<string, JsonValue>>;
|
|
19
|
+
has(v: JsonValue): boolean;
|
|
20
|
+
nameOf(v: JsonValue): string | undefined;
|
|
21
|
+
ordinalOf(v: JsonValue): number;
|
|
22
|
+
}
|
|
23
|
+
declare function createEnumAccessor(contractEnum: ContractEnum): EnumAccessor;
|
|
24
|
+
/**
|
|
25
|
+
* Build the enum-accessor map for a single namespace, keyed by enum name.
|
|
26
|
+
* Each namespace facet exposes only its own enums — the IR keys enums under
|
|
27
|
+
* `domain.namespaces[ns].enum`, so the same name in two namespaces resolves
|
|
28
|
+
* independently rather than colliding in one flat map.
|
|
29
|
+
*/
|
|
30
|
+
declare function buildEnumsMapForNamespace(domain: {
|
|
31
|
+
readonly namespaces: Readonly<Record<string, {
|
|
32
|
+
readonly enum?: Readonly<Record<string, ContractEnum>>;
|
|
33
|
+
}>>;
|
|
34
|
+
}, namespaceId: string): Record<string, EnumAccessor>;
|
|
35
|
+
/**
|
|
36
|
+
* Build the enum-accessor map for every namespace of a domain, keyed by
|
|
37
|
+
* namespace id then enum name. This is the lane-agnostic enum surface the
|
|
38
|
+
* `db.enums` facade member exposes: enums are contract metadata, the same
|
|
39
|
+
* whether reached through the sql lane or the orm lane, so the facade builds
|
|
40
|
+
* this once and projects it per target.
|
|
41
|
+
*/
|
|
42
|
+
declare function buildNamespacedEnums(domain: {
|
|
43
|
+
readonly namespaces: Readonly<Record<string, {
|
|
44
|
+
readonly enum?: Readonly<Record<string, ContractEnum>>;
|
|
45
|
+
}>>;
|
|
46
|
+
}): Record<string, Record<string, EnumAccessor>>;
|
|
47
|
+
type Present<T> = Exclude<T, undefined>;
|
|
48
|
+
type EnumMemberEntry = {
|
|
49
|
+
readonly name: string;
|
|
50
|
+
readonly value: unknown;
|
|
51
|
+
};
|
|
52
|
+
type EnumEntry = {
|
|
53
|
+
readonly members: readonly EnumMemberEntry[];
|
|
54
|
+
};
|
|
55
|
+
type EnumEntryValues<Entry extends EnumEntry> = { readonly [I in keyof Entry['members']]: Entry['members'][I] extends EnumMemberEntry ? Entry['members'][I]['value'] : never };
|
|
56
|
+
type EnumEntryNames<Entry extends EnumEntry> = { readonly [I in keyof Entry['members']]: Entry['members'][I] extends EnumMemberEntry ? Entry['members'][I]['name'] : never };
|
|
57
|
+
type EnumEntryMembers<Entry extends EnumEntry> = { readonly [M in Entry['members'][number] as M['name']]: M['value'] };
|
|
58
|
+
type ContractEnumAccessor<Entry extends EnumEntry> = {
|
|
59
|
+
readonly values: EnumEntryValues<Entry>;
|
|
60
|
+
readonly names: EnumEntryNames<Entry>;
|
|
61
|
+
readonly members: EnumEntryMembers<Entry>;
|
|
62
|
+
has(v: EnumEntryValues<Entry>[number]): boolean;
|
|
63
|
+
nameOf(v: EnumEntryValues<Entry>[number]): string | undefined;
|
|
64
|
+
ordinalOf(v: EnumEntryValues<Entry>[number]): number;
|
|
65
|
+
};
|
|
66
|
+
type EnumEntriesToAccessors<Enums> = { readonly [K in keyof Enums]: Enums[K] extends EnumEntry ? ContractEnumAccessor<Enums[K]> : never };
|
|
67
|
+
type BuiltEnumAccessorsOf<TContract> = TContract extends {
|
|
68
|
+
readonly enumAccessors: infer A;
|
|
69
|
+
} ? A : Record<never, never>;
|
|
70
|
+
type NamespaceEnumEntries<TNamespace> = TNamespace extends {
|
|
71
|
+
readonly enum?: infer E;
|
|
72
|
+
} ? unknown extends E ? Record<never, never> : Present<E> : Record<never, never>;
|
|
73
|
+
type NamespaceEnumAccessors<TContract extends Contract, NsId extends keyof TContract['domain']['namespaces']> = EnumEntriesToAccessors<NamespaceEnumEntries<TContract['domain']['namespaces'][NsId]>> & BuiltEnumAccessorsOf<TContract>;
|
|
74
|
+
type NamespacedEnums<TContract extends Contract> = { readonly [Ns in keyof TContract['domain']['namespaces']]: NamespaceEnumAccessors<TContract, Ns> };
|
|
75
|
+
//#endregion
|
|
76
|
+
export { type ContractEnumAccessor, type EnumAccessor, type NamespaceEnumAccessors, type NamespacedEnums, buildEnumsMapForNamespace, buildNamespacedEnums, createEnumAccessor };
|
|
77
|
+
//# sourceMappingURL=enum-accessor.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-accessor.d.mts","names":[],"sources":["../src/enum-accessor.ts"],"mappings":";;;;;AAcA;;;;;;;;;UAAiB,YAAA;EAAA,SACN,MAAA,WAAiB,SAAA;EAAA,SACjB,KAAA;EAAA,SACA,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,SAAA;EAC1C,GAAA,CAAI,CAAA,EAAG,SAAA;EACP,MAAA,CAAO,CAAA,EAAG,SAAA;EACV,SAAA,CAAU,CAAA,EAAG,SAAA;AAAA;AAAA,iBAGC,kBAAA,CAAmB,YAAA,EAAc,YAAA,GAAe,YAAY;;;;;;;iBA2B5D,yBAAA,CACd,MAAA;EAAA,SACW,UAAA,EAAY,QAAA,CACnB,MAAA;IAAA,SAA0B,IAAA,GAAO,QAAA,CAAS,MAAA,SAAe,YAAA;EAAA;AAAA,GAG7D,WAAA,WACC,MAAA,SAAe,YAAA;AArCM;AAGxB;;;;;;AAHwB,iBAuDR,oBAAA,CAAqB,MAAA;EAAA,SAC1B,UAAA,EAAY,QAAA,CACnB,MAAA;IAAA,SAA0B,IAAA,GAAO,QAAA,CAAS,MAAA,SAAe,YAAA;EAAA;AAAA,IAEzD,MAAA,SAAe,MAAA,SAAe,YAAA;AAAA,KA0B7B,OAAA,MAAa,OAAO,CAAC,CAAA;AAAA,KAKrB,eAAA;EAAA,SAA6B,IAAA;EAAA,SAAuB,KAAK;AAAA;AAAA,KACzD,SAAA;EAAA,SAAuB,OAAA,WAAkB,eAAe;AAAA;AAAA,KAExD,eAAA,eAA8B,SAAA,2BACZ,KAAA,cAAmB,KAAA,YAAiB,CAAA,UAAW,eAAA,GAChE,KAAA,YAAiB,CAAA;AAAA,KAIlB,cAAA,eAA6B,SAAA,2BACX,KAAA,cAAmB,KAAA,YAAiB,CAAA,UAAW,eAAA,GAChE,KAAA,YAAiB,CAAA;AAAA,KAIlB,gBAAA,eAA+B,SAAA,qBACnB,KAAA,uBAA4B,CAAA,WAAY,CAAA;AAAA,KAM7C,oBAAA,eAAmC,SAAA;EAAA,SACpC,MAAA,EAAQ,eAAA,CAAgB,KAAA;EAAA,SACxB,KAAA,EAAO,cAAA,CAAe,KAAA;EAAA,SACtB,OAAA,EAAS,gBAAA,CAAiB,KAAA;EACnC,GAAA,CAAI,CAAA,EAAG,eAAA,CAAgB,KAAA;EACvB,MAAA,CAAO,CAAA,EAAG,eAAA,CAAgB,KAAA;EAC1B,SAAA,CAAU,CAAA,EAAG,eAAA,CAAgB,KAAA;AAAA;AAAA,KAG1B,sBAAA,iCACkB,KAAA,GAAQ,KAAA,CAAM,CAAA,UAAW,SAAA,GAAY,oBAAA,CAAqB,KAAA,CAAM,CAAA;AAAA,KAGlF,oBAAA,cAAkC,SAAA;EAAA,SAC5B,aAAA;AAAA,IAEP,CAAA,GACA,MAAM;AAAA,KAEL,oBAAA,eAAmC,UAAA;EAAA,SAC7B,IAAA;AAAA,oBAES,CAAA,GACd,MAAA,iBACA,OAAA,CAAQ,CAAA,IACV,MAAA;AAAA,KAKQ,sBAAA,mBACQ,QAAA,qBACC,SAAA,4BACjB,sBAAA,CAAuB,oBAAA,CAAqB,SAAA,yBAAkC,IAAA,MAChF,oBAAA,CAAqB,SAAA;AAAA,KAIX,eAAA,mBAAkC,QAAA,4BACtB,SAAA,2BAAoC,sBAAA,CAAuB,SAAA,EAAW,EAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/enum-accessor.ts
|
|
2
|
+
function createEnumAccessor(contractEnum) {
|
|
3
|
+
const values = Object.freeze(contractEnum.members.map((m) => m.value));
|
|
4
|
+
const names = Object.freeze(contractEnum.members.map((m) => m.name));
|
|
5
|
+
const members = Object.freeze(Object.fromEntries(contractEnum.members.map((m) => [m.name, m.value])));
|
|
6
|
+
const valueSet = new Set(values);
|
|
7
|
+
const valueToName = new Map(contractEnum.members.map((m) => [m.value, m.name]));
|
|
8
|
+
const valueToOrdinal = new Map(values.map((v, i) => [v, i]));
|
|
9
|
+
return {
|
|
10
|
+
values,
|
|
11
|
+
names,
|
|
12
|
+
members,
|
|
13
|
+
has: (v) => valueSet.has(v),
|
|
14
|
+
nameOf: (v) => valueToName.get(v),
|
|
15
|
+
ordinalOf: (v) => valueToOrdinal.get(v) ?? -1
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the enum-accessor map for a single namespace, keyed by enum name.
|
|
20
|
+
* Each namespace facet exposes only its own enums — the IR keys enums under
|
|
21
|
+
* `domain.namespaces[ns].enum`, so the same name in two namespaces resolves
|
|
22
|
+
* independently rather than colliding in one flat map.
|
|
23
|
+
*/
|
|
24
|
+
function buildEnumsMapForNamespace(domain, namespaceId) {
|
|
25
|
+
const result = {};
|
|
26
|
+
const namespace = domain.namespaces[namespaceId];
|
|
27
|
+
if (namespace?.enum) for (const [name, contractEnum] of Object.entries(namespace.enum)) result[name] = createEnumAccessor(contractEnum);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build the enum-accessor map for every namespace of a domain, keyed by
|
|
32
|
+
* namespace id then enum name. This is the lane-agnostic enum surface the
|
|
33
|
+
* `db.enums` facade member exposes: enums are contract metadata, the same
|
|
34
|
+
* whether reached through the sql lane or the orm lane, so the facade builds
|
|
35
|
+
* this once and projects it per target.
|
|
36
|
+
*/
|
|
37
|
+
function buildNamespacedEnums(domain) {
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const namespaceId of Object.keys(domain.namespaces)) result[namespaceId] = buildEnumsMapForNamespace(domain, namespaceId);
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { buildEnumsMapForNamespace, buildNamespacedEnums, createEnumAccessor };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=enum-accessor.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-accessor.mjs","names":[],"sources":["../src/enum-accessor.ts"],"sourcesContent":["import type { Contract } from './contract-types';\nimport type { ContractEnum } from './domain-types';\nimport type { JsonValue } from './types';\n\n/**\n * Runtime view of a domain enum, built at the client from the emitted\n * `ContractEnum` JSON (codec-encoded `JsonValue` members, literal types erased).\n *\n * This deliberately mirrors the accessor shape of the authoring-time\n * `EnumTypeHandle` (in `contract-ts`) rather than reusing it: that handle carries\n * the literal value generics and lives in the authoring layer, which the\n * foundation layer cannot depend on. The two are the same surface seen from the\n * two planes — authoring (typed) and runtime (validated JSON).\n */\nexport interface EnumAccessor {\n readonly values: readonly JsonValue[];\n readonly names: readonly string[];\n readonly members: Readonly<Record<string, JsonValue>>;\n has(v: JsonValue): boolean;\n nameOf(v: JsonValue): string | undefined;\n ordinalOf(v: JsonValue): number;\n}\n\nexport function createEnumAccessor(contractEnum: ContractEnum): EnumAccessor {\n const values = Object.freeze(contractEnum.members.map((m) => m.value));\n const names = Object.freeze(contractEnum.members.map((m) => m.name));\n const members: Readonly<Record<string, JsonValue>> = Object.freeze(\n Object.fromEntries(contractEnum.members.map((m) => [m.name, m.value])),\n );\n\n const valueSet = new Set(values);\n const valueToName = new Map(contractEnum.members.map((m) => [m.value, m.name]));\n const valueToOrdinal = new Map(values.map((v, i) => [v, i]));\n\n return {\n values,\n names,\n members,\n has: (v: JsonValue) => valueSet.has(v),\n nameOf: (v: JsonValue) => valueToName.get(v),\n ordinalOf: (v: JsonValue) => valueToOrdinal.get(v) ?? -1,\n };\n}\n\n/**\n * Build the enum-accessor map for a single namespace, keyed by enum name.\n * Each namespace facet exposes only its own enums — the IR keys enums under\n * `domain.namespaces[ns].enum`, so the same name in two namespaces resolves\n * independently rather than colliding in one flat map.\n */\nexport function buildEnumsMapForNamespace(\n domain: {\n readonly namespaces: Readonly<\n Record<string, { readonly enum?: Readonly<Record<string, ContractEnum>> }>\n >;\n },\n namespaceId: string,\n): Record<string, EnumAccessor> {\n const result: Record<string, EnumAccessor> = {};\n const namespace = domain.namespaces[namespaceId];\n if (namespace?.enum) {\n for (const [name, contractEnum] of Object.entries(namespace.enum)) {\n result[name] = createEnumAccessor(contractEnum);\n }\n }\n return result;\n}\n\n/**\n * Build the enum-accessor map for every namespace of a domain, keyed by\n * namespace id then enum name. This is the lane-agnostic enum surface the\n * `db.enums` facade member exposes: enums are contract metadata, the same\n * whether reached through the sql lane or the orm lane, so the facade builds\n * this once and projects it per target.\n */\nexport function buildNamespacedEnums(domain: {\n readonly namespaces: Readonly<\n Record<string, { readonly enum?: Readonly<Record<string, ContractEnum>> }>\n >;\n}): Record<string, Record<string, EnumAccessor>> {\n const result: Record<string, Record<string, EnumAccessor>> = {};\n for (const namespaceId of Object.keys(domain.namespaces)) {\n result[namespaceId] = buildEnumsMapForNamespace(domain, namespaceId);\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Type-level projection of the namespaced enum surface.\n//\n// These types derive the literal-preserving accessor shape from the contract,\n// hung off the `db.enums` facade map (`db.enums.<ns>.<Name>`). They are the\n// same accessors the runtime builds above, but typed from the two emission\n// paths:\n// - Emitted contracts carry the literal enum entries under\n// `domain.namespaces[ns].enum`; each maps to a `ContractEnumAccessor`.\n// - The no-emit (built) contract carries them flat on `enumAccessors`\n// (already accessor-shaped, literal-preserving), since its built domain\n// type does not narrow `namespaces[ns].enum`. All authored enums land in\n// the single built namespace, so exposing the flat map per namespace is\n// correct there.\n// Only `SqlContractResult` carries `enumAccessors`; emitted contracts never\n// do, so the two carriers never overlap.\n// ---------------------------------------------------------------------------\n\ntype Present<T> = Exclude<T, undefined>;\n\n// A domain enum entry as carried in `domain.namespaces[ns].enum[name]`: an\n// ordered member tuple. The no-emit (built) path preserves the literal member\n// values so the derived accessor keeps its literal `values`/`names`/`members`.\ntype EnumMemberEntry = { readonly name: string; readonly value: unknown };\ntype EnumEntry = { readonly members: readonly EnumMemberEntry[] };\n\ntype EnumEntryValues<Entry extends EnumEntry> = {\n readonly [I in keyof Entry['members']]: Entry['members'][I] extends EnumMemberEntry\n ? Entry['members'][I]['value']\n : never;\n};\n\ntype EnumEntryNames<Entry extends EnumEntry> = {\n readonly [I in keyof Entry['members']]: Entry['members'][I] extends EnumMemberEntry\n ? Entry['members'][I]['name']\n : never;\n};\n\ntype EnumEntryMembers<Entry extends EnumEntry> = {\n readonly [M in Entry['members'][number] as M['name']]: M['value'];\n};\n\n// The runtime accessor shape for one enum, with literal `values`/`names`/\n// `members` derived from the entry's member tuple. Mirrors `EnumAccessor`'s\n// runtime surface and the authoring `EnumTypeHandle` accessor.\nexport type ContractEnumAccessor<Entry extends EnumEntry> = {\n readonly values: EnumEntryValues<Entry>;\n readonly names: EnumEntryNames<Entry>;\n readonly members: EnumEntryMembers<Entry>;\n has(v: EnumEntryValues<Entry>[number]): boolean;\n nameOf(v: EnumEntryValues<Entry>[number]): string | undefined;\n ordinalOf(v: EnumEntryValues<Entry>[number]): number;\n};\n\ntype EnumEntriesToAccessors<Enums> = {\n readonly [K in keyof Enums]: Enums[K] extends EnumEntry ? ContractEnumAccessor<Enums[K]> : never;\n};\n\ntype BuiltEnumAccessorsOf<TContract> = TContract extends {\n readonly enumAccessors: infer A;\n}\n ? A\n : Record<never, never>;\n\ntype NamespaceEnumEntries<TNamespace> = TNamespace extends {\n readonly enum?: infer E;\n}\n ? unknown extends E\n ? Record<never, never>\n : Present<E>\n : Record<never, never>;\n\n// The per-namespace enum accessors. Each namespace exposes only its own enums\n// (the IR's `domain.namespaces[ns].enum`), so the same enum name in two\n// namespaces resolves to each namespace's own accessor.\nexport type NamespaceEnumAccessors<\n TContract extends Contract,\n NsId extends keyof TContract['domain']['namespaces'],\n> = EnumEntriesToAccessors<NamespaceEnumEntries<TContract['domain']['namespaces'][NsId]>> &\n BuiltEnumAccessorsOf<TContract>;\n\n// The lane-agnostic enum surface exposed on the `db.enums` facade member: a\n// namespace-keyed map projected per target exactly like `db.sql` / `db.orm`.\nexport type NamespacedEnums<TContract extends Contract> = {\n readonly [Ns in keyof TContract['domain']['namespaces']]: NamespaceEnumAccessors<TContract, Ns>;\n};\n"],"mappings":";AAuBA,SAAgB,mBAAmB,cAA0C;CAC3E,MAAM,SAAS,OAAO,OAAO,aAAa,QAAQ,KAAK,MAAM,EAAE,KAAK,CAAC;CACrE,MAAM,QAAQ,OAAO,OAAO,aAAa,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC;CACnE,MAAM,UAA+C,OAAO,OAC1D,OAAO,YAAY,aAAa,QAAQ,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CACvE;CAEA,MAAM,WAAW,IAAI,IAAI,MAAM;CAC/B,MAAM,cAAc,IAAI,IAAI,aAAa,QAAQ,KAAK,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;CAC9E,MAAM,iBAAiB,IAAI,IAAI,OAAO,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;CAE3D,OAAO;EACL;EACA;EACA;EACA,MAAM,MAAiB,SAAS,IAAI,CAAC;EACrC,SAAS,MAAiB,YAAY,IAAI,CAAC;EAC3C,YAAY,MAAiB,eAAe,IAAI,CAAC,KAAK;CACxD;AACF;;;;;;;AAQA,SAAgB,0BACd,QAKA,aAC8B;CAC9B,MAAM,SAAuC,CAAC;CAC9C,MAAM,YAAY,OAAO,WAAW;CACpC,IAAI,WAAW,MACb,KAAK,MAAM,CAAC,MAAM,iBAAiB,OAAO,QAAQ,UAAU,IAAI,GAC9D,OAAO,QAAQ,mBAAmB,YAAY;CAGlD,OAAO;AACT;;;;;;;;AASA,SAAgB,qBAAqB,QAIY;CAC/C,MAAM,SAAuD,CAAC;CAC9D,KAAK,MAAM,eAAe,OAAO,KAAK,OAAO,UAAU,GACrD,OAAO,eAAe,0BAA0B,QAAQ,WAAW;CAErE,OAAO;AACT"}
|
package/dist/hashing-utils.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as StorageSort, n as PreserveEmptyPredicate } from "./canonicalization-
|
|
1
|
+
import { i as StorageSort, n as PreserveEmptyPredicate } from "./canonicalization-BqYzAeWE.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/canonicalization-path-match.d.ts
|
|
4
4
|
type PathSegment = string | '*' | readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hashing-utils.d.mts","names":[],"sources":["../src/canonicalization-path-match.ts","../src/canonicalization-storage-sort.ts"],"mappings":";;;KAEY,WAAA;AAAA,KAEA,WAAA,YAAuB,WAAW;AAAA,iBAE9B,kBAAA,CAAmB,IAAA,qBAAyB,OAAA,EAAS,WAAW;AAAA,iBAiChE,4BAAA,CACd,QAAA,WAAmB,WAAA,KAClB,sBAAsB;;;KCvCb,aAAA;AAAA,UAEK,oBAAA;EAAA,SACN,IAAA,WAAe,aAAW;EAAA,SAC1B,SAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"hashing-utils.d.mts","names":[],"sources":["../src/canonicalization-path-match.ts","../src/canonicalization-storage-sort.ts"],"mappings":";;;KAEY,WAAA;AAAA,KAEA,WAAA,YAAuB,WAAW;AAAA,iBAE9B,kBAAA,CAAmB,IAAA,qBAAyB,OAAA,EAAS,WAAW;AAAA,iBAiChE,4BAAA,CACd,QAAA,WAAmB,WAAA,KAClB,sBAAsB;;;KCvCb,aAAA;AAAA,UAEK,oBAAA;EAAA,SACN,IAAA,WAAe,aAAW;EAAA,SAC1B,SAAA;AAAA;AAAA,iBAcK,qBAAA,CAAsB,CAAA,WAAY,CAAU;AAAA,iBA2D5C,iBAAA,CACd,OAAA,WAAkB,oBAAA,IAClB,OAAA,IAAU,CAAA,WAAY,CAAA,uBACrB,WAAW"}
|
package/dist/hashing-utils.mjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { n as matchesPathPattern, t as createPreserveEmptyPredicate } from "./canonicalization-path-match-
|
|
1
|
+
import { n as matchesPathPattern, t as createPreserveEmptyPredicate } from "./canonicalization-path-match-CNgHuwM_.mjs";
|
|
2
2
|
//#region src/canonicalization-storage-sort.ts
|
|
3
3
|
function isPlainRecord(value) {
|
|
4
4
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
5
|
}
|
|
6
|
+
function compareCodeUnits(a, b) {
|
|
7
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
8
|
+
}
|
|
6
9
|
function compareByNameProperty(a, b) {
|
|
7
|
-
|
|
8
|
-
const nameB = isPlainRecord(b) && typeof b["name"] === "string" ? b["name"] : "";
|
|
9
|
-
return nameA.localeCompare(nameB);
|
|
10
|
+
return compareCodeUnits(isPlainRecord(a) && typeof a["name"] === "string" ? a["name"] : "", isPlainRecord(b) && typeof b["name"] === "string" ? b["name"] : "");
|
|
10
11
|
}
|
|
11
12
|
function sortArrayKeysOnRecord(record, arrayKeys, compare) {
|
|
12
13
|
const sorted = { ...record };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hashing-utils.mjs","names":[],"sources":["../src/canonicalization-storage-sort.ts"],"sourcesContent":["import type { StorageSort } from './canonicalization';\n\nexport type PathSegment = string | '*';\n\nexport interface NamedArraySortTarget {\n readonly path: readonly PathSegment[];\n readonly arrayKeys: readonly string[];\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function compareByNameProperty(a: unknown, b: unknown): number {\n const nameA = isPlainRecord(a) && typeof a['name'] === 'string' ? a['name'] : '';\n const nameB = isPlainRecord(b) && typeof b['name'] === 'string' ? b['name'] : '';\n return nameA
|
|
1
|
+
{"version":3,"file":"hashing-utils.mjs","names":[],"sources":["../src/canonicalization-storage-sort.ts"],"sourcesContent":["import type { StorageSort } from './canonicalization';\n\nexport type PathSegment = string | '*';\n\nexport interface NamedArraySortTarget {\n readonly path: readonly PathSegment[];\n readonly arrayKeys: readonly string[];\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n// Order by UTF-16 code unit, not locale collation: canonicalization feeds\n// storageHash, which must be byte-identical across hosts, and locale\n// collation (localeCompare/Intl) varies by the engine's ICU build.\nfunction compareCodeUnits(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nexport function compareByNameProperty(a: unknown, b: unknown): number {\n const nameA = isPlainRecord(a) && typeof a['name'] === 'string' ? a['name'] : '';\n const nameB = isPlainRecord(b) && typeof b['name'] === 'string' ? b['name'] : '';\n return compareCodeUnits(nameA, nameB);\n}\n\nfunction sortArrayKeysOnRecord(\n record: Record<string, unknown>,\n arrayKeys: readonly string[],\n compare: (a: unknown, b: unknown) => number,\n): Record<string, unknown> {\n const sorted: Record<string, unknown> = { ...record };\n for (const key of arrayKeys) {\n const value = record[key];\n if (Array.isArray(value)) {\n sorted[key] = [...value].sort(compare);\n }\n }\n return sorted;\n}\n\nfunction walkAndSort(\n node: unknown,\n pathSegments: readonly PathSegment[],\n arrayKeys: readonly string[],\n compare: (a: unknown, b: unknown) => number,\n): unknown {\n if (pathSegments.length === 0) {\n if (!isPlainRecord(node)) {\n return node;\n }\n return sortArrayKeysOnRecord(node, arrayKeys, compare);\n }\n\n if (!isPlainRecord(node)) {\n return node;\n }\n\n const [head, ...rest] = pathSegments;\n if (head === undefined) {\n return node;\n }\n\n if (head === '*') {\n const sorted: Record<string, unknown> = { ...node };\n for (const key of Object.keys(node)) {\n sorted[key] = walkAndSort(node[key], rest, arrayKeys, compare);\n }\n return sorted;\n }\n\n const child = node[head];\n if (child === undefined) {\n return node;\n }\n\n return { ...node, [head]: walkAndSort(child, rest, arrayKeys, compare) };\n}\n\nexport function createStorageSort(\n targets: readonly NamedArraySortTarget[],\n compare: (a: unknown, b: unknown) => number = compareByNameProperty,\n): StorageSort {\n return (storage) => {\n if (!isPlainRecord(storage)) {\n return storage;\n }\n\n let result: unknown = storage;\n for (const target of targets) {\n result = walkAndSort(result, target.path, target.arrayKeys, compare);\n }\n return result;\n };\n}\n"],"mappings":";;AASA,SAAS,cAAc,OAAkD;CACvE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAKA,SAAS,iBAAiB,GAAW,GAAmB;CACtD,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAClC;AAEA,SAAgB,sBAAsB,GAAY,GAAoB;CAGpE,OAAO,iBAFO,cAAc,CAAC,KAAK,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU,IAChE,cAAc,CAAC,KAAK,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU,EAC1C;AACtC;AAEA,SAAS,sBACP,QACA,WACA,SACyB;CACzB,MAAM,SAAkC,EAAE,GAAG,OAAO;CACpD,KAAK,MAAM,OAAO,WAAW;EAC3B,MAAM,QAAQ,OAAO;EACrB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,OAAO;CAEzC;CACA,OAAO;AACT;AAEA,SAAS,YACP,MACA,cACA,WACA,SACS;CACT,IAAI,aAAa,WAAW,GAAG;EAC7B,IAAI,CAAC,cAAc,IAAI,GACrB,OAAO;EAET,OAAO,sBAAsB,MAAM,WAAW,OAAO;CACvD;CAEA,IAAI,CAAC,cAAc,IAAI,GACrB,OAAO;CAGT,MAAM,CAAC,MAAM,GAAG,QAAQ;CACxB,IAAI,SAAS,KAAA,GACX,OAAO;CAGT,IAAI,SAAS,KAAK;EAChB,MAAM,SAAkC,EAAE,GAAG,KAAK;EAClD,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,GAChC,OAAO,OAAO,YAAY,KAAK,MAAM,MAAM,WAAW,OAAO;EAE/D,OAAO;CACT;CAEA,MAAM,QAAQ,KAAK;CACnB,IAAI,UAAU,KAAA,GACZ,OAAO;CAGT,OAAO;EAAE,GAAG;GAAO,OAAO,YAAY,OAAO,MAAM,WAAW,OAAO;CAAE;AACzE;AAEA,SAAgB,kBACd,SACA,UAA8C,uBACjC;CACb,QAAQ,YAAY;EAClB,IAAI,CAAC,cAAc,OAAO,GACxB,OAAO;EAGT,IAAI,SAAkB;EACtB,KAAK,MAAM,UAAU,SACnB,SAAS,YAAY,QAAQ,OAAO,MAAM,OAAO,WAAW,OAAO;EAErE,OAAO;CACT;AACF"}
|
package/dist/hashing.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as canonicalizeContract, i as StorageSort, n as PreserveEmptyPredicate, o as canonicalizeContractToObject, r as SerializeContract, t as CanonicalizeContractOptions } from "./canonicalization-
|
|
1
|
+
import { K as ProfileHashBase, P as ExecutionHashBase, X as StorageHashBase } from "./domain-envelope-DKOnhO5d.mjs";
|
|
2
|
+
import { a as canonicalizeContract, i as StorageSort, n as PreserveEmptyPredicate, o as canonicalizeContractToObject, r as SerializeContract, t as CanonicalizeContractOptions } from "./canonicalization-BqYzAeWE.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/hashing.d.ts
|
|
5
5
|
type ComputeStorageHashArgs = {
|
package/dist/hashing.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hashing.d.mts","names":[],"sources":["../src/hashing.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"hashing.d.mts","names":[],"sources":["../src/hashing.ts"],"mappings":";;;;KA4EY,sBAAA;EACV,MAAA;EACA,YAAA;EACA,OAAA,EAAS,MAAA;EAAA,SACA,mBAAA,GAAsB,sBAAA;EAAA,SACtB,WAAA,GAAc,WAAA;AAAA;AAAA,iBAGT,kBAAA,CAAmB,IAAA,EAAM,sBAAA,GAAyB,eAAe;AAAA,iBAMjE,oBAAA,CAAqB,IAAA;EACnC,MAAA;EACA,YAAA;EACA,SAAA,EAAW,MAAA;AAAA,IACT,iBAAiB;AAAA,iBAML,kBAAA,CAAmB,IAAA;EACjC,MAAA;EACA,YAAA;EACA,YAAA,EAAc,MAAA,SAAe,MAAA;AAAA,IAC3B,eAAA"}
|
package/dist/hashing.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { n as matchesPathPattern } from "./canonicalization-path-match-
|
|
1
|
+
import { n as matchesPathPattern } from "./canonicalization-path-match-CNgHuwM_.mjs";
|
|
2
|
+
import { blindCast, castAs } from "@prisma-next/utils/casts";
|
|
2
3
|
import { isArrayEqual } from "@prisma-next/utils/array-equal";
|
|
3
4
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
4
5
|
import { createHash } from "node:crypto";
|
|
@@ -30,6 +31,12 @@ const DOMAIN_MODEL_STORAGE_PATTERN = [
|
|
|
30
31
|
"*",
|
|
31
32
|
"storage"
|
|
32
33
|
];
|
|
34
|
+
const STORAGE_NAMESPACE_ENTRIES_PATTERN = [
|
|
35
|
+
"storage",
|
|
36
|
+
"namespaces",
|
|
37
|
+
"*",
|
|
38
|
+
"entries"
|
|
39
|
+
];
|
|
33
40
|
const TOP_LEVEL_ORDER = [
|
|
34
41
|
"schemaVersion",
|
|
35
42
|
"canonicalVersion",
|
|
@@ -42,6 +49,7 @@ const TOP_LEVEL_ORDER = [
|
|
|
42
49
|
"execution",
|
|
43
50
|
"capabilities",
|
|
44
51
|
"extensionPacks",
|
|
52
|
+
"defaultControlPolicy",
|
|
45
53
|
"meta"
|
|
46
54
|
];
|
|
47
55
|
function isDefaultValue(value) {
|
|
@@ -65,7 +73,7 @@ function omitDefaults(obj, path, shouldPreserveEmpty) {
|
|
|
65
73
|
const isDomainNamespaceSlot = matchesPathPattern(currentPath, DOMAIN_NAMESPACE_SLOT_PATTERN);
|
|
66
74
|
const isRequiredDomainModels = matchesPathPattern(currentPath, DOMAIN_MODELS_CONTAINER_PATTERN);
|
|
67
75
|
const isRequiredStorageNamespaces = isArrayEqual(currentPath, ["storage", "namespaces"]);
|
|
68
|
-
const
|
|
76
|
+
const isStorageNamespaceEntries = matchesPathPattern(currentPath, STORAGE_NAMESPACE_ENTRIES_PATTERN);
|
|
69
77
|
const isRequiredRoots = isArrayEqual(currentPath, ["roots"]);
|
|
70
78
|
const isRequiredExtensionPacks = isArrayEqual(currentPath, ["extensionPacks"]);
|
|
71
79
|
const isRequiredCapabilities = isArrayEqual(currentPath, ["capabilities"]);
|
|
@@ -80,7 +88,7 @@ function omitDefaults(obj, path, shouldPreserveEmpty) {
|
|
|
80
88
|
const isModelStorage = matchesPathPattern(currentPath, DOMAIN_MODEL_STORAGE_PATTERN);
|
|
81
89
|
const isNullableField = key === "nullable";
|
|
82
90
|
const isFamilyPreserved = shouldPreserveEmpty?.(currentPath) ?? false;
|
|
83
|
-
if (!isRequiredDomainNamespaces && !isDomainNamespaceSlot && !isRequiredDomainModels && !isRequiredStorageNamespaces && !
|
|
91
|
+
if (!isRequiredDomainNamespaces && !isDomainNamespaceSlot && !isRequiredDomainModels && !isRequiredStorageNamespaces && !isStorageNamespaceEntries && !isRequiredRoots && !isRequiredExtensionPacks && !isRequiredCapabilities && !isRequiredMeta && !isRequiredExecutionDefaults && !isExtensionNamespace && !isModelRelations && !isModelStorage && !isNullableField && !isFamilyPreserved) continue;
|
|
84
92
|
}
|
|
85
93
|
result[key] = omitDefaults(value, currentPath, shouldPreserveEmpty);
|
|
86
94
|
}
|
|
@@ -122,6 +130,7 @@ function canonicalizeContractToObject(contract, options) {
|
|
|
122
130
|
...ifDefined("execution", serialized["execution"]),
|
|
123
131
|
extensionPacks: serialized["extensionPacks"],
|
|
124
132
|
capabilities: serialized["capabilities"],
|
|
133
|
+
...ifDefined("defaultControlPolicy", serialized["defaultControlPolicy"]),
|
|
125
134
|
meta: serialized["meta"]
|
|
126
135
|
}, [], options.shouldPreserveEmpty);
|
|
127
136
|
return orderTopLevel(sortObjectKeys(options.sortStorage ? {
|
|
@@ -135,6 +144,23 @@ function canonicalizeContract(contract, options) {
|
|
|
135
144
|
//#endregion
|
|
136
145
|
//#region src/hashing.ts
|
|
137
146
|
const SCHEMA_VERSION = "1";
|
|
147
|
+
function isPlainRecord(value) {
|
|
148
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
149
|
+
}
|
|
150
|
+
function omitNamespaceKindsForHash(storage) {
|
|
151
|
+
if (!isPlainRecord(storage)) return storage;
|
|
152
|
+
const namespaces = storage["namespaces"];
|
|
153
|
+
if (!isPlainRecord(namespaces)) return storage;
|
|
154
|
+
const stripped = {};
|
|
155
|
+
for (const [nsId, ns] of Object.entries(namespaces)) if (isPlainRecord(ns)) {
|
|
156
|
+
const { kind: _kind, ...rest } = ns;
|
|
157
|
+
stripped[nsId] = rest;
|
|
158
|
+
} else stripped[nsId] = ns;
|
|
159
|
+
return {
|
|
160
|
+
...storage,
|
|
161
|
+
namespaces: stripped
|
|
162
|
+
};
|
|
163
|
+
}
|
|
138
164
|
function sha256(content) {
|
|
139
165
|
const hash = createHash("sha256");
|
|
140
166
|
hash.update(content);
|
|
@@ -142,33 +168,34 @@ function sha256(content) {
|
|
|
142
168
|
}
|
|
143
169
|
function hashContract(section) {
|
|
144
170
|
const { shouldPreserveEmpty, sortStorage, ...sectionData } = section;
|
|
145
|
-
|
|
171
|
+
const storageForHash = omitNamespaceKindsForHash(sectionData["storage"] ?? {});
|
|
172
|
+
return canonicalizeContract(blindCast({
|
|
146
173
|
targetFamily: sectionData["targetFamily"],
|
|
147
174
|
target: sectionData["target"],
|
|
148
175
|
roots: {},
|
|
149
176
|
domain: { namespaces: {} },
|
|
150
|
-
storage: sectionData["storage"] ?? {},
|
|
151
177
|
execution: sectionData["execution"],
|
|
152
178
|
extensionPacks: {},
|
|
153
179
|
capabilities: sectionData["capabilities"] ?? {},
|
|
154
180
|
meta: {},
|
|
155
181
|
profileHash: "",
|
|
156
|
-
...sectionData
|
|
157
|
-
|
|
182
|
+
...sectionData,
|
|
183
|
+
storage: storageForHash
|
|
184
|
+
}), {
|
|
158
185
|
schemaVersion: SCHEMA_VERSION,
|
|
159
|
-
serializeContract: (c) => JSON.parse(JSON.stringify(c)),
|
|
186
|
+
serializeContract: (c) => castAs(JSON.parse(JSON.stringify(c))),
|
|
160
187
|
...ifDefined("shouldPreserveEmpty", shouldPreserveEmpty),
|
|
161
188
|
...ifDefined("sortStorage", sortStorage)
|
|
162
189
|
});
|
|
163
190
|
}
|
|
164
191
|
function computeStorageHash(args) {
|
|
165
|
-
return sha256(hashContract(args));
|
|
192
|
+
return blindCast(sha256(hashContract(args)));
|
|
166
193
|
}
|
|
167
194
|
function computeExecutionHash(args) {
|
|
168
|
-
return sha256(hashContract(args));
|
|
195
|
+
return blindCast(sha256(hashContract(args)));
|
|
169
196
|
}
|
|
170
197
|
function computeProfileHash(args) {
|
|
171
|
-
return sha256(hashContract(args));
|
|
198
|
+
return blindCast(sha256(hashContract(args)));
|
|
172
199
|
}
|
|
173
200
|
//#endregion
|
|
174
201
|
export { canonicalizeContract, canonicalizeContractToObject, computeExecutionHash, computeProfileHash, computeStorageHash };
|
package/dist/hashing.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hashing.mjs","names":[],"sources":["../src/canonicalization.ts","../src/hashing.ts"],"sourcesContent":["import { isArrayEqual } from '@prisma-next/utils/array-equal';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { matchesPathPattern, type PathPattern } from './canonicalization-path-match';\nimport type { Contract } from './contract-types';\n\n/**\n * Per-target contract serializer hook. The framework canonicalizer uses\n * this to convert an in-memory contract (which may carry class-instance\n * IR nodes whose runtime-only fields must not appear in the on-disk\n * envelope) into a plain JsonObject before applying the family-agnostic\n * canonical-key ordering / default-omission / sort steps. Targets whose\n * contract is JSON-clean by construction return the contract unchanged.\n */\nexport type SerializeContract = (contract: Contract) => JsonObject;\n\n/**\n * Family-contributed predicate for the default-omission walk. Called when\n * a value at `path` is a default (empty object/array or `false`); if this\n * returns `true` the value is kept rather than stripped.\n *\n * The framework only calls the predicate inside the `isDefaultValue` branch,\n * so there is no need to guard against non-default values.\n */\nexport type PreserveEmptyPredicate = (path: readonly string[]) => boolean;\n\n/**\n * Family-contributed storage sort. Applied to the serialized `storage`\n * subtree after the default-omission walk; the result replaces the\n * `storage` field before the final key sort. Use to establish a\n * deterministic order for storage arrays (indexes, uniques) that the\n * family-agnostic `sortObjectKeys` pass cannot handle.\n */\nexport type StorageSort = (storage: unknown) => unknown;\n\nconst DOMAIN_NAMESPACE_SLOT_PATTERN = ['domain', 'namespaces', '*'] as const satisfies PathPattern;\nconst DOMAIN_MODELS_CONTAINER_PATTERN = [\n 'domain',\n 'namespaces',\n '*',\n 'models',\n] as const satisfies PathPattern;\nconst DOMAIN_MODEL_RELATIONS_PATTERN = [\n 'domain',\n 'namespaces',\n '*',\n 'models',\n '*',\n 'relations',\n] as const satisfies PathPattern;\nconst DOMAIN_MODEL_STORAGE_PATTERN = [\n 'domain',\n 'namespaces',\n '*',\n 'models',\n '*',\n 'storage',\n] as const satisfies PathPattern;\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'profileHash',\n 'roots',\n 'domain',\n 'storage',\n 'execution',\n 'capabilities',\n 'extensionPacks',\n 'meta',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(\n obj: unknown,\n path: readonly string[],\n shouldPreserveEmpty: PreserveEmptyPredicate | undefined,\n): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path, shouldPreserveEmpty));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if ((key === 'onDelete' || key === 'onUpdate') && value === 'noAction') {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredDomainNamespaces = isArrayEqual(currentPath, ['domain', 'namespaces']);\n const isDomainNamespaceSlot = matchesPathPattern(currentPath, DOMAIN_NAMESPACE_SLOT_PATTERN);\n const isRequiredDomainModels = matchesPathPattern(\n currentPath,\n DOMAIN_MODELS_CONTAINER_PATTERN,\n );\n const isRequiredStorageNamespaces = isArrayEqual(currentPath, ['storage', 'namespaces']);\n const isStorageNamespaceSlot =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[1]], ['storage', 'namespaces']);\n const isRequiredRoots = isArrayEqual(currentPath, ['roots']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredExecutionDefaults = isArrayEqual(currentPath, [\n 'execution',\n 'mutations',\n 'defaults',\n ]);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations = matchesPathPattern(currentPath, DOMAIN_MODEL_RELATIONS_PATTERN);\n const isModelStorage = matchesPathPattern(currentPath, DOMAIN_MODEL_STORAGE_PATTERN);\n\n const isNullableField = key === 'nullable';\n\n const isFamilyPreserved = shouldPreserveEmpty?.(currentPath) ?? false;\n\n if (\n !isRequiredDomainNamespaces &&\n !isDomainNamespaceSlot &&\n !isRequiredDomainModels &&\n !isRequiredStorageNamespaces &&\n !isStorageNamespaceSlot &&\n !isRequiredRoots &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredExecutionDefaults &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isModelStorage &&\n !isNullableField &&\n !isFamilyPreserved\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath, shouldPreserveEmpty);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\nexport function orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport interface CanonicalizeContractOptions {\n readonly schemaVersion?: string;\n /**\n * Per-target hook that converts the in-memory contract (which may\n * carry class-instance IR nodes) into a plain JsonObject before the\n * family-agnostic canonicalization steps run.\n *\n * Routing through the hook is what lets each target decide which\n * fields appear in the on-disk envelope; runtime-only class API\n * fields stay invisible to the canonicalization walk by virtue of\n * the per-target serializer not putting them in the JSON shape.\n */\n readonly serializeContract: SerializeContract;\n /**\n * Family-contributed preserve-empty predicate. When the walk encounters a\n * default value (empty object/array or `false`) at `path`, calling this\n * with the full path allows the family to veto the omission. If absent,\n * only the framework's family-agnostic required-slot rules apply.\n */\n readonly shouldPreserveEmpty?: PreserveEmptyPredicate;\n /**\n * Family-contributed storage sort. Applied to the serialized `storage`\n * subtree after the default-omission walk, before the final key sort.\n * SQL family uses this to impose a deterministic order on `indexes` and\n * `uniques` arrays within each namespace table. Families that require no\n * special storage ordering omit this hook.\n */\n readonly sortStorage?: StorageSort;\n}\n\n/**\n * Object-form variant of {@link canonicalizeContract}. Exported because the\n * emitter writes the canonical contract through a separate JSON-stringify\n * pass and consumes the structured object directly.\n */\nexport function canonicalizeContractToObject(\n contract: Contract,\n options: CanonicalizeContractOptions,\n): Record<string, unknown> {\n const serialized = options.serializeContract(contract);\n const normalized: Record<string, unknown> = {\n ...ifDefined('schemaVersion', options.schemaVersion),\n targetFamily: serialized['targetFamily'],\n target: serialized['target'],\n profileHash: serialized['profileHash'],\n roots: serialized['roots'],\n domain: serialized['domain'],\n storage: serialized['storage'],\n ...ifDefined('execution', serialized['execution']),\n extensionPacks: serialized['extensionPacks'],\n capabilities: serialized['capabilities'],\n meta: serialized['meta'],\n };\n const withDefaultsOmitted = omitDefaults(normalized, [], options.shouldPreserveEmpty) as Record<\n string,\n unknown\n >;\n const withSortedStorage = options.sortStorage\n ? { ...withDefaultsOmitted, storage: options.sortStorage(withDefaultsOmitted['storage']) }\n : withDefaultsOmitted;\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n return orderTopLevel(withSortedKeys);\n}\n\nexport function canonicalizeContract(\n contract: Contract,\n options: CanonicalizeContractOptions,\n): string {\n return JSON.stringify(canonicalizeContractToObject(contract, options), null, 2);\n}\n","import { createHash } from 'node:crypto';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport {\n canonicalizeContract,\n type PreserveEmptyPredicate,\n type StorageSort,\n} from './canonicalization';\nimport type { Contract } from './contract-types';\nimport type { ExecutionHashBase, ProfileHashBase, StorageHashBase } from './types';\n\nconst SCHEMA_VERSION = '1';\n\nfunction sha256(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\ntype HashContractSection = Record<string, unknown> & {\n readonly shouldPreserveEmpty?: PreserveEmptyPredicate;\n readonly sortStorage?: StorageSort;\n};\n\nfunction hashContract(section: HashContractSection): string {\n const { shouldPreserveEmpty, sortStorage, ...sectionData } = section;\n // Blind cast: the synthesised object is a hash-only stand-in\n // — never returned to callers, never executed as a Contract.\n // `canonicalizeContract` only walks the storage / execution /\n // capabilities slices, all of which are populated above, so the\n // missing precise Contract typing on the other slots is\n // immaterial for the hash result.\n const contract = {\n targetFamily: sectionData['targetFamily'],\n target: sectionData['target'],\n roots: {},\n domain: { namespaces: {} },\n storage: sectionData['storage'] ?? {},\n execution: sectionData['execution'],\n extensionPacks: {},\n capabilities: sectionData['capabilities'] ?? {},\n meta: {},\n profileHash: '',\n ...sectionData,\n } as unknown as Contract;\n return canonicalizeContract(contract, {\n schemaVersion: SCHEMA_VERSION,\n serializeContract: (c) => JSON.parse(JSON.stringify(c)) as JsonObject,\n ...ifDefined('shouldPreserveEmpty', shouldPreserveEmpty),\n ...ifDefined('sortStorage', sortStorage),\n });\n}\n\nexport type ComputeStorageHashArgs = {\n target: string;\n targetFamily: string;\n storage: Record<string, unknown>;\n readonly shouldPreserveEmpty?: PreserveEmptyPredicate;\n readonly sortStorage?: StorageSort;\n};\n\nexport function computeStorageHash(args: ComputeStorageHashArgs): StorageHashBase<string> {\n return sha256(hashContract(args)) as StorageHashBase<string>;\n}\n\nexport function computeExecutionHash(args: {\n target: string;\n targetFamily: string;\n execution: Record<string, unknown>;\n}): ExecutionHashBase<string> {\n return sha256(hashContract(args)) as ExecutionHashBase<string>;\n}\n\nexport function computeProfileHash(args: {\n target: string;\n targetFamily: string;\n capabilities: Record<string, Record<string, boolean>>;\n}): ProfileHashBase<string> {\n return sha256(hashContract(args)) as ProfileHashBase<string>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hashing.mjs","names":[],"sources":["../src/canonicalization.ts","../src/hashing.ts"],"sourcesContent":["import { isArrayEqual } from '@prisma-next/utils/array-equal';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { matchesPathPattern, type PathPattern } from './canonicalization-path-match';\nimport type { Contract } from './contract-types';\n\n/**\n * Per-target contract serializer hook. The framework canonicalizer uses\n * this to convert an in-memory contract (which may carry class-instance\n * IR nodes whose runtime-only fields must not appear in the on-disk\n * envelope) into a plain JsonObject before applying the family-agnostic\n * canonical-key ordering / default-omission / sort steps. Targets whose\n * contract is JSON-clean by construction return the contract unchanged.\n */\nexport type SerializeContract = (contract: Contract) => JsonObject;\n\n/**\n * Family-contributed predicate for the default-omission walk. Called when\n * a value at `path` is a default (empty object/array or `false`); if this\n * returns `true` the value is kept rather than stripped.\n *\n * The framework only calls the predicate inside the `isDefaultValue` branch,\n * so there is no need to guard against non-default values.\n */\nexport type PreserveEmptyPredicate = (path: readonly string[]) => boolean;\n\n/**\n * Family-contributed storage sort. Applied to the serialized `storage`\n * subtree after the default-omission walk; the result replaces the\n * `storage` field before the final key sort. Use to establish a\n * deterministic order for storage arrays (indexes, uniques) that the\n * family-agnostic `sortObjectKeys` pass cannot handle.\n */\nexport type StorageSort = (storage: unknown) => unknown;\n\nconst DOMAIN_NAMESPACE_SLOT_PATTERN = ['domain', 'namespaces', '*'] as const satisfies PathPattern;\nconst DOMAIN_MODELS_CONTAINER_PATTERN = [\n 'domain',\n 'namespaces',\n '*',\n 'models',\n] as const satisfies PathPattern;\nconst DOMAIN_MODEL_RELATIONS_PATTERN = [\n 'domain',\n 'namespaces',\n '*',\n 'models',\n '*',\n 'relations',\n] as const satisfies PathPattern;\nconst DOMAIN_MODEL_STORAGE_PATTERN = [\n 'domain',\n 'namespaces',\n '*',\n 'models',\n '*',\n 'storage',\n] as const satisfies PathPattern;\nconst STORAGE_NAMESPACE_ENTRIES_PATTERN = [\n 'storage',\n 'namespaces',\n '*',\n 'entries',\n] as const satisfies PathPattern;\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'profileHash',\n 'roots',\n 'domain',\n 'storage',\n 'execution',\n 'capabilities',\n 'extensionPacks',\n 'defaultControlPolicy',\n 'meta',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(\n obj: unknown,\n path: readonly string[],\n shouldPreserveEmpty: PreserveEmptyPredicate | undefined,\n): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path, shouldPreserveEmpty));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if ((key === 'onDelete' || key === 'onUpdate') && value === 'noAction') {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredDomainNamespaces = isArrayEqual(currentPath, ['domain', 'namespaces']);\n const isDomainNamespaceSlot = matchesPathPattern(currentPath, DOMAIN_NAMESPACE_SLOT_PATTERN);\n const isRequiredDomainModels = matchesPathPattern(\n currentPath,\n DOMAIN_MODELS_CONTAINER_PATTERN,\n );\n const isRequiredStorageNamespaces = isArrayEqual(currentPath, ['storage', 'namespaces']);\n const isStorageNamespaceEntries = matchesPathPattern(\n currentPath,\n STORAGE_NAMESPACE_ENTRIES_PATTERN,\n );\n const isRequiredRoots = isArrayEqual(currentPath, ['roots']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredExecutionDefaults = isArrayEqual(currentPath, [\n 'execution',\n 'mutations',\n 'defaults',\n ]);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations = matchesPathPattern(currentPath, DOMAIN_MODEL_RELATIONS_PATTERN);\n const isModelStorage = matchesPathPattern(currentPath, DOMAIN_MODEL_STORAGE_PATTERN);\n\n const isNullableField = key === 'nullable';\n\n const isFamilyPreserved = shouldPreserveEmpty?.(currentPath) ?? false;\n\n if (\n !isRequiredDomainNamespaces &&\n !isDomainNamespaceSlot &&\n !isRequiredDomainModels &&\n !isRequiredStorageNamespaces &&\n !isStorageNamespaceEntries &&\n !isRequiredRoots &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredExecutionDefaults &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isModelStorage &&\n !isNullableField &&\n !isFamilyPreserved\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath, shouldPreserveEmpty);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\nexport function orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport interface CanonicalizeContractOptions {\n readonly schemaVersion?: string;\n /**\n * Per-target hook that converts the in-memory contract (which may\n * carry class-instance IR nodes) into a plain JsonObject before the\n * family-agnostic canonicalization steps run.\n *\n * Routing through the hook is what lets each target decide which\n * fields appear in the on-disk envelope; runtime-only class API\n * fields stay invisible to the canonicalization walk by virtue of\n * the per-target serializer not putting them in the JSON shape.\n */\n readonly serializeContract: SerializeContract;\n /**\n * Family-contributed preserve-empty predicate. When the walk encounters a\n * default value (empty object/array or `false`) at `path`, calling this\n * with the full path allows the family to veto the omission. If absent,\n * only the framework's family-agnostic required-slot rules apply.\n */\n readonly shouldPreserveEmpty?: PreserveEmptyPredicate;\n /**\n * Family-contributed storage sort. Applied to the serialized `storage`\n * subtree after the default-omission walk, before the final key sort.\n * SQL family uses this to impose a deterministic order on `indexes` and\n * `uniques` arrays within each namespace table. Families that require no\n * special storage ordering omit this hook.\n */\n readonly sortStorage?: StorageSort;\n}\n\n/**\n * Object-form variant of {@link canonicalizeContract}. Exported because the\n * emitter writes the canonical contract through a separate JSON-stringify\n * pass and consumes the structured object directly.\n */\nexport function canonicalizeContractToObject(\n contract: Contract,\n options: CanonicalizeContractOptions,\n): Record<string, unknown> {\n const serialized = options.serializeContract(contract);\n const normalized: Record<string, unknown> = {\n ...ifDefined('schemaVersion', options.schemaVersion),\n targetFamily: serialized['targetFamily'],\n target: serialized['target'],\n profileHash: serialized['profileHash'],\n roots: serialized['roots'],\n domain: serialized['domain'],\n storage: serialized['storage'],\n ...ifDefined('execution', serialized['execution']),\n extensionPacks: serialized['extensionPacks'],\n capabilities: serialized['capabilities'],\n ...ifDefined('defaultControlPolicy', serialized['defaultControlPolicy']),\n meta: serialized['meta'],\n };\n const withDefaultsOmitted = omitDefaults(normalized, [], options.shouldPreserveEmpty) as Record<\n string,\n unknown\n >;\n const withSortedStorage = options.sortStorage\n ? { ...withDefaultsOmitted, storage: options.sortStorage(withDefaultsOmitted['storage']) }\n : withDefaultsOmitted;\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n return orderTopLevel(withSortedKeys);\n}\n\nexport function canonicalizeContract(\n contract: Contract,\n options: CanonicalizeContractOptions,\n): string {\n return JSON.stringify(canonicalizeContractToObject(contract, options), null, 2);\n}\n","import { createHash } from 'node:crypto';\nimport { blindCast, castAs } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport {\n canonicalizeContract,\n type PreserveEmptyPredicate,\n type StorageSort,\n} from './canonicalization';\nimport type { Contract } from './contract-types';\nimport type { ExecutionHashBase, ProfileHashBase, StorageHashBase } from './types';\n\nconst SCHEMA_VERSION = '1';\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n// Storage hashes fingerprint table/column layout, not which target pack emitted a\n// namespace. Persisted contract.json carries namespace `kind` discriminators;\n// authoring-time hashes never included them (IR `kind` is non-enumerable).\nfunction omitNamespaceKindsForHash(storage: unknown): unknown {\n if (!isPlainRecord(storage)) {\n return storage;\n }\n const namespaces = storage['namespaces'];\n if (!isPlainRecord(namespaces)) {\n return storage;\n }\n const stripped: Record<string, unknown> = {};\n for (const [nsId, ns] of Object.entries(namespaces)) {\n if (isPlainRecord(ns)) {\n const { kind: _kind, ...rest } = ns;\n stripped[nsId] = rest;\n } else {\n stripped[nsId] = ns;\n }\n }\n return { ...storage, namespaces: stripped };\n}\n\nfunction sha256(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\ntype HashContractSection = Record<string, unknown> & {\n readonly shouldPreserveEmpty?: PreserveEmptyPredicate;\n readonly sortStorage?: StorageSort;\n};\n\nfunction hashContract(section: HashContractSection): string {\n const { shouldPreserveEmpty, sortStorage, ...sectionData } = section;\n const storageForHash = omitNamespaceKindsForHash(sectionData['storage'] ?? {});\n const contract = blindCast<Contract, 'hash-only partial contract for canonicalizeContract'>({\n targetFamily: sectionData['targetFamily'],\n target: sectionData['target'],\n roots: {},\n domain: { namespaces: {} },\n execution: sectionData['execution'],\n extensionPacks: {},\n capabilities: sectionData['capabilities'] ?? {},\n meta: {},\n profileHash: '',\n ...sectionData,\n storage: storageForHash,\n });\n return canonicalizeContract(contract, {\n schemaVersion: SCHEMA_VERSION,\n serializeContract: (c) => castAs<JsonObject>(JSON.parse(JSON.stringify(c))),\n ...ifDefined('shouldPreserveEmpty', shouldPreserveEmpty),\n ...ifDefined('sortStorage', sortStorage),\n });\n}\n\nexport type ComputeStorageHashArgs = {\n target: string;\n targetFamily: string;\n storage: Record<string, unknown>;\n readonly shouldPreserveEmpty?: PreserveEmptyPredicate;\n readonly sortStorage?: StorageSort;\n};\n\nexport function computeStorageHash(args: ComputeStorageHashArgs): StorageHashBase<string> {\n return blindCast<StorageHashBase<string>, 'sha256 digest of canonicalized storage'>(\n sha256(hashContract(args)),\n );\n}\n\nexport function computeExecutionHash(args: {\n target: string;\n targetFamily: string;\n execution: Record<string, unknown>;\n}): ExecutionHashBase<string> {\n return blindCast<ExecutionHashBase<string>, 'sha256 digest of canonicalized execution'>(\n sha256(hashContract(args)),\n );\n}\n\nexport function computeProfileHash(args: {\n target: string;\n targetFamily: string;\n capabilities: Record<string, Record<string, boolean>>;\n}): ProfileHashBase<string> {\n return blindCast<ProfileHashBase<string>, 'sha256 digest of canonicalized profile'>(\n sha256(hashContract(args)),\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace-id-
|
|
1
|
+
{"version":3,"file":"namespace-id-CUxYd4KL.mjs","names":[],"sources":["../src/namespace-id.ts"],"sourcesContent":["import { blindCast } from '@prisma-next/utils/casts';\n\nexport type NamespaceId = string & { readonly __brand: 'NamespaceId' };\n\nexport function asNamespaceId(value: string): NamespaceId {\n return blindCast<\n NamespaceId,\n 'NamespaceId is a compile-time-only brand on string; this factory is the sole assertion site'\n >(value);\n}\n"],"mappings":";;AAIA,SAAgB,cAAc,OAA4B;CACxD,OAAO,UAGL,KAAK;AACT"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/resolve-domain-model.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a bare domain model name to its namespace coordinate and model IR by
|
|
4
|
+
* scanning the contract's namespaces. For the single-namespace contracts in
|
|
5
|
+
* scope the scan is exact; cross-namespace bare-name collisions are selected
|
|
6
|
+
* explicitly (TML-2550).
|
|
7
|
+
*/
|
|
8
|
+
function resolveDomainModel(domain, modelName) {
|
|
9
|
+
for (const namespaceId of Object.keys(domain.namespaces)) {
|
|
10
|
+
const model = domain.namespaces[namespaceId]?.models[modelName];
|
|
11
|
+
if (model !== void 0) return {
|
|
12
|
+
namespaceId,
|
|
13
|
+
model
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { resolveDomainModel as t };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=resolve-domain-model-BovPAsW2.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-domain-model-BovPAsW2.mjs","names":[],"sources":["../src/resolve-domain-model.ts"],"sourcesContent":["import type { ApplicationDomain } from './domain-envelope';\nimport type { ContractModelBase } from './domain-types';\n\nexport interface ResolvedDomainModel {\n readonly namespaceId: string;\n readonly model: ContractModelBase;\n}\n\n/**\n * Resolve a bare domain model name to its namespace coordinate and model IR by\n * scanning the contract's namespaces. For the single-namespace contracts in\n * scope the scan is exact; cross-namespace bare-name collisions are selected\n * explicitly (TML-2550).\n */\nexport function resolveDomainModel(\n domain: ApplicationDomain,\n modelName: string,\n): ResolvedDomainModel | undefined {\n for (const namespaceId of Object.keys(domain.namespaces)) {\n const model = domain.namespaces[namespaceId]?.models[modelName];\n if (model !== undefined) {\n return { namespaceId, model };\n }\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;AAcA,SAAgB,mBACd,QACA,WACiC;CACjC,KAAK,MAAM,eAAe,OAAO,KAAK,OAAO,UAAU,GAAG;EACxD,MAAM,QAAQ,OAAO,WAAW,YAAY,EAAE,OAAO;EACrD,IAAI,UAAU,KAAA,GACZ,OAAO;GAAE;GAAa;EAAM;CAEhC;AAGF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { d as ContractModelBase, t as ApplicationDomain } from "./domain-envelope-DKOnhO5d.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/resolve-domain-model.d.ts
|
|
4
|
+
interface ResolvedDomainModel {
|
|
5
|
+
readonly namespaceId: string;
|
|
6
|
+
readonly model: ContractModelBase;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a bare domain model name to its namespace coordinate and model IR by
|
|
10
|
+
* scanning the contract's namespaces. For the single-namespace contracts in
|
|
11
|
+
* scope the scan is exact; cross-namespace bare-name collisions are selected
|
|
12
|
+
* explicitly (TML-2550).
|
|
13
|
+
*/
|
|
14
|
+
declare function resolveDomainModel(domain: ApplicationDomain, modelName: string): ResolvedDomainModel | undefined;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { resolveDomainModel as n, ResolvedDomainModel as t };
|
|
17
|
+
//# sourceMappingURL=resolve-domain-model-CSEqpByI.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-domain-model-CSEqpByI.d.mts","names":[],"sources":["../src/resolve-domain-model.ts"],"mappings":";;;UAGiB,mBAAA;EAAA,SACN,WAAA;EAAA,SACA,KAAA,EAAO,iBAAiB;AAAA;;;;;;AAAA;iBASnB,kBAAA,CACd,MAAA,EAAQ,iBAAA,EACR,SAAA,WACC,mBAAmB"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
import { r as
|
|
2
|
-
import { C as UnionFieldType, D as
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { a as ControlPolicy, i as ContractValueObjectDefinitions, n as ContractExecutionSection, o as effectiveControlPolicy, r as ContractModelDefinitions, t as Contract } from "./contract-types-CtIh62PH.mjs";
|
|
2
|
+
import { $ as executionHash, A as ColumnDefaultLiteralValue, B as FieldType, C as UnionFieldType, D as Brand, E as $, F as ExecutionMutationDefault, G as PlanMeta, H as JsonPrimitive, I as ExecutionMutationDefaultPhases, J as StorageBase, K as ProfileHashBase, L as ExecutionMutationDefaultValue, M as DocCollection, N as DocIndex, O as ColumnDefault, P as ExecutionHashBase, Q as coreHash, R as ExecutionSection, S as ScalarFieldType, T as ValueSetRef, U as JsonValue, V as GeneratedValueSpec, W as LedgerEntryRecord, X as StorageHashBase, Y as StorageEntitySlot, Z as StorageNamespace, _ as ContractValueObject, a as ContractEmbedRelation, at as CrossReferenceSchema, b as ModelStorageBase, c as ContractFieldType, ct as asNamespaceId, d as ContractModelBase, et as isColumnDefault, f as ContractNonJunctionRelation, g as ContractRelationThrough, h as ContractRelationOn, i as ContractDiscriminator, it as CrossReference, j as ContractMarkerRecord, k as ColumnDefaultLiteralInputValue, l as ContractManyToManyRelation, m as ContractRelation, n as ApplicationDomainNamespace, nt as isExecutionMutationDefaultValue, o as ContractEnum, ot as crossRef, p as ContractReferenceRelation, q as Source, r as ContractWithDomain, rt as profileHash, s as ContractField, st as NamespaceId, t as ApplicationDomain, tt as isColumnDefaultLiteralInputValue, u as ContractModel, v as ContractVariantEntry, w as ValueObjectFieldType, x as ReferenceRelationKeys, y as EmbedRelationKeys, z as Expr } from "./domain-envelope-DKOnhO5d.mjs";
|
|
3
|
+
import { n as soleDomainNamespaceId, t as UNBOUND_DOMAIN_NAMESPACE_ID } from "./default-namespace-D5X_k6hJ.mjs";
|
|
4
|
+
import { r as DomainNamespaceResolutionError } from "./contract-validation-error-D7g0kmcc.mjs";
|
|
5
|
+
import { n as resolveDomainModel, t as ResolvedDomainModel } from "./resolve-domain-model-CSEqpByI.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/domain-namespace-access.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Models map for the contract's single domain namespace. Throws when the
|
|
10
|
+
* contract does not declare exactly one namespace — bare-name access is
|
|
11
|
+
* ambiguous across namespaces and must be qualified explicitly (TML-2550).
|
|
12
|
+
*/
|
|
13
|
+
declare function domainModelsAtDefaultNamespace<TModels extends Record<string, ContractModelBase>>(domain: ApplicationDomain<TModels>): TModels;
|
|
14
|
+
/**
|
|
15
|
+
* Value objects for the contract's single domain namespace, when present.
|
|
16
|
+
* Throws when the contract does not declare exactly one namespace.
|
|
17
|
+
*/
|
|
18
|
+
declare function domainValueObjectsAtDefaultNamespace<TModels extends Record<string, ContractModelBase>>(domain: ApplicationDomain<TModels>): Record<string, ContractValueObject> | undefined;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { type $, type ApplicationDomain, type ApplicationDomainNamespace, type Brand, type ColumnDefault, type ColumnDefaultLiteralInputValue, type ColumnDefaultLiteralValue, type Contract, type ContractDiscriminator, type ContractEmbedRelation, type ContractEnum, type ContractExecutionSection, type ContractField, type ContractFieldType, type ContractManyToManyRelation, type ContractMarkerRecord, type ContractModel, type ContractModelBase, type ContractModelDefinitions, type ContractNonJunctionRelation, type ContractReferenceRelation, type ContractRelation, type ContractRelationOn, type ContractRelationThrough, type ContractValueObject, type ContractValueObjectDefinitions, type ContractVariantEntry, type ContractWithDomain, type ControlPolicy, type CrossReference, CrossReferenceSchema, type DocCollection, type DocIndex, DomainNamespaceResolutionError, type EmbedRelationKeys, type ExecutionHashBase, type ExecutionMutationDefault, type ExecutionMutationDefaultPhases, type ExecutionMutationDefaultValue, type ExecutionSection, type Expr, type FieldType, type GeneratedValueSpec, type JsonPrimitive, type JsonValue, type LedgerEntryRecord, type ModelStorageBase, type NamespaceId, type PlanMeta, type ProfileHashBase, type ReferenceRelationKeys, type ResolvedDomainModel, type ScalarFieldType, type Source, type StorageBase, type StorageEntitySlot, type StorageHashBase, type StorageNamespace, UNBOUND_DOMAIN_NAMESPACE_ID, type UnionFieldType, type ValueObjectFieldType, type ValueSetRef, asNamespaceId, coreHash, crossRef, domainModelsAtDefaultNamespace, domainValueObjectsAtDefaultNamespace, effectiveControlPolicy, executionHash, isColumnDefault, isColumnDefaultLiteralInputValue, isExecutionMutationDefaultValue, profileHash, resolveDomainModel, soleDomainNamespaceId };
|
|
21
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/domain-namespace-access.ts"],"mappings":";;;;;;;;;;;;iBAUgB,8BAAA,iBAA+C,MAAA,SAAe,iBAAA,GAC5E,MAAA,EAAQ,iBAAA,CAAkB,OAAA,IACzB,OAAA;;;;;iBAea,oCAAA,iBACE,MAAA,SAAe,iBAAA,GAC/B,MAAA,EAAQ,iBAAA,CAAkB,OAAA,IAAW,MAAA,SAAe,mBAAA"}
|