@prisma-next/contract-authoring 0.3.0-dev.9 → 0.3.0-dev.91

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/index.mjs ADDED
@@ -0,0 +1,237 @@
1
+ import { ifDefined } from "@prisma-next/utils/defined";
2
+
3
+ //#region src/model-builder.ts
4
+ var ModelBuilder = class ModelBuilder {
5
+ _name;
6
+ _table;
7
+ _fields;
8
+ _relations;
9
+ constructor(name, table, fields = {}, relations = {}) {
10
+ this._name = name;
11
+ this._table = table;
12
+ this._fields = fields;
13
+ this._relations = relations;
14
+ }
15
+ field(fieldName, columnName) {
16
+ return new ModelBuilder(this._name, this._table, {
17
+ ...this._fields,
18
+ [fieldName]: columnName
19
+ }, this._relations);
20
+ }
21
+ relation(name, options) {
22
+ if (options.on.parentTable !== this._table) throw new Error(`Relation "${name}" parentTable "${options.on.parentTable}" does not match model table "${this._table}"`);
23
+ if (options.cardinality === "N:M") {
24
+ if (!options.through) throw new Error(`Relation "${name}" with cardinality "N:M" requires through field`);
25
+ if (options.on.childTable !== options.through.table) throw new Error(`Relation "${name}" childTable "${options.on.childTable}" does not match through.table "${options.through.table}"`);
26
+ } else if (options.on.childTable !== options.toTable) throw new Error(`Relation "${name}" childTable "${options.on.childTable}" does not match toTable "${options.toTable}"`);
27
+ const relationDef = {
28
+ to: options.toModel,
29
+ cardinality: options.cardinality,
30
+ on: {
31
+ parentCols: options.on.parentColumns,
32
+ childCols: options.on.childColumns
33
+ },
34
+ ...options.through ? { through: {
35
+ table: options.through.table,
36
+ parentCols: options.through.parentColumns,
37
+ childCols: options.through.childColumns
38
+ } } : void 0
39
+ };
40
+ return new ModelBuilder(this._name, this._table, this._fields, {
41
+ ...this._relations,
42
+ [name]: relationDef
43
+ });
44
+ }
45
+ build() {
46
+ return {
47
+ name: this._name,
48
+ table: this._table,
49
+ fields: this._fields,
50
+ relations: this._relations
51
+ };
52
+ }
53
+ };
54
+
55
+ //#endregion
56
+ //#region src/table-builder.ts
57
+ function isIndexDef(value) {
58
+ return !Array.isArray(value);
59
+ }
60
+ /**
61
+ * Creates a new table builder with the given name.
62
+ * This is the preferred way to create a TableBuilder - it ensures
63
+ * type parameters are inferred correctly without unsafe casts.
64
+ */
65
+ function createTable(name) {
66
+ return new TableBuilder(name, {}, void 0, void 0, [], [], []);
67
+ }
68
+ /**
69
+ * Builder for defining table structure with type-safe chaining.
70
+ * Use `createTable(name)` to create instances.
71
+ */
72
+ var TableBuilder = class TableBuilder {
73
+ _state;
74
+ /** @internal Use createTable() instead */
75
+ constructor(name, columns, primaryKey, primaryKeyName, uniques, indexes, foreignKeys) {
76
+ this._state = {
77
+ name,
78
+ columns,
79
+ primaryKey,
80
+ primaryKeyName,
81
+ uniques,
82
+ indexes,
83
+ foreignKeys
84
+ };
85
+ }
86
+ get _name() {
87
+ return this._state.name;
88
+ }
89
+ get _columns() {
90
+ return this._state.columns;
91
+ }
92
+ get _primaryKey() {
93
+ return this._state.primaryKey;
94
+ }
95
+ /**
96
+ * Implementation of the column method.
97
+ */
98
+ column(name, options) {
99
+ return this.columnInternal(name, options);
100
+ }
101
+ generated(name, options) {
102
+ const { generated, ...columnOptions } = options;
103
+ return this.columnInternal(name, columnOptions, generated);
104
+ }
105
+ columnInternal(name, options, executionDefault) {
106
+ const nullable = options.nullable ?? false;
107
+ const { codecId, nativeType, typeParams: descriptorTypeParams, typeRef } = options.type;
108
+ const columnState = {
109
+ name,
110
+ nullable,
111
+ type: codecId,
112
+ nativeType,
113
+ ...ifDefined("typeParams", options.typeParams ?? descriptorTypeParams),
114
+ ...ifDefined("typeRef", typeRef),
115
+ ...ifDefined("default", "default" in options ? options.default : void 0),
116
+ ...ifDefined("executionDefault", executionDefault)
117
+ };
118
+ const newColumns = {
119
+ ...this._columns,
120
+ [name]: columnState
121
+ };
122
+ return new TableBuilder(this._state.name, newColumns, this._state.primaryKey, this._state.primaryKeyName, this._state.uniques, this._state.indexes, this._state.foreignKeys);
123
+ }
124
+ primaryKey(columns, name) {
125
+ return new TableBuilder(this._state.name, this._state.columns, columns, name, this._state.uniques, this._state.indexes, this._state.foreignKeys);
126
+ }
127
+ unique(columns, name) {
128
+ const constraint = name ? {
129
+ columns,
130
+ name
131
+ } : { columns };
132
+ return new TableBuilder(this._state.name, this._state.columns, this._state.primaryKey, this._state.primaryKeyName, [...this._state.uniques, constraint], this._state.indexes, this._state.foreignKeys);
133
+ }
134
+ index(columnsOrIndexDef, nameOrOptions) {
135
+ const indexDef = isIndexDef(columnsOrIndexDef) ? columnsOrIndexDef : {
136
+ columns: columnsOrIndexDef,
137
+ ...typeof nameOrOptions === "string" ? { name: nameOrOptions } : {},
138
+ ...typeof nameOrOptions === "object" && nameOrOptions !== null ? {
139
+ ...nameOrOptions.name !== void 0 ? { name: nameOrOptions.name } : {},
140
+ ...nameOrOptions.using !== void 0 ? { using: nameOrOptions.using } : {},
141
+ ...nameOrOptions.config !== void 0 ? { config: nameOrOptions.config } : {}
142
+ } : {}
143
+ };
144
+ return new TableBuilder(this._state.name, this._state.columns, this._state.primaryKey, this._state.primaryKeyName, this._state.uniques, [...this._state.indexes, indexDef], this._state.foreignKeys);
145
+ }
146
+ foreignKey(columns, references, opts) {
147
+ const resolved = typeof opts === "string" ? { name: opts } : opts;
148
+ const fkDef = {
149
+ columns,
150
+ references,
151
+ ...ifDefined("name", resolved?.name),
152
+ ...ifDefined("onDelete", resolved?.onDelete),
153
+ ...ifDefined("onUpdate", resolved?.onUpdate),
154
+ ...ifDefined("constraint", resolved?.constraint),
155
+ ...ifDefined("index", resolved?.index)
156
+ };
157
+ return new TableBuilder(this._state.name, this._state.columns, this._state.primaryKey, this._state.primaryKeyName, this._state.uniques, this._state.indexes, [...this._state.foreignKeys, fkDef]);
158
+ }
159
+ build() {
160
+ return {
161
+ name: this._name,
162
+ columns: this._columns,
163
+ ...this._primaryKey !== void 0 ? { primaryKey: this._primaryKey } : {},
164
+ ...this._state.primaryKeyName !== void 0 ? { primaryKeyName: this._state.primaryKeyName } : {},
165
+ uniques: this._state.uniques,
166
+ indexes: this._state.indexes,
167
+ foreignKeys: this._state.foreignKeys
168
+ };
169
+ }
170
+ };
171
+
172
+ //#endregion
173
+ //#region src/contract-builder.ts
174
+ var ContractBuilder = class ContractBuilder {
175
+ state;
176
+ constructor(state) {
177
+ this.state = state ?? {
178
+ tables: {},
179
+ models: {}
180
+ };
181
+ }
182
+ target(packRef) {
183
+ return new ContractBuilder({
184
+ ...this.state,
185
+ target: packRef.targetId
186
+ });
187
+ }
188
+ capabilities(capabilities) {
189
+ return new ContractBuilder({
190
+ ...this.state,
191
+ capabilities
192
+ });
193
+ }
194
+ table(name, callback) {
195
+ const tableBuilder = createTable(name);
196
+ const result = callback(tableBuilder);
197
+ const tableState = (result instanceof TableBuilder ? result : tableBuilder).build();
198
+ return new ContractBuilder({
199
+ ...this.state,
200
+ tables: {
201
+ ...this.state.tables,
202
+ [name]: tableState
203
+ }
204
+ });
205
+ }
206
+ model(name, table, callback) {
207
+ const modelBuilder = new ModelBuilder(name, table);
208
+ const result = callback(modelBuilder);
209
+ const modelState = (result instanceof ModelBuilder ? result : modelBuilder).build();
210
+ return new ContractBuilder({
211
+ ...this.state,
212
+ models: {
213
+ ...this.state.models,
214
+ [name]: modelState
215
+ }
216
+ });
217
+ }
218
+ storageHash(hash) {
219
+ return new ContractBuilder({
220
+ ...this.state,
221
+ storageHash: hash
222
+ });
223
+ }
224
+ foreignKeyDefaults(config) {
225
+ return new ContractBuilder({
226
+ ...this.state,
227
+ foreignKeyDefaults: config
228
+ });
229
+ }
230
+ };
231
+ function defineContract() {
232
+ return new ContractBuilder();
233
+ }
234
+
235
+ //#endregion
236
+ export { ContractBuilder, ModelBuilder, TableBuilder, createTable, defineContract };
237
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["relationDef: RelationDefinition","constraint: UniqueConstraintDef","indexDef: IndexDef","fkDef: ForeignKeyDef"],"sources":["../src/model-builder.ts","../src/table-builder.ts","../src/contract-builder.ts"],"sourcesContent":["import type { ModelBuilderState, RelationDefinition } from './builder-state';\n\nexport class ModelBuilder<\n Name extends string,\n Table extends string,\n Fields extends Record<string, string> = Record<never, never>,\n Relations extends Record<string, RelationDefinition> = Record<never, never>,\n> {\n private readonly _name: Name;\n private readonly _table: Table;\n private readonly _fields: Fields;\n private readonly _relations: Relations;\n\n constructor(\n name: Name,\n table: Table,\n fields: Fields = {} as Fields,\n relations: Relations = {} as Relations,\n ) {\n this._name = name;\n this._table = table;\n this._fields = fields;\n this._relations = relations;\n }\n\n field<FieldName extends string, ColumnName extends string>(\n fieldName: FieldName,\n columnName: ColumnName,\n ): ModelBuilder<Name, Table, Fields & Record<FieldName, ColumnName>, Relations> {\n return new ModelBuilder(\n this._name,\n this._table,\n {\n ...this._fields,\n [fieldName]: columnName,\n } as Fields & Record<FieldName, ColumnName>,\n this._relations,\n );\n }\n\n relation<RelationName extends string, ToModel extends string, ToTable extends string>(\n name: RelationName,\n options: {\n toModel: ToModel;\n toTable: ToTable;\n cardinality: '1:1' | '1:N' | 'N:1';\n on: {\n parentTable: Table;\n parentColumns: readonly string[];\n childTable: ToTable;\n childColumns: readonly string[];\n };\n },\n ): ModelBuilder<Name, Table, Fields, Relations & Record<RelationName, RelationDefinition>>;\n relation<\n RelationName extends string,\n ToModel extends string,\n ToTable extends string,\n JunctionTable extends string,\n >(\n name: RelationName,\n options: {\n toModel: ToModel;\n toTable: ToTable;\n cardinality: 'N:M';\n through: {\n table: JunctionTable;\n parentColumns: readonly string[];\n childColumns: readonly string[];\n };\n on: {\n parentTable: Table;\n parentColumns: readonly string[];\n childTable: JunctionTable;\n childColumns: readonly string[];\n };\n },\n ): ModelBuilder<Name, Table, Fields, Relations & Record<RelationName, RelationDefinition>>;\n relation<\n RelationName extends string,\n ToModel extends string,\n ToTable extends string,\n JunctionTable extends string = never,\n >(\n name: RelationName,\n options: {\n toModel: ToModel;\n toTable: ToTable;\n cardinality: '1:1' | '1:N' | 'N:1' | 'N:M';\n through?: {\n table: JunctionTable;\n parentColumns: readonly string[];\n childColumns: readonly string[];\n };\n on: {\n parentTable: Table;\n parentColumns: readonly string[];\n childTable: ToTable | JunctionTable;\n childColumns: readonly string[];\n };\n },\n ): ModelBuilder<Name, Table, Fields, Relations & Record<RelationName, RelationDefinition>> {\n // Validate parentTable matches model's table\n if (options.on.parentTable !== this._table) {\n throw new Error(\n `Relation \"${name}\" parentTable \"${options.on.parentTable}\" does not match model table \"${this._table}\"`,\n );\n }\n\n // Validate childTable matches toTable (for non-N:M) or through.table (for N:M)\n if (options.cardinality === 'N:M') {\n if (!options.through) {\n throw new Error(`Relation \"${name}\" with cardinality \"N:M\" requires through field`);\n }\n if (options.on.childTable !== options.through.table) {\n throw new Error(\n `Relation \"${name}\" childTable \"${options.on.childTable}\" does not match through.table \"${options.through.table}\"`,\n );\n }\n } else {\n if (options.on.childTable !== options.toTable) {\n throw new Error(\n `Relation \"${name}\" childTable \"${options.on.childTable}\" does not match toTable \"${options.toTable}\"`,\n );\n }\n }\n\n const relationDef: RelationDefinition = {\n to: options.toModel,\n cardinality: options.cardinality,\n on: {\n parentCols: options.on.parentColumns,\n childCols: options.on.childColumns,\n },\n ...(options.through\n ? {\n through: {\n table: options.through.table,\n parentCols: options.through.parentColumns,\n childCols: options.through.childColumns,\n },\n }\n : undefined),\n };\n\n return new ModelBuilder(this._name, this._table, this._fields, {\n ...this._relations,\n [name]: relationDef,\n } as Relations & Record<RelationName, RelationDefinition>);\n }\n\n build(): ModelBuilderState<Name, Table, Fields, Relations> {\n return {\n name: this._name,\n table: this._table,\n fields: this._fields,\n relations: this._relations,\n };\n }\n}\n","import type { ColumnDefault, ExecutionMutationDefaultValue } from '@prisma-next/contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type {\n ColumnBuilderState,\n ColumnTypeDescriptor,\n ForeignKeyDef,\n ForeignKeyOptions,\n IndexDef,\n TableBuilderState,\n UniqueConstraintDef,\n} from './builder-state';\n\n/**\n * Column options for nullable columns.\n */\ninterface NullableColumnOptions<Descriptor extends ColumnTypeDescriptor> {\n type: Descriptor;\n nullable: true;\n typeParams?: Record<string, unknown>;\n default?: ColumnDefault;\n}\n\n/**\n * Column options for non-nullable columns.\n * Non-nullable columns can optionally have a default value.\n */\ninterface NonNullableColumnOptions<Descriptor extends ColumnTypeDescriptor> {\n type: Descriptor;\n nullable?: false;\n typeParams?: Record<string, unknown>;\n default?: ColumnDefault;\n}\n\ntype GeneratedColumnOptions<Descriptor extends ColumnTypeDescriptor> = Omit<\n NonNullableColumnOptions<Descriptor>,\n 'default' | 'nullable'\n> & {\n /**\n * Generated columns are always non-nullable and use mutation-time defaults\n * that the runtime injects when the column is omitted from insert input.\n */\n nullable?: false;\n generated: ExecutionMutationDefaultValue;\n};\n\n/** Column options for any column nullability. */\ntype ColumnOptions<Descriptor extends ColumnTypeDescriptor> =\n | NullableColumnOptions<Descriptor>\n | NonNullableColumnOptions<Descriptor>;\n\ntype NullableFromOptions<TOptions> = TOptions extends { nullable: true } ? true : false;\ntype IndexOptions = {\n readonly name?: string;\n readonly using?: string;\n readonly config?: Record<string, unknown>;\n};\n\nfunction isIndexDef(value: readonly string[] | IndexDef): value is IndexDef {\n return !Array.isArray(value);\n}\n\ninterface TableBuilderInternalState<\n Name extends string,\n Columns extends Record<string, ColumnBuilderState<string, boolean, string>>,\n PrimaryKey extends readonly string[] | undefined,\n> {\n readonly name: Name;\n readonly columns: Columns;\n readonly primaryKey: PrimaryKey;\n readonly primaryKeyName: string | undefined;\n readonly uniques: readonly UniqueConstraintDef[];\n readonly indexes: readonly IndexDef[];\n readonly foreignKeys: readonly ForeignKeyDef[];\n}\n\n/**\n * Creates a new table builder with the given name.\n * This is the preferred way to create a TableBuilder - it ensures\n * type parameters are inferred correctly without unsafe casts.\n */\nexport function createTable<Name extends string>(name: Name): TableBuilder<Name> {\n return new TableBuilder(name, {}, undefined, undefined, [], [], []);\n}\n\n/**\n * Builder for defining table structure with type-safe chaining.\n * Use `createTable(name)` to create instances.\n */\nexport class TableBuilder<\n Name extends string,\n Columns extends Record<string, ColumnBuilderState<string, boolean, string>> = Record<\n never,\n ColumnBuilderState<string, boolean, string>\n >,\n PrimaryKey extends readonly string[] | undefined = undefined,\n> {\n private readonly _state: TableBuilderInternalState<Name, Columns, PrimaryKey>;\n\n /** @internal Use createTable() instead */\n constructor(\n name: Name,\n columns: Columns,\n primaryKey: PrimaryKey,\n primaryKeyName: string | undefined,\n uniques: readonly UniqueConstraintDef[],\n indexes: readonly IndexDef[],\n foreignKeys: readonly ForeignKeyDef[],\n ) {\n this._state = {\n name,\n columns,\n primaryKey,\n primaryKeyName,\n uniques,\n indexes,\n foreignKeys,\n };\n }\n\n private get _name(): Name {\n return this._state.name;\n }\n\n private get _columns(): Columns {\n return this._state.columns;\n }\n\n private get _primaryKey(): PrimaryKey {\n return this._state.primaryKey;\n }\n\n /** Add a nullable column to the table. */\n column<ColName extends string, Descriptor extends ColumnTypeDescriptor>(\n name: ColName,\n options: NullableColumnOptions<Descriptor>,\n ): TableBuilder<\n Name,\n Columns & Record<ColName, ColumnBuilderState<ColName, true, Descriptor['codecId']>>,\n PrimaryKey\n >;\n\n /**\n * Add a non-nullable column to the table.\n * Non-nullable columns can optionally have a default value.\n */\n column<ColName extends string, Descriptor extends ColumnTypeDescriptor>(\n name: ColName,\n options: NonNullableColumnOptions<Descriptor>,\n ): TableBuilder<\n Name,\n Columns & Record<ColName, ColumnBuilderState<ColName, false, Descriptor['codecId']>>,\n PrimaryKey\n >;\n\n /**\n * Implementation of the column method.\n */\n column<ColName extends string, Descriptor extends ColumnTypeDescriptor>(\n name: ColName,\n options: ColumnOptions<Descriptor>,\n ): TableBuilder<\n Name,\n Columns & Record<ColName, ColumnBuilderState<ColName, boolean, Descriptor['codecId']>>,\n PrimaryKey\n > {\n return this.columnInternal(name, options);\n }\n\n generated<ColName extends string, Descriptor extends ColumnTypeDescriptor>(\n name: ColName,\n options: GeneratedColumnOptions<Descriptor>,\n ): TableBuilder<\n Name,\n Columns & Record<ColName, ColumnBuilderState<ColName, false, Descriptor['codecId']>>,\n PrimaryKey\n > {\n const { generated, ...columnOptions } = options;\n return this.columnInternal(name, columnOptions, generated);\n }\n\n private columnInternal<\n ColName extends string,\n Descriptor extends ColumnTypeDescriptor,\n Options extends ColumnOptions<Descriptor>,\n >(\n name: ColName,\n options: Options,\n executionDefault?: ExecutionMutationDefaultValue,\n ): TableBuilder<\n Name,\n Columns &\n Record<\n ColName,\n ColumnBuilderState<ColName, NullableFromOptions<Options>, Descriptor['codecId']>\n >,\n PrimaryKey\n > {\n const nullable = options.nullable ?? false;\n const { codecId, nativeType, typeParams: descriptorTypeParams, typeRef } = options.type;\n const typeParams = options.typeParams ?? descriptorTypeParams;\n\n const columnState = {\n name,\n nullable,\n type: codecId,\n nativeType,\n ...ifDefined('typeParams', typeParams),\n ...ifDefined('typeRef', typeRef),\n ...ifDefined('default', 'default' in options ? options.default : undefined),\n ...ifDefined('executionDefault', executionDefault),\n } as ColumnBuilderState<ColName, NullableFromOptions<Options>, Descriptor['codecId']>;\n const newColumns = { ...this._columns, [name]: columnState } as Columns &\n Record<\n ColName,\n ColumnBuilderState<ColName, NullableFromOptions<Options>, Descriptor['codecId']>\n >;\n return new TableBuilder(\n this._state.name,\n newColumns,\n this._state.primaryKey,\n this._state.primaryKeyName,\n this._state.uniques,\n this._state.indexes,\n this._state.foreignKeys,\n );\n }\n\n primaryKey<PK extends readonly string[]>(\n columns: PK,\n name?: string,\n ): TableBuilder<Name, Columns, PK> {\n return new TableBuilder(\n this._state.name,\n this._state.columns,\n columns,\n name,\n this._state.uniques,\n this._state.indexes,\n this._state.foreignKeys,\n );\n }\n\n unique(columns: readonly string[], name?: string): TableBuilder<Name, Columns, PrimaryKey> {\n const constraint: UniqueConstraintDef = name ? { columns, name } : { columns };\n return new TableBuilder(\n this._state.name,\n this._state.columns,\n this._state.primaryKey,\n this._state.primaryKeyName,\n [...this._state.uniques, constraint],\n this._state.indexes,\n this._state.foreignKeys,\n );\n }\n\n index(columns: readonly string[], name?: string): TableBuilder<Name, Columns, PrimaryKey>;\n index(\n columns: readonly string[],\n options?: IndexOptions,\n ): TableBuilder<Name, Columns, PrimaryKey>;\n index(indexDef: IndexDef): TableBuilder<Name, Columns, PrimaryKey>;\n index(\n columnsOrIndexDef: readonly string[] | IndexDef,\n nameOrOptions?: string | IndexOptions,\n ): TableBuilder<Name, Columns, PrimaryKey> {\n const indexDef: IndexDef = isIndexDef(columnsOrIndexDef)\n ? columnsOrIndexDef\n : {\n columns: columnsOrIndexDef,\n ...(typeof nameOrOptions === 'string' ? { name: nameOrOptions } : {}),\n ...(typeof nameOrOptions === 'object' && nameOrOptions !== null\n ? {\n ...(nameOrOptions.name !== undefined ? { name: nameOrOptions.name } : {}),\n ...(nameOrOptions.using !== undefined ? { using: nameOrOptions.using } : {}),\n ...(nameOrOptions.config !== undefined ? { config: nameOrOptions.config } : {}),\n }\n : {}),\n };\n\n return new TableBuilder(\n this._state.name,\n this._state.columns,\n this._state.primaryKey,\n this._state.primaryKeyName,\n this._state.uniques,\n [...this._state.indexes, indexDef],\n this._state.foreignKeys,\n );\n }\n\n foreignKey(\n columns: readonly string[],\n references: { table: string; columns: readonly string[] },\n opts?: string | (ForeignKeyOptions & { constraint?: boolean; index?: boolean }),\n ): TableBuilder<Name, Columns, PrimaryKey> {\n const resolved = typeof opts === 'string' ? { name: opts } : opts;\n const fkDef: ForeignKeyDef = {\n columns,\n references,\n ...ifDefined('name', resolved?.name),\n ...ifDefined('onDelete', resolved?.onDelete),\n ...ifDefined('onUpdate', resolved?.onUpdate),\n ...ifDefined('constraint', resolved?.constraint),\n ...ifDefined('index', resolved?.index),\n };\n return new TableBuilder(\n this._state.name,\n this._state.columns,\n this._state.primaryKey,\n this._state.primaryKeyName,\n this._state.uniques,\n this._state.indexes,\n [...this._state.foreignKeys, fkDef],\n );\n }\n\n build(): TableBuilderState<Name, Columns, PrimaryKey> {\n return {\n name: this._name,\n columns: this._columns,\n ...(this._primaryKey !== undefined ? { primaryKey: this._primaryKey } : {}),\n ...(this._state.primaryKeyName !== undefined\n ? { primaryKeyName: this._state.primaryKeyName }\n : {}),\n uniques: this._state.uniques,\n indexes: this._state.indexes,\n foreignKeys: this._state.foreignKeys,\n } as TableBuilderState<Name, Columns, PrimaryKey>;\n }\n}\n","import type { TargetPackRef } from '@prisma-next/contract/framework-components';\nimport type {\n ColumnBuilderState,\n ContractBuilderState,\n ForeignKeyDefaultsState,\n ModelBuilderState,\n RelationDefinition,\n TableBuilderState,\n} from './builder-state';\nimport { ModelBuilder } from './model-builder';\nimport { createTable, TableBuilder } from './table-builder';\n\nexport class ContractBuilder<\n Target extends string | undefined = undefined,\n Tables extends Record<\n string,\n TableBuilderState<\n string,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >\n > = Record<never, never>,\n Models extends Record<\n string,\n ModelBuilderState<string, string, Record<string, string>, Record<string, RelationDefinition>>\n > = Record<never, never>,\n StorageHash extends string | undefined = undefined,\n ExtensionPacks extends Record<string, unknown> | undefined = undefined,\n Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,\n> {\n protected readonly state: ContractBuilderState<\n Target,\n Tables,\n Models,\n StorageHash,\n ExtensionPacks,\n Capabilities\n >;\n\n constructor(\n state?: ContractBuilderState<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities>,\n ) {\n this.state =\n state ??\n ({\n tables: {},\n models: {},\n } as ContractBuilderState<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities>);\n }\n\n target<T extends string>(\n packRef: TargetPackRef<string, T>,\n ): ContractBuilder<T, Tables, Models, StorageHash, ExtensionPacks, Capabilities> {\n return new ContractBuilder<T, Tables, Models, StorageHash, ExtensionPacks, Capabilities>({\n ...this.state,\n target: packRef.targetId,\n });\n }\n\n capabilities<C extends Record<string, Record<string, boolean>>>(\n capabilities: C,\n ): ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, C> {\n return new ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, C>({\n ...this.state,\n capabilities,\n });\n }\n\n table<\n TableName extends string,\n T extends TableBuilder<\n TableName,\n Record<string, ColumnBuilderState<string, boolean, string>>,\n readonly string[] | undefined\n >,\n >(\n name: TableName,\n callback: (t: TableBuilder<TableName>) => T | undefined,\n ): ContractBuilder<\n Target,\n Tables & Record<TableName, ReturnType<T['build']>>,\n Models,\n StorageHash,\n ExtensionPacks,\n Capabilities\n > {\n const tableBuilder = createTable(name);\n const result = callback(tableBuilder);\n const finalBuilder = result instanceof TableBuilder ? result : tableBuilder;\n const tableState = finalBuilder.build();\n\n return new ContractBuilder<\n Target,\n Tables & Record<TableName, ReturnType<T['build']>>,\n Models,\n StorageHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n tables: { ...this.state.tables, [name]: tableState } as Tables &\n Record<TableName, ReturnType<T['build']>>,\n });\n }\n\n model<\n ModelName extends string,\n TableName extends string,\n M extends ModelBuilder<\n ModelName,\n TableName,\n Record<string, string>,\n Record<string, RelationDefinition>\n >,\n >(\n name: ModelName,\n table: TableName,\n callback: (\n m: ModelBuilder<ModelName, TableName, Record<never, never>, Record<never, never>>,\n ) => M | undefined,\n ): ContractBuilder<\n Target,\n Tables,\n Models & Record<ModelName, ReturnType<M['build']>>,\n StorageHash,\n ExtensionPacks,\n Capabilities\n > {\n const modelBuilder = new ModelBuilder<ModelName, TableName>(name, table);\n const result = callback(modelBuilder);\n const finalBuilder = result instanceof ModelBuilder ? result : modelBuilder;\n const modelState = finalBuilder.build();\n\n return new ContractBuilder<\n Target,\n Tables,\n Models & Record<ModelName, ReturnType<M['build']>>,\n StorageHash,\n ExtensionPacks,\n Capabilities\n >({\n ...this.state,\n models: { ...this.state.models, [name]: modelState } as Models &\n Record<ModelName, ReturnType<M['build']>>,\n });\n }\n\n storageHash<H extends string>(\n hash: H,\n ): ContractBuilder<Target, Tables, Models, H, ExtensionPacks, Capabilities> {\n return new ContractBuilder<Target, Tables, Models, H, ExtensionPacks, Capabilities>({\n ...this.state,\n storageHash: hash,\n });\n }\n\n foreignKeyDefaults(\n config: ForeignKeyDefaultsState,\n ): ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities> {\n return new ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities>({\n ...this.state,\n foreignKeyDefaults: config,\n });\n }\n}\n\nexport function defineContract(): ContractBuilder {\n return new ContractBuilder();\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,37 +1,45 @@
1
1
  {
2
2
  "name": "@prisma-next/contract-authoring",
3
- "version": "0.3.0-dev.9",
3
+ "version": "0.3.0-dev.91",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Target-agnostic contract authoring builder core for Prisma Next",
7
7
  "dependencies": {
8
8
  "ts-toolbelt": "^9.6.0",
9
- "@prisma-next/contract": "0.3.0-dev.9"
9
+ "@prisma-next/contract": "0.3.0-dev.91",
10
+ "@prisma-next/utils": "0.3.0-dev.91"
10
11
  },
11
12
  "devDependencies": {
12
- "@vitest/coverage-v8": "4.0.16",
13
- "tsup": "8.5.1",
13
+ "tsdown": "0.18.4",
14
14
  "typescript": "5.9.3",
15
- "vitest": "4.0.16"
15
+ "vitest": "4.0.17",
16
+ "@prisma-next/tsdown": "0.0.0",
17
+ "@prisma-next/tsconfig": "0.0.0"
16
18
  },
17
19
  "files": [
18
20
  "dist",
19
21
  "src"
20
22
  ],
21
23
  "exports": {
22
- ".": {
23
- "types": "./dist/index.d.ts",
24
- "import": "./dist/index.js"
25
- }
24
+ ".": "./dist/index.mjs",
25
+ "./package.json": "./package.json"
26
+ },
27
+ "main": "./dist/index.mjs",
28
+ "module": "./dist/index.mjs",
29
+ "types": "./dist/index.d.mts",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/prisma/prisma-next.git",
33
+ "directory": "packages/1-framework/2-authoring/contract"
26
34
  },
27
35
  "scripts": {
28
- "build": "tsup --config tsup.config.ts && tsc --project tsconfig.build.json",
36
+ "build": "tsdown",
29
37
  "test": "vitest run",
30
38
  "test:coverage": "vitest run --coverage",
31
39
  "typecheck": "tsc --project tsconfig.json --noEmit",
32
- "lint": "biome check . --config-path ../../../../biome.json --error-on-warnings",
33
- "lint:fix": "biome check --write . --config-path ../../../../biome.json",
34
- "lint:fix:unsafe": "biome check --write --unsafe . --config-path ../../../../biome.json",
35
- "clean": "node ../../../../scripts/clean.mjs"
40
+ "lint": "biome check . --error-on-warnings",
41
+ "lint:fix": "biome check --write .",
42
+ "lint:fix:unsafe": "biome check --write --unsafe .",
43
+ "clean": "rm -rf dist dist-tsc dist-tsc-prod coverage .tmp-output"
36
44
  }
37
45
  }
@@ -1,21 +1,106 @@
1
+ import type { ColumnDefault, ExecutionMutationDefaultValue } from '@prisma-next/contract/types';
2
+
3
+ /**
4
+ * Duplicated from sql-contract to avoid cross-layer dependency
5
+ * (framework authoring cannot depend on the SQL domain's contract package).
6
+ */
7
+ export type ReferentialAction = 'noAction' | 'restrict' | 'cascade' | 'setNull' | 'setDefault';
8
+
1
9
  /**
2
10
  * Column type descriptor containing both codec ID and native type.
3
11
  * Used when defining columns with descriptor objects instead of string IDs.
12
+ *
13
+ * For parameterized types (e.g., `vector(1536)`), the `typeParams` field
14
+ * carries codec-owned parameters that affect both TypeScript type generation
15
+ * and native DDL output.
4
16
  */
5
17
  export type ColumnTypeDescriptor = {
6
18
  readonly codecId: string;
7
19
  readonly nativeType: string;
20
+ readonly typeParams?: Record<string, unknown>;
21
+ readonly typeRef?: string;
8
22
  };
9
23
 
10
- export interface ColumnBuilderState<
11
- Name extends string,
12
- Nullable extends boolean,
13
- Type extends string,
14
- > {
24
+ /**
25
+ * Base column properties shared by all column states.
26
+ */
27
+ type ColumnBuilderStateBase<Name extends string, Type extends string> = {
15
28
  readonly name: Name;
16
- readonly nullable: Nullable;
17
29
  readonly type: Type;
18
30
  readonly nativeType: string;
31
+ readonly typeParams?: Record<string, unknown>;
32
+ readonly typeRef?: string;
33
+ };
34
+
35
+ export type StorageTypeInstanceState = {
36
+ readonly codecId: string;
37
+ readonly nativeType: string;
38
+ readonly typeParams: Record<string, unknown>;
39
+ };
40
+
41
+ /**
42
+ * Column builder state.
43
+ *
44
+ * Both nullable and non-nullable columns can define defaults to match database behavior.
45
+ */
46
+ export type ColumnBuilderState<
47
+ Name extends string,
48
+ Nullable extends boolean,
49
+ Type extends string,
50
+ > = ColumnBuilderStateBase<Name, Type> &
51
+ (Nullable extends true
52
+ ? { readonly nullable: true; readonly default?: ColumnDefault }
53
+ : {
54
+ readonly nullable: false;
55
+ readonly default?: ColumnDefault;
56
+ readonly executionDefault?: ExecutionMutationDefaultValue;
57
+ });
58
+
59
+ /**
60
+ * Unique constraint definition for table builder.
61
+ */
62
+ export interface UniqueConstraintDef {
63
+ readonly columns: readonly string[];
64
+ readonly name?: string;
65
+ }
66
+
67
+ /**
68
+ * Index definition for table builder.
69
+ */
70
+ export interface IndexDef {
71
+ readonly columns: readonly string[];
72
+ readonly name?: string;
73
+ /**
74
+ * Optional index access method. Extension-specific methods are represented
75
+ * as strings and interpreted by the owning extension package.
76
+ */
77
+ readonly using?: string;
78
+ /**
79
+ * Optional extension-owned index configuration payload.
80
+ */
81
+ readonly config?: Record<string, unknown>;
82
+ }
83
+
84
+ /**
85
+ * Options for configuring a foreign key's name and referential actions.
86
+ */
87
+ export type ForeignKeyOptions = {
88
+ readonly name?: string;
89
+ readonly onDelete?: ReferentialAction;
90
+ readonly onUpdate?: ReferentialAction;
91
+ };
92
+
93
+ /**
94
+ * Foreign key definition for table builder.
95
+ */
96
+ export interface ForeignKeyDef extends ForeignKeyOptions {
97
+ readonly columns: readonly string[];
98
+ readonly references: {
99
+ readonly table: string;
100
+ readonly columns: readonly string[];
101
+ };
102
+ readonly constraint?: boolean;
103
+ readonly index?: boolean;
19
104
  }
20
105
 
21
106
  export interface TableBuilderState<
@@ -26,6 +111,10 @@ export interface TableBuilderState<
26
111
  readonly name: Name;
27
112
  readonly columns: Columns;
28
113
  readonly primaryKey?: PrimaryKey;
114
+ readonly primaryKeyName?: string;
115
+ readonly uniques: readonly UniqueConstraintDef[];
116
+ readonly indexes: readonly IndexDef[];
117
+ readonly foreignKeys: readonly ForeignKeyDef[];
29
118
  }
30
119
 
31
120
  export type RelationDefinition = {
@@ -54,6 +143,11 @@ export interface ModelBuilderState<
54
143
  readonly relations: Relations;
55
144
  }
56
145
 
146
+ export interface ForeignKeyDefaultsState {
147
+ readonly constraint: boolean;
148
+ readonly index: boolean;
149
+ }
150
+
57
151
  export interface ContractBuilderState<
58
152
  Target extends string | undefined = string | undefined,
59
153
  Tables extends Record<
@@ -78,16 +172,18 @@ export interface ContractBuilderState<
78
172
  never,
79
173
  ModelBuilderState<string, string, Record<string, string>, Record<string, RelationDefinition>>
80
174
  >,
81
- CoreHash extends string | undefined = string | undefined,
175
+ StorageHash extends string | undefined = string | undefined,
82
176
  ExtensionPacks extends Record<string, unknown> | undefined = undefined,
83
177
  Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
84
178
  > {
85
179
  readonly target?: Target;
86
180
  readonly tables: Tables;
87
181
  readonly models: Models;
88
- readonly coreHash?: CoreHash;
182
+ readonly storageHash?: StorageHash;
89
183
  readonly extensionPacks?: ExtensionPacks;
90
184
  readonly capabilities?: Capabilities;
185
+ readonly storageTypes?: Record<string, StorageTypeInstanceState>;
186
+ readonly foreignKeyDefaults?: ForeignKeyDefaultsState;
91
187
  /**
92
188
  * Array of extension pack namespace identifiers (e.g., ['pgvector', 'postgis']).
93
189
  * Populated when extension packs are registered during contract building.
@@ -2,12 +2,13 @@ import type { TargetPackRef } from '@prisma-next/contract/framework-components';
2
2
  import type {
3
3
  ColumnBuilderState,
4
4
  ContractBuilderState,
5
+ ForeignKeyDefaultsState,
5
6
  ModelBuilderState,
6
7
  RelationDefinition,
7
8
  TableBuilderState,
8
9
  } from './builder-state';
9
10
  import { ModelBuilder } from './model-builder';
10
- import { TableBuilder } from './table-builder';
11
+ import { createTable, TableBuilder } from './table-builder';
11
12
 
12
13
  export class ContractBuilder<
13
14
  Target extends string | undefined = undefined,
@@ -23,7 +24,7 @@ export class ContractBuilder<
23
24
  string,
24
25
  ModelBuilderState<string, string, Record<string, string>, Record<string, RelationDefinition>>
25
26
  > = Record<never, never>,
26
- CoreHash extends string | undefined = undefined,
27
+ StorageHash extends string | undefined = undefined,
27
28
  ExtensionPacks extends Record<string, unknown> | undefined = undefined,
28
29
  Capabilities extends Record<string, Record<string, boolean>> | undefined = undefined,
29
30
  > {
@@ -31,26 +32,26 @@ export class ContractBuilder<
31
32
  Target,
32
33
  Tables,
33
34
  Models,
34
- CoreHash,
35
+ StorageHash,
35
36
  ExtensionPacks,
36
37
  Capabilities
37
38
  >;
38
39
 
39
40
  constructor(
40
- state?: ContractBuilderState<Target, Tables, Models, CoreHash, ExtensionPacks, Capabilities>,
41
+ state?: ContractBuilderState<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities>,
41
42
  ) {
42
43
  this.state =
43
44
  state ??
44
45
  ({
45
46
  tables: {},
46
47
  models: {},
47
- } as ContractBuilderState<Target, Tables, Models, CoreHash, ExtensionPacks, Capabilities>);
48
+ } as ContractBuilderState<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities>);
48
49
  }
49
50
 
50
51
  target<T extends string>(
51
52
  packRef: TargetPackRef<string, T>,
52
- ): ContractBuilder<T, Tables, Models, CoreHash, ExtensionPacks, Capabilities> {
53
- return new ContractBuilder<T, Tables, Models, CoreHash, ExtensionPacks, Capabilities>({
53
+ ): ContractBuilder<T, Tables, Models, StorageHash, ExtensionPacks, Capabilities> {
54
+ return new ContractBuilder<T, Tables, Models, StorageHash, ExtensionPacks, Capabilities>({
54
55
  ...this.state,
55
56
  target: packRef.targetId,
56
57
  });
@@ -58,8 +59,8 @@ export class ContractBuilder<
58
59
 
59
60
  capabilities<C extends Record<string, Record<string, boolean>>>(
60
61
  capabilities: C,
61
- ): ContractBuilder<Target, Tables, Models, CoreHash, ExtensionPacks, C> {
62
- return new ContractBuilder<Target, Tables, Models, CoreHash, ExtensionPacks, C>({
62
+ ): ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, C> {
63
+ return new ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, C>({
63
64
  ...this.state,
64
65
  capabilities,
65
66
  });
@@ -79,11 +80,11 @@ export class ContractBuilder<
79
80
  Target,
80
81
  Tables & Record<TableName, ReturnType<T['build']>>,
81
82
  Models,
82
- CoreHash,
83
+ StorageHash,
83
84
  ExtensionPacks,
84
85
  Capabilities
85
86
  > {
86
- const tableBuilder = new TableBuilder<TableName>(name);
87
+ const tableBuilder = createTable(name);
87
88
  const result = callback(tableBuilder);
88
89
  const finalBuilder = result instanceof TableBuilder ? result : tableBuilder;
89
90
  const tableState = finalBuilder.build();
@@ -92,7 +93,7 @@ export class ContractBuilder<
92
93
  Target,
93
94
  Tables & Record<TableName, ReturnType<T['build']>>,
94
95
  Models,
95
- CoreHash,
96
+ StorageHash,
96
97
  ExtensionPacks,
97
98
  Capabilities
98
99
  >({
@@ -115,13 +116,13 @@ export class ContractBuilder<
115
116
  name: ModelName,
116
117
  table: TableName,
117
118
  callback: (
118
- m: ModelBuilder<ModelName, TableName, Record<string, string>, Record<never, never>>,
119
+ m: ModelBuilder<ModelName, TableName, Record<never, never>, Record<never, never>>,
119
120
  ) => M | undefined,
120
121
  ): ContractBuilder<
121
122
  Target,
122
123
  Tables,
123
124
  Models & Record<ModelName, ReturnType<M['build']>>,
124
- CoreHash,
125
+ StorageHash,
125
126
  ExtensionPacks,
126
127
  Capabilities
127
128
  > {
@@ -134,7 +135,7 @@ export class ContractBuilder<
134
135
  Target,
135
136
  Tables,
136
137
  Models & Record<ModelName, ReturnType<M['build']>>,
137
- CoreHash,
138
+ StorageHash,
138
139
  ExtensionPacks,
139
140
  Capabilities
140
141
  >({
@@ -144,12 +145,21 @@ export class ContractBuilder<
144
145
  });
145
146
  }
146
147
 
147
- coreHash<H extends string>(
148
+ storageHash<H extends string>(
148
149
  hash: H,
149
150
  ): ContractBuilder<Target, Tables, Models, H, ExtensionPacks, Capabilities> {
150
151
  return new ContractBuilder<Target, Tables, Models, H, ExtensionPacks, Capabilities>({
151
152
  ...this.state,
152
- coreHash: hash,
153
+ storageHash: hash,
154
+ });
155
+ }
156
+
157
+ foreignKeyDefaults(
158
+ config: ForeignKeyDefaultsState,
159
+ ): ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities> {
160
+ return new ContractBuilder<Target, Tables, Models, StorageHash, ExtensionPacks, Capabilities>({
161
+ ...this.state,
162
+ foreignKeyDefaults: config,
153
163
  });
154
164
  }
155
165
  }
package/src/index.ts CHANGED
@@ -3,14 +3,19 @@ export type {
3
3
  ColumnBuilderState,
4
4
  ColumnTypeDescriptor,
5
5
  ContractBuilderState,
6
+ ForeignKeyDef,
7
+ ForeignKeyDefaultsState,
8
+ ForeignKeyOptions,
9
+ IndexDef,
6
10
  ModelBuilderState,
7
11
  RelationDefinition,
8
12
  TableBuilderState,
13
+ UniqueConstraintDef,
9
14
  } from './builder-state';
10
15
 
11
16
  export { ContractBuilder, defineContract } from './contract-builder';
12
17
  export { ModelBuilder } from './model-builder';
13
- export { TableBuilder } from './table-builder';
18
+ export { createTable, TableBuilder } from './table-builder';
14
19
 
15
20
  export type {
16
21
  BuildModelFields,