@prisma-next/sql-contract-ts 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/README.md +8 -0
- package/dist/{build-contract-BCYW3_wE.mjs → build-contract-HP3IjjLv.mjs} +220 -79
- package/dist/build-contract-HP3IjjLv.mjs.map +1 -0
- package/dist/config-types.d.mts +7 -3
- package/dist/config-types.d.mts.map +1 -1
- package/dist/config-types.mjs +12 -9
- package/dist/config-types.mjs.map +1 -1
- package/dist/contract-builder.d.mts +395 -39
- package/dist/contract-builder.d.mts.map +1 -1
- package/dist/contract-builder.mjs +295 -44
- package/dist/contract-builder.mjs.map +1 -1
- package/package.json +13 -13
- package/schemas/data-contract-sql-v1.json +31 -0
- package/src/build-contract.ts +348 -102
- package/src/config-types.ts +24 -6
- package/src/contract-builder.ts +171 -21
- package/src/contract-definition.ts +57 -3
- package/src/contract-dsl.ts +346 -18
- package/src/contract-lowering.ts +188 -15
- package/src/contract-types.ts +123 -47
- package/src/enum-type.ts +306 -0
- package/src/exports/contract-builder.ts +13 -0
- package/dist/build-contract-BCYW3_wE.mjs.map +0 -1
|
@@ -1,19 +1,156 @@
|
|
|
1
|
-
import { ColumnDefault, ColumnDefaultLiteralInputValue, Contract, ContractRelation, ExecutionMutationDefaultPhases, ExecutionMutationDefaultPhases as ExecutionMutationDefaultPhases$1, ExecutionMutationDefaultValue, NamespaceId, StorageHashBase } from "@prisma-next/contract/types";
|
|
1
|
+
import { ColumnDefault, ColumnDefaultLiteralInputValue, Contract, ContractRelation, ControlPolicy, ExecutionMutationDefaultPhases, ExecutionMutationDefaultPhases as ExecutionMutationDefaultPhases$1, ExecutionMutationDefaultValue, NamespaceId, StorageHashBase } from "@prisma-next/contract/types";
|
|
2
2
|
import { EntityHelpersFromNamespace, ExtractAuthoringNamespaceFromPack, ForeignKeyDefaultsState, MergeExtensionAuthoringNamespaces } from "@prisma-next/contract-authoring";
|
|
3
|
-
import { Namespace } from "@prisma-next/framework-components/ir";
|
|
3
|
+
import { Namespace, StorageType } from "@prisma-next/framework-components/ir";
|
|
4
4
|
import { IndexTypeRegistration } from "@prisma-next/sql-contract/index-types";
|
|
5
5
|
import { ContractWithTypeMaps, Index as Index$1, PostgresEnumStorageEntry, ReferentialAction, SqlNamespaceTablesInput, SqlStorage, StorageTypeInstance, TypeMaps } from "@prisma-next/sql-contract/types";
|
|
6
6
|
import { AuthoringArgumentDescriptor, AuthoringFieldPresetDescriptor, AuthoringTypeConstructorDescriptor } from "@prisma-next/framework-components/authoring";
|
|
7
7
|
import { ExtensionPackRef, FamilyPackRef, TargetPackRef } from "@prisma-next/framework-components/components";
|
|
8
8
|
import { CodecLookup, ColumnTypeDescriptor } from "@prisma-next/framework-components/codec";
|
|
9
9
|
|
|
10
|
+
//#region src/enum-type.d.ts
|
|
11
|
+
/**
|
|
12
|
+
* A single enum member produced by `member()`. The `Name` and `Value` generics
|
|
13
|
+
* are preserved as literal types so `enumType()` can carry the ordered value
|
|
14
|
+
* tuple in its return type. `Value` is whatever the codec dictates — its type
|
|
15
|
+
* is constrained at `enumType` against the codec's input type, not here.
|
|
16
|
+
*/
|
|
17
|
+
interface EnumMember<Name extends string, Value> {
|
|
18
|
+
readonly name: Name;
|
|
19
|
+
readonly value: Value;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Declare an enum member. The `value` defaults to `name` when omitted. The
|
|
23
|
+
* value is an unconstrained literal here; `enumType` constrains it against the
|
|
24
|
+
* codec's input type. Both generics are preserved as literals so downstream
|
|
25
|
+
* `enumType` carries the value union in its type; the value is serialized to its
|
|
26
|
+
* codec string form only at lowering.
|
|
27
|
+
*/
|
|
28
|
+
declare function member<const Name extends string>(name: Name): EnumMember<Name, Name>;
|
|
29
|
+
declare function member<const Name extends string, const Value>(name: Name, value: Value): EnumMember<Name, Value>;
|
|
30
|
+
type MembersToValues<Members extends readonly EnumMember<string, unknown>[]> = { readonly [K in keyof Members]: Members[K] extends EnumMember<string, infer V> ? V : never };
|
|
31
|
+
type MembersToNames<Members extends readonly EnumMember<string, unknown>[]> = { readonly [K in keyof Members]: Members[K] extends EnumMember<infer N, unknown> ? N : never };
|
|
32
|
+
type MembersAccessorMap<Members extends readonly EnumMember<string, unknown>[]> = { readonly [M in Members[number] as M['name']]: M['value'] };
|
|
33
|
+
/**
|
|
34
|
+
* Internal brand that identifies an EnumTypeHandle in the lowering pipeline.
|
|
35
|
+
* Not exported — callers only interact with `EnumTypeHandle`.
|
|
36
|
+
*/
|
|
37
|
+
declare const ENUM_TYPE_HANDLE_BRAND: unique symbol;
|
|
38
|
+
/**
|
|
39
|
+
* Authoring handle returned by `enumType()`. Carries:
|
|
40
|
+
*
|
|
41
|
+
* - The ordered literal value tuple (`.values`) and name tuple (`.names`)
|
|
42
|
+
* so downstream type-tests can assert literal preservation.
|
|
43
|
+
* - A namespaced member accessor map (`.members`) to avoid collisions with
|
|
44
|
+
* `.values` / `.has` / `.nameOf` / `.ordinalOf`.
|
|
45
|
+
* - Runtime helpers `.has()`, `.nameOf()`, `.ordinalOf()`.
|
|
46
|
+
* - Internal metadata (`enumName`, `codecId`, `nativeType`,
|
|
47
|
+
* `enumMembers`) for the lowering pipeline.
|
|
48
|
+
*
|
|
49
|
+
* The type is generic over the ordered value tuple so callers that assign
|
|
50
|
+
* `const Role = enumType(...)` retain the literal tuple on `.values`.
|
|
51
|
+
*/
|
|
52
|
+
interface EnumTypeHandle<Name extends string = string, Values extends readonly unknown[] = readonly unknown[], Names extends readonly string[] = readonly string[], MembersMap extends Record<string, unknown> = Record<string, unknown>> {
|
|
53
|
+
/** Internal brand for lowering-pipeline detection. */
|
|
54
|
+
readonly [ENUM_TYPE_HANDLE_BRAND]: true;
|
|
55
|
+
/** The enum's declared name (used as the key in domain `enum` / storage `valueSet`). */
|
|
56
|
+
readonly enumName: Name;
|
|
57
|
+
/** codecId from the codec passed to `enumType`. */
|
|
58
|
+
readonly codecId: string;
|
|
59
|
+
/** nativeType from the codec passed to `enumType`. */
|
|
60
|
+
readonly nativeType: string;
|
|
61
|
+
/** Ordered member list for lowering (name + value pairs). */
|
|
62
|
+
readonly enumMembers: readonly {
|
|
63
|
+
readonly name: string;
|
|
64
|
+
readonly value: Values[number];
|
|
65
|
+
}[];
|
|
66
|
+
/** Ordered literal value tuple. Declaration order is preserved. */
|
|
67
|
+
readonly values: Values;
|
|
68
|
+
/** Ordered literal name tuple. Declaration order is preserved. */
|
|
69
|
+
readonly names: Names;
|
|
70
|
+
/**
|
|
71
|
+
* Namespaced accessor map: `Role.members.User === 'user'`.
|
|
72
|
+
* Namespaced under `.members` to avoid collisions with `.values` / `.has`.
|
|
73
|
+
*/
|
|
74
|
+
readonly members: MembersMap;
|
|
75
|
+
/** Returns `true` if `v` is a declared member value. */
|
|
76
|
+
has(v: Values[number]): boolean;
|
|
77
|
+
/** Returns the member name for a value, or `undefined` if not found. */
|
|
78
|
+
nameOf(v: Values[number]): string | undefined;
|
|
79
|
+
/** Returns the zero-based declaration index of a value, or `-1` if not found. */
|
|
80
|
+
ordinalOf(v: Values[number]): number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* A codec typemap: codecId → `{ input, output }`, the same shape the query
|
|
84
|
+
* lanes consume (e.g. `{ 'pg/text@1': { input: string }, 'pg/int4@1': { input: number } }`).
|
|
85
|
+
* The bound `enumType` wrappers supply the target pack's typemap; the core
|
|
86
|
+
* defaults to an empty map (no codec is known), so member values stay
|
|
87
|
+
* unconstrained.
|
|
88
|
+
*/
|
|
89
|
+
type CodecTypeMap = Record<string, {
|
|
90
|
+
readonly input?: unknown;
|
|
91
|
+
}>;
|
|
92
|
+
/**
|
|
93
|
+
* The application input type the codec dictates for an enum's member values:
|
|
94
|
+
* looks `Codec['codecId']` up in the supplied codec typemap. When the codecId
|
|
95
|
+
* isn't in the map (the core's empty default, or an unknown codec) the input is
|
|
96
|
+
* unconstrained, so any member-value literal is accepted and inferred verbatim.
|
|
97
|
+
*/
|
|
98
|
+
type CodecInput<CodecTypes extends CodecTypeMap, Codec extends {
|
|
99
|
+
readonly codecId: string;
|
|
100
|
+
}> = Codec['codecId'] extends keyof CodecTypes ? CodecTypes[Codec['codecId']] extends {
|
|
101
|
+
readonly input: infer In;
|
|
102
|
+
} ? In : unknown : unknown;
|
|
103
|
+
/**
|
|
104
|
+
* Declare a domain enum for use in TS-authoring contracts.
|
|
105
|
+
*
|
|
106
|
+
* - The codec is an explicit required argument — the `codecId` and
|
|
107
|
+
* `nativeType` are taken from the passed `ColumnTypeDescriptor` (e.g.
|
|
108
|
+
* `{ codecId: 'pg/text@1', nativeType: 'text' }` from a field preset
|
|
109
|
+
* output or a direct inline object).
|
|
110
|
+
* - `const` generics on the members spread preserve the ordered literal
|
|
111
|
+
* value tuple so `Role.values` is `readonly ['user','admin']`, not
|
|
112
|
+
* `string[]`.
|
|
113
|
+
* - Well-formedness assertions at construction: non-empty member list;
|
|
114
|
+
* unique names; unique values.
|
|
115
|
+
*
|
|
116
|
+
* The returned handle wires into `field.namedType(handle)` to set
|
|
117
|
+
* `valueSet` refs on both the domain field and the storage column.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const Role = enumType('Role', { codecId: 'pg/text@1', nativeType: 'text' },
|
|
122
|
+
* member('User', 'user'),
|
|
123
|
+
* member('Admin', 'admin'),
|
|
124
|
+
* );
|
|
125
|
+
* // Role.values → readonly ['user', 'admin']
|
|
126
|
+
* // Role.members.User → 'user'
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
declare function enumType<CodecTypes extends CodecTypeMap = Record<string, never>, const Name extends string = string, const Codec extends Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'> = Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'>, const Members extends readonly [EnumMember<string, CodecInput<CodecTypes, Codec>>, ...EnumMember<string, CodecInput<CodecTypes, Codec>>[]] = readonly [EnumMember<string, CodecInput<CodecTypes, Codec>>]>(name: Name, codec: Codec, ...members: Members): EnumTypeHandle<Name, MembersToValues<[...Members]>, MembersToNames<[...Members]>, MembersAccessorMap<[...Members]>>;
|
|
130
|
+
declare function enumType(name: string, codec: Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'>, ...members: EnumMember<string, unknown>[]): EnumTypeHandle;
|
|
131
|
+
/**
|
|
132
|
+
* The signature of an `enumType` whose codec typemap is already bound — the
|
|
133
|
+
* shape a target-bound wrapper (e.g. `@prisma-next/postgres/contract-builder`)
|
|
134
|
+
* exposes. The member values are constrained to the codec's input type drawn
|
|
135
|
+
* from `CodecTypes` (so a `pg/text@1` codec rejects numeric members, etc.),
|
|
136
|
+
* while `Name`, `Codec`, and the member tuple still infer from the call.
|
|
137
|
+
*/
|
|
138
|
+
type BoundEnumType<CodecTypes extends CodecTypeMap> = <const Name extends string, const Codec extends Pick<ColumnTypeDescriptor, 'codecId' | 'nativeType'>, const Members extends readonly [EnumMember<string, CodecInput<CodecTypes, Codec>>, ...EnumMember<string, CodecInput<CodecTypes, Codec>>[]]>(name: Name, codec: Codec, ...members: Members) => EnumTypeHandle<Name, MembersToValues<[...Members]>, MembersToNames<[...Members]>, MembersAccessorMap<[...Members]>>;
|
|
139
|
+
/**
|
|
140
|
+
* Bind `enumType` to a target's codec typemap. The returned function is the
|
|
141
|
+
* same runtime `enumType`, retyped so member values are constrained to the
|
|
142
|
+
* codec's input type. Target packages call this with their pack's
|
|
143
|
+
* `ExtractCodecTypesFromPack<Pack>` to expose a codec-aware `enumType`.
|
|
144
|
+
*/
|
|
145
|
+
declare function bindEnumType<CodecTypes extends CodecTypeMap>(): BoundEnumType<CodecTypes>;
|
|
146
|
+
//#endregion
|
|
10
147
|
//#region src/contract-dsl.d.ts
|
|
11
148
|
type NamingStrategy = 'identity' | 'snake_case';
|
|
12
149
|
type NamingConfig = {
|
|
13
150
|
readonly tables?: NamingStrategy;
|
|
14
151
|
readonly columns?: NamingStrategy;
|
|
15
152
|
};
|
|
16
|
-
type NamedStorageTypeRef = string | StorageTypeInstance | PostgresEnumStorageEntry;
|
|
153
|
+
type NamedStorageTypeRef = string | StorageTypeInstance | PostgresEnumStorageEntry | EnumTypeHandle;
|
|
17
154
|
type NamedConstraintNameSpec<Name extends string = string> = {
|
|
18
155
|
readonly name: Name;
|
|
19
156
|
};
|
|
@@ -78,6 +215,13 @@ declare class ScalarFieldBuilder<State extends AnyScalarFieldState = AnyScalarFi
|
|
|
78
215
|
private readonly state;
|
|
79
216
|
readonly __state: State;
|
|
80
217
|
constructor(state: State);
|
|
218
|
+
/**
|
|
219
|
+
* Returns the physical column name when `.column(name)` was called, or
|
|
220
|
+
* `undefined` when the field uses the default (logical field name) mapping.
|
|
221
|
+
* Used by cross-space FK lowering to stamp the physical column name onto
|
|
222
|
+
* `TargetFieldRef.columnName` so FK target columns are resolved correctly.
|
|
223
|
+
*/
|
|
224
|
+
get physicalColumnName(): string | undefined;
|
|
81
225
|
optional(): ScalarFieldBuilder<State extends ScalarFieldState<infer CodecId, infer TypeRef, boolean, infer ColumnName, infer IdSpec, infer UniqueSpec> ? ScalarFieldState<CodecId, TypeRef, true, ColumnName, IdSpec, UniqueSpec> : never>;
|
|
82
226
|
column<ColumnName extends string>(name: ColumnName): ScalarFieldBuilder<State extends ScalarFieldState<infer CodecId, infer TypeRef, infer Nullable, string | undefined, infer IdSpec, infer UniqueSpec> ? ScalarFieldState<CodecId, TypeRef, Nullable, ColumnName, IdSpec, UniqueSpec> : never>;
|
|
83
227
|
default(value: ColumnDefaultLiteralInputValue | ColumnDefault): ScalarFieldBuilder<State>;
|
|
@@ -94,6 +238,7 @@ declare function generatedField<Descriptor extends ColumnTypeDescriptor>(spec: G
|
|
|
94
238
|
declare function namedTypeField<TypeRef extends string>(typeRef: TypeRef): ScalarFieldBuilder<ScalarFieldState<string, TypeRef, false, undefined>>;
|
|
95
239
|
declare function namedTypeField<TypeRef extends StorageTypeInstance>(typeRef: TypeRef): ScalarFieldBuilder<ScalarFieldState<TypeRef['codecId'], TypeRef, false, undefined>>;
|
|
96
240
|
declare function namedTypeField<TypeRef extends PostgresEnumStorageEntry>(typeRef: TypeRef): ScalarFieldBuilder<ScalarFieldState<string, TypeRef, false, undefined>>;
|
|
241
|
+
declare function namedTypeField<Handle extends EnumTypeHandle>(typeRef: Handle): ScalarFieldBuilder<ScalarFieldState<Handle['codecId'], Handle, false, undefined>>;
|
|
97
242
|
type RelationModelRefSource = 'string' | 'token' | 'lazyToken';
|
|
98
243
|
type TargetFieldRefSource = 'string' | 'token';
|
|
99
244
|
type EagerRelationModelName<ModelName extends string = string, Source extends Exclude<RelationModelRefSource, 'lazyToken'> = Exclude<RelationModelRefSource, 'lazyToken'>> = {
|
|
@@ -113,6 +258,22 @@ type BelongsToRelation<ToModel extends string = string, FromField extends string
|
|
|
113
258
|
readonly from: FromField;
|
|
114
259
|
readonly to: ToField;
|
|
115
260
|
readonly sql?: SqlSpec;
|
|
261
|
+
/**
|
|
262
|
+
* Contract-space identity of the target model. Populated when
|
|
263
|
+
* `belongsTo` receives a cross-space branded handle. Absent for
|
|
264
|
+
* local (same-space) relations.
|
|
265
|
+
*/
|
|
266
|
+
readonly spaceId?: string;
|
|
267
|
+
/**
|
|
268
|
+
* Physical table name of the cross-space target model. Only set
|
|
269
|
+
* when `spaceId` is present; read from the handle's `tableName`.
|
|
270
|
+
*/
|
|
271
|
+
readonly tableName?: string;
|
|
272
|
+
/**
|
|
273
|
+
* Namespace coordinate of the cross-space target model.
|
|
274
|
+
* Only set when `spaceId` is present.
|
|
275
|
+
*/
|
|
276
|
+
readonly namespaceId?: string;
|
|
116
277
|
};
|
|
117
278
|
type HasManyRelation<ToModel extends string = string, ByField extends string | readonly string[] = string | readonly string[]> = {
|
|
118
279
|
readonly kind: 'hasMany';
|
|
@@ -142,17 +303,58 @@ declare class RelationBuilder<State extends RelationState = AnyRelationState> {
|
|
|
142
303
|
sql<const SqlSpec extends BelongsToRelationSqlSpec>(this: State extends BelongsToRelation<string, string | readonly string[], string | readonly string[], BelongsToRelationSqlSpec | undefined> ? RelationBuilder<State> : never, spec: SqlSpec): RelationBuilder<ApplyBelongsToRelationSqlSpec<State, SqlSpec>>;
|
|
143
304
|
build(): State;
|
|
144
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* Reference to a column on the current (local) model.
|
|
308
|
+
*
|
|
309
|
+
* Source columns are always local to the contract being authored. The
|
|
310
|
+
* cross-space brand lives on `TargetFieldRef` (the target side of a foreign
|
|
311
|
+
* key), not here.
|
|
312
|
+
*/
|
|
145
313
|
type ColumnRef<FieldName extends string = string> = {
|
|
146
314
|
readonly kind: 'columnRef';
|
|
147
315
|
readonly fieldName: FieldName;
|
|
148
316
|
};
|
|
149
|
-
|
|
317
|
+
/**
|
|
318
|
+
* Reference to a field on a target model, produced by model `.refs` and
|
|
319
|
+
* `constraints.ref(modelName, fieldName)`.
|
|
320
|
+
*
|
|
321
|
+
* The `TSpaceId` phantom parameter carries the contract-space identity of the
|
|
322
|
+
* target model. Local model handles produce `TSpaceId = '<self>'`; extension
|
|
323
|
+
* handles carry the extension's `spaceId`. The brand is propagated from the
|
|
324
|
+
* parent `ContractModelBuilder` via the `spaceId?` property: absent means local
|
|
325
|
+
* (`'<self>'`), present means cross-space.
|
|
326
|
+
*/
|
|
327
|
+
type TargetFieldRef<ModelName extends string = string, FieldName extends string = string, TSpaceId extends string = string> = {
|
|
150
328
|
readonly kind: 'targetFieldRef';
|
|
151
|
-
readonly source:
|
|
329
|
+
readonly source: TargetFieldRefSource;
|
|
152
330
|
readonly modelName: ModelName;
|
|
153
331
|
readonly fieldName: FieldName;
|
|
332
|
+
/**
|
|
333
|
+
* Cross-space discriminator. When present, the referenced model lives in a
|
|
334
|
+
* different contract space identified by this value. Absent for local refs.
|
|
335
|
+
*/
|
|
336
|
+
readonly spaceId?: TSpaceId extends '<self>' ? never : TSpaceId;
|
|
337
|
+
/**
|
|
338
|
+
* Namespace id of the cross-space target model (e.g. `'auth'` for
|
|
339
|
+
* `supabase` `auth.User`). Only present for cross-space refs.
|
|
340
|
+
*/
|
|
341
|
+
readonly namespaceId?: string;
|
|
342
|
+
/**
|
|
343
|
+
* Physical table name of the cross-space target model. Only present for
|
|
344
|
+
* cross-space refs; allows the lowering path to bypass the local model
|
|
345
|
+
* registry.
|
|
346
|
+
*/
|
|
347
|
+
readonly tableName?: string;
|
|
348
|
+
/**
|
|
349
|
+
* Physical column name of the target field. Populated for cross-space refs
|
|
350
|
+
* when the extension handle's field used `.column(name)` to rename the
|
|
351
|
+
* physical column. When absent the logical `fieldName` is used as the column
|
|
352
|
+
* name. Only relevant for cross-space FK lowering — local FKs resolve column
|
|
353
|
+
* names via the local `fieldToColumn` map.
|
|
354
|
+
*/
|
|
355
|
+
readonly columnName?: string;
|
|
154
356
|
};
|
|
155
|
-
type ModelTokenRefs<ModelName extends string, Fields extends Record<string, ScalarFieldBuilder
|
|
357
|
+
type ModelTokenRefs<ModelName extends string, Fields extends Record<string, ScalarFieldBuilder>, TSpaceId extends string = '<self>'> = { readonly [K in keyof Fields]: TargetFieldRef<ModelName, K & string, TSpaceId> };
|
|
156
358
|
type ConstraintOptions<Name extends string | undefined = string | undefined> = {
|
|
157
359
|
readonly name?: Name;
|
|
158
360
|
};
|
|
@@ -198,6 +400,22 @@ type ForeignKeyConstraint<SourceFieldNames extends readonly string[] = readonly
|
|
|
198
400
|
readonly targetModel: TargetModelName;
|
|
199
401
|
readonly targetFields: TargetFieldNames;
|
|
200
402
|
readonly targetSource?: TargetFieldRefSource;
|
|
403
|
+
/**
|
|
404
|
+
* Cross-space discriminator. When present, the FK target lives in a
|
|
405
|
+
* different contract space identified by this value. Absent for local FKs.
|
|
406
|
+
*/
|
|
407
|
+
readonly targetSpaceId?: string;
|
|
408
|
+
/**
|
|
409
|
+
* Namespace coordinate of the cross-space target model. Populated when
|
|
410
|
+
* the target model handle carries a `namespace` (e.g. `auth` for supabase
|
|
411
|
+
* `auth.User`). Absent for local FKs.
|
|
412
|
+
*/
|
|
413
|
+
readonly targetNamespaceId?: string;
|
|
414
|
+
/**
|
|
415
|
+
* Table name of the cross-space target. Populated for cross-space FKs
|
|
416
|
+
* so the lowering path doesn't need a local model lookup.
|
|
417
|
+
*/
|
|
418
|
+
readonly targetTableName?: string;
|
|
201
419
|
readonly name?: Name;
|
|
202
420
|
readonly onDelete?: 'noAction' | 'restrict' | 'cascade' | 'setNull' | 'setDefault';
|
|
203
421
|
readonly onUpdate?: 'noAction' | 'restrict' | 'cascade' | 'setNull' | 'setDefault';
|
|
@@ -227,6 +445,7 @@ type ModelAttributesSpec = {
|
|
|
227
445
|
};
|
|
228
446
|
type SqlStageSpec = {
|
|
229
447
|
readonly table?: string;
|
|
448
|
+
readonly control?: ControlPolicy;
|
|
230
449
|
readonly indexes?: readonly IndexConstraint[];
|
|
231
450
|
readonly foreignKeys?: readonly ForeignKeyConstraint[];
|
|
232
451
|
};
|
|
@@ -271,7 +490,7 @@ type SqlForeignKeys<SqlSpec extends SqlStageSpec> = SqlSpec extends {
|
|
|
271
490
|
type SqlNamedObjects<SqlSpec extends SqlStageSpec> = [...SqlIndexes<SqlSpec>, ...SqlForeignKeys<SqlSpec>];
|
|
272
491
|
type ValidateSqlStageSpec<Fields extends Record<string, ScalarFieldBuilder>, AttributesSpec extends ModelAttributesSpec | undefined, SqlSpec extends SqlStageSpec> = [DuplicateLiteralNames<SqlNamedObjects<SqlSpec>>] extends [never] ? [Extract<ModelIdLiteralName<Fields, AttributesSpec>, NamedConstraintLiteralName<SqlNamedObjects<SqlSpec>[number]>>] extends [never] ? SqlSpec : never : never;
|
|
273
492
|
type ValidateAttributesStageSpec<Fields extends Record<string, ScalarFieldBuilder>, SqlSpec extends SqlStageSpec | undefined, AttributesSpec extends ModelAttributesSpec> = SqlSpec extends SqlStageSpec ? [Extract<ModelIdLiteralName<Fields, AttributesSpec>, NamedConstraintLiteralName<SqlNamedObjects<SqlSpec>[number]>>] extends [never] ? AttributesSpec : never : AttributesSpec;
|
|
274
|
-
declare class ContractModelBuilder<ModelName extends string | undefined, Fields extends Record<string, ScalarFieldBuilder>, Relations extends Record<string, AnyRelationBuilder> = Record<never, never>, AttributesSpec extends ModelAttributesSpec | undefined = undefined, SqlSpec extends SqlStageSpec | undefined = undefined, IndexTypes extends IndexTypeMap = Record<never, never
|
|
493
|
+
declare class ContractModelBuilder<ModelName extends string | undefined, Fields extends Record<string, ScalarFieldBuilder>, Relations extends Record<string, AnyRelationBuilder> = Record<never, never>, AttributesSpec extends ModelAttributesSpec | undefined = undefined, SqlSpec extends SqlStageSpec | undefined = undefined, IndexTypes extends IndexTypeMap = Record<never, never>, TSpaceId extends string = '<self>'> {
|
|
275
494
|
readonly stageOne: {
|
|
276
495
|
readonly modelName?: ModelName;
|
|
277
496
|
readonly namespace?: string;
|
|
@@ -280,23 +499,26 @@ declare class ContractModelBuilder<ModelName extends string | undefined, Fields
|
|
|
280
499
|
};
|
|
281
500
|
readonly attributesFactory?: StageInput<AttributeContext<Fields>, AttributesSpec> | undefined;
|
|
282
501
|
readonly sqlFactory?: StageInput<SqlContext<Fields, IndexTypes>, SqlSpec> | undefined;
|
|
502
|
+
readonly spaceId?: TSpaceId | undefined;
|
|
503
|
+
readonly tableName?: string | undefined;
|
|
283
504
|
readonly __name: ModelName;
|
|
284
505
|
readonly __fields: Fields;
|
|
285
506
|
readonly __relations: Relations;
|
|
286
507
|
readonly __attributes: AttributesSpec;
|
|
287
508
|
readonly __sql: SqlSpec;
|
|
288
509
|
readonly __indexTypes: IndexTypes;
|
|
289
|
-
readonly
|
|
510
|
+
readonly __spaceId: TSpaceId;
|
|
511
|
+
readonly refs: ModelName extends string ? ModelTokenRefs<ModelName, Fields, TSpaceId> : never;
|
|
290
512
|
constructor(stageOne: {
|
|
291
513
|
readonly modelName?: ModelName;
|
|
292
514
|
readonly namespace?: string;
|
|
293
515
|
readonly fields: Fields;
|
|
294
516
|
readonly relations: Relations;
|
|
295
|
-
}, attributesFactory?: StageInput<AttributeContext<Fields>, AttributesSpec> | undefined, sqlFactory?: StageInput<SqlContext<Fields, IndexTypes>, SqlSpec> | undefined);
|
|
517
|
+
}, attributesFactory?: StageInput<AttributeContext<Fields>, AttributesSpec> | undefined, sqlFactory?: StageInput<SqlContext<Fields, IndexTypes>, SqlSpec> | undefined, spaceId?: TSpaceId | undefined, tableName?: string | undefined);
|
|
296
518
|
ref<FieldName extends keyof Fields & string>(this: ModelName extends string ? ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, SqlSpec, IndexTypes> : never, fieldName: FieldName): TargetFieldRef<ModelName & string, FieldName>;
|
|
297
|
-
relations<const NextRelations extends Record<string, AnyRelationBuilder>>(relations: NextRelations): ContractModelBuilder<ModelName, Fields, Relations & NextRelations, AttributesSpec, SqlSpec, IndexTypes>;
|
|
298
|
-
attributes<const NextAttributesSpec extends ModelAttributesSpec>(specOrFactory: StageInput<AttributeContext<Fields>, ValidateAttributesStageSpec<Fields, SqlSpec, NextAttributesSpec>>): ContractModelBuilder<ModelName, Fields, Relations, NextAttributesSpec, SqlSpec, IndexTypes>;
|
|
299
|
-
sql<const NextSqlSpec extends SqlStageSpec>(specOrFactory: StageInput<SqlContext<Fields, IndexTypes>, NextSqlSpec>): [ValidateSqlStageSpec<Fields, AttributesSpec, NextSqlSpec>] extends [never] ? ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, never, IndexTypes> : ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, NextSqlSpec, IndexTypes>;
|
|
519
|
+
relations<const NextRelations extends Record<string, AnyRelationBuilder>>(relations: NextRelations): ContractModelBuilder<ModelName, Fields, Relations & NextRelations, AttributesSpec, SqlSpec, IndexTypes, TSpaceId>;
|
|
520
|
+
attributes<const NextAttributesSpec extends ModelAttributesSpec>(specOrFactory: StageInput<AttributeContext<Fields>, ValidateAttributesStageSpec<Fields, SqlSpec, NextAttributesSpec>>): ContractModelBuilder<ModelName, Fields, Relations, NextAttributesSpec, SqlSpec, IndexTypes, TSpaceId>;
|
|
521
|
+
sql<const NextSqlSpec extends SqlStageSpec>(specOrFactory: StageInput<SqlContext<Fields, IndexTypes>, NextSqlSpec>): [ValidateSqlStageSpec<Fields, AttributesSpec, NextSqlSpec>] extends [never] ? ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, never, IndexTypes, TSpaceId> : ContractModelBuilder<ModelName, Fields, Relations, AttributesSpec, NextSqlSpec, IndexTypes, TSpaceId>;
|
|
300
522
|
buildAttributesSpec(): AttributesSpec;
|
|
301
523
|
buildSqlSpec(): SqlSpec;
|
|
302
524
|
}
|
|
@@ -318,6 +540,7 @@ type ContractInput<Family extends FamilyPackRef<string> = FamilyPackRef<string>,
|
|
|
318
540
|
readonly naming?: NamingConfig;
|
|
319
541
|
readonly storageHash?: string;
|
|
320
542
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
543
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
321
544
|
/**
|
|
322
545
|
* Declared namespace coordinates the contract recognises. Per-model
|
|
323
546
|
* `namespace` references must reference an entry in this list (or the
|
|
@@ -366,6 +589,12 @@ type ContractInput<Family extends FamilyPackRef<string> = FamilyPackRef<string>,
|
|
|
366
589
|
readonly types?: Types;
|
|
367
590
|
readonly models?: Models;
|
|
368
591
|
readonly codecLookup?: CodecLookup;
|
|
592
|
+
/**
|
|
593
|
+
* Domain enum handles authored via `enumType()`. Each handle lowers to a
|
|
594
|
+
* domain `enum` entry and a storage `valueSet` entry in the target's
|
|
595
|
+
* default namespace. Fields reference the enum via `field.namedType(handle)`.
|
|
596
|
+
*/
|
|
597
|
+
readonly enums?: Record<string, EnumTypeHandle>;
|
|
369
598
|
};
|
|
370
599
|
declare function model<const ModelName extends string, Fields extends Record<string, ScalarFieldBuilder>, Relations extends Record<string, AnyRelationBuilder> = Record<never, never>>(modelName: ModelName, input: {
|
|
371
600
|
readonly fields: Fields;
|
|
@@ -377,6 +606,26 @@ declare function model<Fields extends Record<string, ScalarFieldBuilder>, Relati
|
|
|
377
606
|
readonly relations?: Relations;
|
|
378
607
|
readonly namespace?: string;
|
|
379
608
|
}): ContractModelBuilder<undefined, Fields, Relations>;
|
|
609
|
+
/**
|
|
610
|
+
* Factory for building a standalone branded extension model handle.
|
|
611
|
+
*
|
|
612
|
+
* Use this instead of `new ContractModelBuilder(…)` when constructing handles
|
|
613
|
+
* for models that live in a foreign contract space (e.g. a Supabase extension
|
|
614
|
+
* model referenced by a user's contract). The `spaceId` brands the returned
|
|
615
|
+
* handle so `refs.<field>.spaceId` carries the foreign space identifier.
|
|
616
|
+
*
|
|
617
|
+
* @param name - The domain model name as declared in the foreign contract
|
|
618
|
+
* (e.g. `'AuthUser'`, not a bare table alias like `'User'`).
|
|
619
|
+
* @param input.namespace - The namespace within the foreign space (e.g. `'auth'`).
|
|
620
|
+
* @param input.fields - Field definitions (use `field.column(…)`).
|
|
621
|
+
* @param input.table - The physical table name in the foreign schema.
|
|
622
|
+
* @param spaceId - The extension space identifier (e.g. `'supabase'`).
|
|
623
|
+
*/
|
|
624
|
+
declare function extensionModel<const ModelName extends string, Fields extends Record<string, ScalarFieldBuilder>, const TSpaceId extends string>(name: ModelName, input: {
|
|
625
|
+
readonly namespace: string;
|
|
626
|
+
readonly fields: Fields;
|
|
627
|
+
readonly table: string;
|
|
628
|
+
}, spaceId: TSpaceId): ContractModelBuilder<ModelName, Fields, Record<never, never>, undefined, undefined, Record<never, never>, TSpaceId>;
|
|
380
629
|
declare function belongsTo<Token extends AnyNamedModelToken, FromField extends string | readonly string[], ToField extends RelationFieldSelection<RelationModelFieldNames<Token>>>(toModel: Token | LazyNamedModelToken<Token>, options: {
|
|
381
630
|
readonly from: FromField;
|
|
382
631
|
readonly to: ToField;
|
|
@@ -513,7 +762,7 @@ type DefinitionNamespaces<Definition> = Definition extends {
|
|
|
513
762
|
} ? string[] extends Names ? never : readonly string[] extends Names ? never : Names[number] : never;
|
|
514
763
|
type DefinitionTypes<Definition> = Definition extends {
|
|
515
764
|
readonly types?: unknown;
|
|
516
|
-
} ? Present<Definition['types']> extends Record<string,
|
|
765
|
+
} ? Present<Definition['types']> extends Record<string, StorageType> ? Present<Definition['types']> : Record<never, never> : Record<never, never>;
|
|
517
766
|
type DefinitionTableNaming<Definition> = Definition extends {
|
|
518
767
|
readonly naming?: {
|
|
519
768
|
readonly tables?: infer Strategy extends string;
|
|
@@ -577,11 +826,19 @@ type DescriptorTypeParams<Descriptor> = Descriptor extends {
|
|
|
577
826
|
type DescriptorTypeRef<Descriptor> = Descriptor extends {
|
|
578
827
|
readonly typeRef: infer TypeRef extends string;
|
|
579
828
|
} ? TypeRef : undefined;
|
|
580
|
-
type LookupNamedStorageTypeKeyByValue<Definition, TypeRef extends
|
|
581
|
-
type ResolveNamedStorageTypeKey<Definition, TypeRef> = TypeRef extends string ? TypeRef : TypeRef extends
|
|
829
|
+
type LookupNamedStorageTypeKeyByValue<Definition, TypeRef extends StorageType> = { [TypeName in keyof DefinitionTypes<Definition> & string]: [TypeRef] extends [DefinitionTypes<Definition>[TypeName]] ? [DefinitionTypes<Definition>[TypeName]] extends [TypeRef] ? TypeName : never : never }[keyof DefinitionTypes<Definition> & string];
|
|
830
|
+
type ResolveNamedStorageTypeKey<Definition, TypeRef> = TypeRef extends string ? TypeRef : TypeRef extends StorageType ? [LookupNamedStorageTypeKeyByValue<Definition, TypeRef>] extends [never] ? string : LookupNamedStorageTypeKeyByValue<Definition, TypeRef> : never;
|
|
582
831
|
type ResolveNamedStorageType<Definition, TypeRef> = ResolveNamedStorageTypeKey<Definition, TypeRef> extends infer TypeName extends string ? TypeName extends keyof DefinitionTypes<Definition> ? DefinitionTypes<Definition>[TypeName] : StorageTypeInstance : StorageTypeInstance;
|
|
583
|
-
type
|
|
584
|
-
type
|
|
832
|
+
type EnumFieldHandle<FieldState> = [FieldTypeRefOf<FieldState>] extends [never] ? never : FieldTypeRefOf<FieldState> extends EnumTypeHandle ? FieldTypeRefOf<FieldState> : never;
|
|
833
|
+
type EnumHandleDescriptor<Handle> = Handle extends {
|
|
834
|
+
readonly codecId: infer CodecId extends string;
|
|
835
|
+
readonly nativeType: infer NativeType extends string;
|
|
836
|
+
} ? {
|
|
837
|
+
readonly codecId: CodecId;
|
|
838
|
+
readonly nativeType: NativeType;
|
|
839
|
+
} : never;
|
|
840
|
+
type ResolveFieldDescriptor<Definition, FieldState> = [EnumFieldHandle<FieldState>] extends [never] ? [FieldDescriptorOf<FieldState>] extends [never] ? ResolveNamedStorageType<Definition, FieldTypeRefOf<FieldState>> : FieldDescriptorOf<FieldState> : EnumHandleDescriptor<EnumFieldHandle<FieldState>>;
|
|
841
|
+
type ResolveFieldColumnTypeRef<Definition, FieldState> = [EnumFieldHandle<FieldState>] extends [never] ? [FieldTypeRefOf<FieldState>] extends [never] ? DescriptorTypeRef<FieldDescriptorOf<FieldState>> : ResolveNamedStorageTypeKey<Definition, FieldTypeRefOf<FieldState>> : undefined;
|
|
585
842
|
type ResolveFieldColumnTypeParams<Definition, FieldState> = [ResolveFieldColumnTypeRef<Definition, FieldState>] extends [string] ? undefined : DescriptorTypeParams<FieldDescriptorOf<FieldState>>;
|
|
586
843
|
type ModelTableName<Definition, ModelName extends ModelNames<Definition>> = [Present<ModelSql<Definition, ModelName> extends {
|
|
587
844
|
readonly table?: infer TableName;
|
|
@@ -648,6 +905,7 @@ type BuiltStorageTables<Definition> = { readonly [ModelName in ModelNames<Defini
|
|
|
648
905
|
};
|
|
649
906
|
readonly target: {
|
|
650
907
|
readonly namespaceId: NamespaceId;
|
|
908
|
+
readonly spaceId?: string;
|
|
651
909
|
readonly tableName: string;
|
|
652
910
|
readonly columns: readonly string[];
|
|
653
911
|
};
|
|
@@ -663,7 +921,19 @@ type BuiltStorageTables<Definition> = { readonly [ModelName in ModelNames<Defini
|
|
|
663
921
|
readonly name?: ModelIdName<Definition, ModelName>;
|
|
664
922
|
};
|
|
665
923
|
} : Record<string, never>) };
|
|
666
|
-
type
|
|
924
|
+
type DefinitionEnums<Definition> = Definition extends {
|
|
925
|
+
readonly enums?: infer E;
|
|
926
|
+
} ? Present<E> extends Record<string, EnumTypeHandle> ? string extends keyof Present<E> ? Record<never, never> : Present<E> : Record<never, never> : Record<never, never>;
|
|
927
|
+
type EnumHandleAccessorType<Handle> = Handle extends EnumTypeHandle<infer _Name, infer Values, infer Names, infer MembersMap> ? {
|
|
928
|
+
readonly values: Values;
|
|
929
|
+
readonly names: Names;
|
|
930
|
+
readonly members: MembersMap;
|
|
931
|
+
has(v: Values[number]): boolean;
|
|
932
|
+
nameOf(v: Values[number]): string | undefined;
|
|
933
|
+
ordinalOf(v: Values[number]): number;
|
|
934
|
+
} : never;
|
|
935
|
+
type BuiltEnumAccessors<Definition> = { readonly [K in keyof DefinitionEnums<Definition>]: EnumHandleAccessorType<DefinitionEnums<Definition>[K]> };
|
|
936
|
+
type BuiltDocumentScopedTypes<Definition> = { readonly [K in keyof DefinitionTypes<Definition> as DefinitionTypes<Definition>[K] extends StorageTypeInstance ? K : never]: DefinitionTypes<Definition>[K] };
|
|
667
937
|
type BuiltDomain<Definition> = BuiltDocumentScopedTypes<Definition> extends Record<never, never> ? Record<string, never> : {
|
|
668
938
|
readonly __unbound__: {
|
|
669
939
|
readonly types: BuiltDocumentScopedTypes<Definition>;
|
|
@@ -676,23 +946,21 @@ type BuiltStorage<Definition> = {
|
|
|
676
946
|
readonly namespaces: { readonly [K in DefaultStorageNamespaceId<Definition>]: {
|
|
677
947
|
readonly id: K;
|
|
678
948
|
readonly kind: string;
|
|
679
|
-
readonly
|
|
680
|
-
|
|
949
|
+
readonly entries: {
|
|
950
|
+
readonly table: BuiltStorageTables<Definition>;
|
|
951
|
+
};
|
|
681
952
|
} } & { readonly [Ns in Exclude<DefinitionNamespaces<Definition>, DefaultStorageNamespaceId<Definition>>]: {
|
|
682
953
|
readonly id: Ns;
|
|
683
954
|
readonly kind: string;
|
|
684
|
-
readonly
|
|
685
|
-
|
|
955
|
+
readonly entries: {
|
|
956
|
+
readonly table: Record<never, never>;
|
|
957
|
+
};
|
|
686
958
|
} };
|
|
687
959
|
};
|
|
688
|
-
type
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
} ? Col extends {
|
|
693
|
-
readonly nullable: true;
|
|
694
|
-
} ? O | null : O : unknown : unknown : unknown : unknown;
|
|
695
|
-
type FieldOutputTypes<Definition> = { readonly [ModelName in ModelNames<Definition>]: { readonly [FieldName in ModelFieldNames<Definition, ModelName>]: FieldOutputType<Definition, ModelName, FieldName> } };
|
|
960
|
+
type EnumValueUnion<FieldState> = [FieldTypeRefOf<FieldState>] extends [EnumTypeHandle<string, infer Values>] ? readonly unknown[] extends Values ? never : Values[number] : never;
|
|
961
|
+
type CodecChannelType<Definition, ModelName extends ModelNames<Definition>, FieldName extends ModelFieldNames<Definition, ModelName>, Channel extends 'output' | 'input'> = ModelStorageColumn<Definition, ModelName, FieldName>['codecId'] extends infer Id extends keyof CodecTypesFromDefinition<Definition> ? CodecTypesFromDefinition<Definition>[Id] extends { readonly [K in Channel]: infer T } ? T : unknown : unknown;
|
|
962
|
+
type FieldChannelType<Definition, ModelName extends ModelNames<Definition>, FieldName extends ModelFieldNames<Definition, ModelName>, Channel extends 'output' | 'input'> = ([EnumValueUnion<ModelFieldState<Definition, ModelName, FieldName>>] extends [never] ? CodecChannelType<Definition, ModelName, FieldName, Channel> : EnumValueUnion<ModelFieldState<Definition, ModelName, FieldName>>) | (FieldNullableOf<ModelFieldState<Definition, ModelName, FieldName>> extends true ? null : never);
|
|
963
|
+
type FieldChannelTypes<Definition, Channel extends 'output' | 'input'> = { readonly [ModelName in ModelNames<Definition>]: { readonly [FieldName in ModelFieldNames<Definition, ModelName>]: FieldChannelType<Definition, ModelName, FieldName, Channel> } };
|
|
696
964
|
type SqlContractResult<Definition> = ContractWithTypeMaps<Contract<BuiltStorage<Definition>, BuiltModels<Definition>> & {
|
|
697
965
|
readonly target: DefinitionTargetId<Definition>;
|
|
698
966
|
readonly targetFamily: 'sql';
|
|
@@ -701,7 +969,8 @@ type SqlContractResult<Definition> = ContractWithTypeMaps<Contract<BuiltStorage<
|
|
|
701
969
|
} & {
|
|
702
970
|
readonly extensionPacks: keyof DefinitionExtensionPacks<Definition> extends never ? Record<string, never> : DefinitionExtensionPacks<Definition>;
|
|
703
971
|
readonly capabilities: DerivedCapabilities<Definition>;
|
|
704
|
-
|
|
972
|
+
readonly enumAccessors: BuiltEnumAccessors<Definition>;
|
|
973
|
+
}, TypeMaps<CodecTypesFromDefinition<Definition>, Record<string, never>, FieldChannelTypes<Definition, 'output'>, FieldChannelTypes<Definition, 'input'>>>;
|
|
705
974
|
//#endregion
|
|
706
975
|
//#region src/composed-authoring-helpers.d.ts
|
|
707
976
|
type ExtractTypeNamespaceFromPack<Pack> = ExtractAuthoringNamespaceFromPack<Pack, 'type', Record<never, never>>;
|
|
@@ -758,6 +1027,8 @@ interface FieldNode {
|
|
|
758
1027
|
readonly default?: ColumnDefault;
|
|
759
1028
|
readonly executionDefaults?: ExecutionMutationDefaultPhases$1;
|
|
760
1029
|
readonly many?: boolean;
|
|
1030
|
+
/** Present when the field was authored with `field.namedType(enumHandle)`. */
|
|
1031
|
+
readonly enumTypeHandle?: EnumTypeHandle;
|
|
761
1032
|
}
|
|
762
1033
|
interface PrimaryKeyNode {
|
|
763
1034
|
readonly columns: readonly string[];
|
|
@@ -786,6 +1057,12 @@ interface ForeignKeyNode {
|
|
|
786
1057
|
* know the target namespace can stamp it explicitly.
|
|
787
1058
|
*/
|
|
788
1059
|
readonly namespaceId?: string;
|
|
1060
|
+
/**
|
|
1061
|
+
* Contract-space identity of the referenced table. When present, the
|
|
1062
|
+
* table lives in a different contract space (identified by this value)
|
|
1063
|
+
* rather than the current contract. Absent for local FKs.
|
|
1064
|
+
*/
|
|
1065
|
+
readonly spaceId?: string;
|
|
789
1066
|
};
|
|
790
1067
|
readonly name?: string;
|
|
791
1068
|
readonly onDelete?: ReferentialAction;
|
|
@@ -797,7 +1074,26 @@ interface RelationNode {
|
|
|
797
1074
|
readonly fieldName: string;
|
|
798
1075
|
readonly toModel: string;
|
|
799
1076
|
readonly toTable: string;
|
|
1077
|
+
/**
|
|
1078
|
+
* Namespace coordinate of the related model. When omitted the assembler
|
|
1079
|
+
* resolves the coordinate from the referenced model node's own
|
|
1080
|
+
* `namespaceId`; the field exists so authoring paths that already know the
|
|
1081
|
+
* target namespace can stamp it explicitly — required to disambiguate a
|
|
1082
|
+
* relation to a model whose bare name also exists in another namespace.
|
|
1083
|
+
*/
|
|
1084
|
+
readonly toNamespaceId?: string;
|
|
800
1085
|
readonly cardinality: '1:1' | '1:N' | 'N:1' | 'N:M';
|
|
1086
|
+
/**
|
|
1087
|
+
* Contract-space identity of the related model. When present, the
|
|
1088
|
+
* related model lives in a different contract space. Absent for local
|
|
1089
|
+
* (same-space) relations.
|
|
1090
|
+
*/
|
|
1091
|
+
readonly spaceId?: string;
|
|
1092
|
+
/**
|
|
1093
|
+
* Namespace coordinate of the related model in the foreign space.
|
|
1094
|
+
* Only set when `spaceId` is present.
|
|
1095
|
+
*/
|
|
1096
|
+
readonly namespaceId?: string;
|
|
801
1097
|
readonly on: {
|
|
802
1098
|
readonly parentTable: string;
|
|
803
1099
|
readonly parentColumns: readonly string[];
|
|
@@ -843,9 +1139,19 @@ interface ModelNode {
|
|
|
843
1139
|
readonly indexes?: readonly IndexNode[];
|
|
844
1140
|
readonly foreignKeys?: readonly ForeignKeyNode[];
|
|
845
1141
|
readonly relations?: readonly RelationNode[];
|
|
1142
|
+
readonly control?: ControlPolicy;
|
|
1143
|
+
/**
|
|
1144
|
+
* Single-table-inheritance variants share their base model's storage table:
|
|
1145
|
+
* the variant's columns are materialised onto the base `ModelNode`, and this
|
|
1146
|
+
* model contributes a domain model but no storage table of its own. When set,
|
|
1147
|
+
* the assembler builds the domain model but skips creating a (shadow) storage
|
|
1148
|
+
* table and a root for this model — the base owns both.
|
|
1149
|
+
*/
|
|
1150
|
+
readonly sharesBaseTable?: boolean;
|
|
846
1151
|
}
|
|
847
1152
|
interface ContractDefinition {
|
|
848
1153
|
readonly target: TargetPackRef<'sql', string>;
|
|
1154
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
849
1155
|
readonly extensionPacks?: Record<string, ExtensionPackRef<'sql', string>>;
|
|
850
1156
|
readonly storageHash?: string;
|
|
851
1157
|
readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
|
|
@@ -853,7 +1159,7 @@ interface ContractDefinition {
|
|
|
853
1159
|
/**
|
|
854
1160
|
* Enum types declared inside a named `namespace { enum … }` block,
|
|
855
1161
|
* keyed first by namespace id then by type name. These are routed to
|
|
856
|
-
* `storage.namespaces[nsId].
|
|
1162
|
+
* `storage.namespaces[nsId].entries.type` rather than the implicit fallback
|
|
857
1163
|
* namespace used for top-level `storageTypes` enums.
|
|
858
1164
|
*/
|
|
859
1165
|
readonly namespaceTypes?: Readonly<Record<string, Readonly<Record<string, PostgresEnumStorageEntry>>>>;
|
|
@@ -866,10 +1172,19 @@ interface ContractDefinition {
|
|
|
866
1172
|
* Target-supplied factory that materialises a `Namespace` concretion
|
|
867
1173
|
* for a declared namespace coordinate. Mirrors
|
|
868
1174
|
* `ContractInput.createNamespace`.
|
|
1175
|
+
*
|
|
1176
|
+
* The optional second argument carries target-specific enum types for the
|
|
1177
|
+
* namespace (e.g. postgres enum registrations keyed by type name).
|
|
869
1178
|
*/
|
|
870
|
-
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
1179
|
+
readonly createNamespace?: (input: SqlNamespaceTablesInput, enumTypes?: Readonly<Record<string, PostgresEnumStorageEntry>>) => Namespace;
|
|
871
1180
|
readonly models: readonly ModelNode[];
|
|
872
1181
|
readonly valueObjects?: readonly ValueObjectNode[];
|
|
1182
|
+
/**
|
|
1183
|
+
* Domain enum handles authored via `enumType()`. Each entry lowers to a
|
|
1184
|
+
* domain `enum` entry and a storage `valueSet` entry in the contract's
|
|
1185
|
+
* default namespace.
|
|
1186
|
+
*/
|
|
1187
|
+
readonly enums?: Record<string, EnumTypeHandle>;
|
|
873
1188
|
}
|
|
874
1189
|
//#endregion
|
|
875
1190
|
//#region src/build-contract.d.ts
|
|
@@ -888,38 +1203,79 @@ type ModelLike = {
|
|
|
888
1203
|
buildAttributesSpec(): ModelAttributesSpec | undefined;
|
|
889
1204
|
buildSqlSpec(): SqlStageSpec | undefined;
|
|
890
1205
|
};
|
|
891
|
-
type ContractDefinition$1<Family extends FamilyPackRef<string>, Target extends TargetPackRef<'sql', string>, Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, Models extends Record<string, ModelLike>, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Naming extends ContractInput['naming'] | undefined, StorageHash extends string | undefined, ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined, Namespaces extends readonly string[] | undefined = undefined> = {
|
|
1206
|
+
type ContractDefinition$1<Family extends FamilyPackRef<string>, Target extends TargetPackRef<'sql', string>, Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, Models extends Record<string, ModelLike>, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Naming extends ContractInput['naming'] | undefined, StorageHash extends string | undefined, ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined, Namespaces extends readonly string[] | undefined = undefined, Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>> = {
|
|
892
1207
|
readonly family: Family;
|
|
893
1208
|
readonly target: Target;
|
|
894
1209
|
readonly extensionPacks?: ExtensionPacks;
|
|
895
1210
|
readonly naming?: Naming;
|
|
896
1211
|
readonly storageHash?: StorageHash;
|
|
897
1212
|
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
1213
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
898
1214
|
readonly namespaces?: Namespaces;
|
|
899
1215
|
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
900
1216
|
readonly types?: Types;
|
|
901
1217
|
readonly models?: Models;
|
|
902
1218
|
readonly codecLookup?: CodecLookup;
|
|
1219
|
+
readonly enums?: Enums;
|
|
903
1220
|
};
|
|
904
|
-
type ContractScaffold<Family extends FamilyPackRef<string>, Target extends TargetPackRef<'sql', string>, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Naming extends ContractInput['naming'] | undefined, StorageHash extends string | undefined, ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined, Namespaces extends readonly string[] | undefined = undefined> = {
|
|
1221
|
+
type ContractScaffold<Family extends FamilyPackRef<string>, Target extends TargetPackRef<'sql', string>, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Naming extends ContractInput['naming'] | undefined, StorageHash extends string | undefined, ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined, Namespaces extends readonly string[] | undefined = undefined, Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>> = {
|
|
905
1222
|
readonly family: Family;
|
|
906
1223
|
readonly target: Target;
|
|
907
1224
|
readonly extensionPacks?: ExtensionPacks;
|
|
908
1225
|
readonly naming?: Naming;
|
|
909
1226
|
readonly storageHash?: StorageHash;
|
|
910
1227
|
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
1228
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
911
1229
|
readonly namespaces?: Namespaces;
|
|
912
1230
|
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
913
1231
|
readonly types?: never;
|
|
914
1232
|
readonly models?: never;
|
|
915
1233
|
readonly codecLookup?: CodecLookup;
|
|
1234
|
+
readonly enums?: Enums;
|
|
916
1235
|
};
|
|
917
|
-
type ContractFactory<Family extends FamilyPackRef<string>, Target extends TargetPackRef<'sql', string>, Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, Models extends Record<string, ModelLike>, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined> = (helpers: ComposedAuthoringHelpers<Family, Target, ExtensionPacks>) => {
|
|
1236
|
+
type ContractFactory<Family extends FamilyPackRef<string>, Target extends TargetPackRef<'sql', string>, Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, Models extends Record<string, ModelLike>, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined, Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>> = (helpers: ComposedAuthoringHelpers<Family, Target, ExtensionPacks>) => {
|
|
918
1237
|
readonly types?: Types;
|
|
919
1238
|
readonly models?: Models;
|
|
1239
|
+
readonly enums?: Enums;
|
|
1240
|
+
};
|
|
1241
|
+
type BoundDefinitionInput<Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = Record<never, never>, Models extends Record<string, ModelLike> = Record<never, never>, ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined, Naming extends ContractInput['naming'] | undefined = undefined, StorageHash extends string | undefined = undefined, ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined, Namespaces extends readonly string[] | undefined = undefined> = {
|
|
1242
|
+
readonly extensionPacks?: ExtensionPacks;
|
|
1243
|
+
readonly naming?: Naming;
|
|
1244
|
+
readonly storageHash?: StorageHash;
|
|
1245
|
+
readonly foreignKeyDefaults?: ForeignKeyDefaults;
|
|
1246
|
+
readonly defaultControlPolicy?: ControlPolicy;
|
|
1247
|
+
readonly namespaces?: Namespaces;
|
|
1248
|
+
readonly createNamespace?: (input: SqlNamespaceTablesInput) => Namespace;
|
|
1249
|
+
readonly types?: Types;
|
|
1250
|
+
readonly models?: Models;
|
|
1251
|
+
readonly codecLookup?: CodecLookup;
|
|
1252
|
+
readonly enums?: Record<string, EnumTypeHandle>;
|
|
1253
|
+
};
|
|
1254
|
+
type LiteralEnums<E extends Record<string, EnumTypeHandle>> = string extends keyof E ? Record<never, never> : E;
|
|
1255
|
+
type MergeEnums<ScaffoldEnums extends Record<string, EnumTypeHandle>, FactoryEnums extends Record<string, EnumTypeHandle>> = LiteralEnums<ScaffoldEnums> & LiteralEnums<FactoryEnums>;
|
|
1256
|
+
type WithFamilyTarget<Input, F extends FamilyPackRef<string>, T extends TargetPackRef<'sql', string>> = Input & {
|
|
1257
|
+
readonly family: F;
|
|
1258
|
+
readonly target: T;
|
|
920
1259
|
};
|
|
921
|
-
|
|
922
|
-
|
|
1260
|
+
/**
|
|
1261
|
+
* Shared builder that assembles a SqlContract with pre-bound family and target.
|
|
1262
|
+
* Extension wrappers keep their own public overloads and delegate their impl body here;
|
|
1263
|
+
* this is a plain overloaded function (not a factory returning an overloaded function)
|
|
1264
|
+
* so no overloaded-function-return cast is needed.
|
|
1265
|
+
*
|
|
1266
|
+
* Overload 1: definition form (no factory).
|
|
1267
|
+
*/
|
|
1268
|
+
declare function buildBoundContract<const F extends FamilyPackRef<string>, const T extends TargetPackRef<'sql', string>, const Definition extends BoundDefinitionInput<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, Record<string, ModelLike>, Record<string, ExtensionPackRef<'sql', string>> | undefined, ContractInput['naming'] | undefined, string | undefined, ForeignKeyDefaultsState | undefined, readonly string[] | undefined>>(family: F, target: T, definition: Definition, factory?: undefined): SqlContractResult<WithFamilyTarget<Definition, F, T>>;
|
|
1269
|
+
/**
|
|
1270
|
+
* Overload 2: factory form.
|
|
1271
|
+
*/
|
|
1272
|
+
declare function buildBoundContract<const F extends FamilyPackRef<string>, const T extends TargetPackRef<'sql', string>, const Definition extends BoundDefinitionInput<Record<string, StorageTypeInstance | PostgresEnumStorageEntry>, Record<string, ModelLike>, Record<string, ExtensionPackRef<'sql', string>> | undefined, ContractInput['naming'] | undefined, string | undefined, ForeignKeyDefaultsState | undefined, readonly string[] | undefined>, const Built extends {
|
|
1273
|
+
readonly types?: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
|
|
1274
|
+
readonly models?: Record<string, ModelLike>;
|
|
1275
|
+
readonly enums?: Record<string, EnumTypeHandle>;
|
|
1276
|
+
}>(family: F, target: T, definition: Definition, factory: (helpers: ComposedAuthoringHelpers<F, T, NonNullable<Definition['extensionPacks']>>) => Built): SqlContractResult<WithFamilyTarget<Definition & Built, F, T>>;
|
|
1277
|
+
declare function defineContract<const Family extends FamilyPackRef<string>, const Target extends TargetPackRef<'sql', string>, const Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = Record<never, never>, const Models extends Record<string, ModelLike> = Record<never, never>, const ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined, const Naming extends ContractInput['naming'] | undefined = undefined, const StorageHash extends string | undefined = undefined, const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined, const Namespaces extends readonly string[] | undefined = undefined, const Enums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>>(definition: ContractDefinition$1<Family, Target, Types, Models, ExtensionPacks, Naming, StorageHash, ForeignKeyDefaults, Namespaces, Enums>): SqlContractResult<ContractDefinition$1<Family, Target, Types, Models, ExtensionPacks, Naming, StorageHash, ForeignKeyDefaults, Namespaces, Enums>>;
|
|
1278
|
+
declare function defineContract<const Family extends FamilyPackRef<string>, const Target extends TargetPackRef<'sql', string>, const Types extends Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = Record<never, never>, const Models extends Record<string, ModelLike> = Record<never, never>, const ExtensionPacks extends Record<string, ExtensionPackRef<'sql', string>> | undefined = undefined, const Naming extends ContractInput['naming'] | undefined = undefined, const StorageHash extends string | undefined = undefined, const ForeignKeyDefaults extends ForeignKeyDefaultsState | undefined = undefined, const Namespaces extends readonly string[] | undefined = undefined, const ScaffoldEnums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>, const FactoryEnums extends Record<string, EnumTypeHandle> = Record<string, EnumTypeHandle>>(definition: ContractScaffold<Family, Target, ExtensionPacks, Naming, StorageHash, ForeignKeyDefaults, Namespaces, ScaffoldEnums>, factory: ContractFactory<Family, Target, Types, Models, ExtensionPacks, FactoryEnums>): SqlContractResult<ContractDefinition$1<Family, Target, Types, Models, ExtensionPacks, Naming, StorageHash, ForeignKeyDefaults, Namespaces, MergeEnums<ScaffoldEnums, FactoryEnums>>>;
|
|
923
1279
|
//#endregion
|
|
924
|
-
export { type ComposedAuthoringHelpers, type ContractDefinition, type ContractInput, type ContractModelBuilder, type FieldNode, type ForeignKeyNode, type IndexNode, type ModelLike, type ModelNode, type PrimaryKeyNode, type RelationNode, type ScalarFieldBuilder, type UniqueConstraintNode, buildSqlContractFromDefinition, defineContract, field, model, rel };
|
|
1280
|
+
export { type BoundEnumType, type CodecInput, type CodecTypeMap, type ComposedAuthoringHelpers, type ContractDefinition, type ContractInput, type ContractModelBuilder, type EnumMember, type EnumTypeHandle, type ExtractCodecTypesFromPack, type FieldNode, type ForeignKeyNode, type IndexNode, type MergeEnums, type ModelLike, type ModelNode, type PrimaryKeyNode, type RelationNode, type ScalarFieldBuilder, type TargetFieldRef, type UniqueConstraintNode, bindEnumType, buildBoundContract, buildSqlContractFromDefinition, defineContract, enumType, extensionModel, field, member, model, rel };
|
|
925
1281
|
//# sourceMappingURL=contract-builder.d.mts.map
|