@prisma-next/sql-relational-core 0.12.0-dev.9 → 0.13.0-dev.1

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.
Files changed (72) hide show
  1. package/dist/{codec-types-Cezo7k-i.d.mts → codec-types-DFLA6Hmj.d.mts} +6 -4
  2. package/dist/codec-types-DFLA6Hmj.d.mts.map +1 -0
  3. package/dist/ddl-types-D3vlEjMA.d.mts +126 -0
  4. package/dist/ddl-types-D3vlEjMA.d.mts.map +1 -0
  5. package/dist/ddl-types-X9_XHUl0.mjs +130 -0
  6. package/dist/ddl-types-X9_XHUl0.mjs.map +1 -0
  7. package/dist/{errors-BF7W5uUd.mjs → errors-BwyJxXME.mjs} +1 -1
  8. package/dist/{errors-BF7W5uUd.mjs.map → errors-BwyJxXME.mjs.map} +1 -1
  9. package/dist/{errors-DyOlJVVe.d.mts → errors-CPLfzKkw.d.mts} +2 -2
  10. package/dist/{errors-DyOlJVVe.d.mts.map → errors-CPLfzKkw.d.mts.map} +1 -1
  11. package/dist/exports/ast.d.mts +11 -15
  12. package/dist/exports/ast.d.mts.map +1 -1
  13. package/dist/exports/ast.mjs +4 -3
  14. package/dist/exports/ast.mjs.map +1 -1
  15. package/dist/exports/codec-descriptor-registry.d.mts +8 -4
  16. package/dist/exports/codec-descriptor-registry.d.mts.map +1 -1
  17. package/dist/exports/codec-descriptor-registry.mjs +24 -26
  18. package/dist/exports/codec-descriptor-registry.mjs.map +1 -1
  19. package/dist/exports/contract-free.d.mts +161 -0
  20. package/dist/exports/contract-free.d.mts.map +1 -0
  21. package/dist/exports/contract-free.mjs +268 -0
  22. package/dist/exports/contract-free.mjs.map +1 -0
  23. package/dist/exports/errors.d.mts +1 -1
  24. package/dist/exports/errors.mjs +1 -1
  25. package/dist/exports/expression.d.mts +2 -2
  26. package/dist/exports/expression.d.mts.map +1 -1
  27. package/dist/exports/expression.mjs +1 -1
  28. package/dist/exports/middleware.d.mts +2 -2
  29. package/dist/exports/middleware.mjs +1 -1
  30. package/dist/exports/plan.d.mts +2 -2
  31. package/dist/exports/query-lane-context.d.mts +1 -1
  32. package/dist/exports/types.d.mts +3 -3
  33. package/dist/index.d.mts +12 -11
  34. package/dist/index.mjs +6 -5
  35. package/dist/{middleware-wAl5AE2L.d.mts → middleware-BXSFukKU.d.mts} +2 -2
  36. package/dist/{middleware-wAl5AE2L.d.mts.map → middleware-BXSFukKU.d.mts.map} +1 -1
  37. package/dist/{middleware-B0yz0pff.mjs → middleware-CMr4CHNz.mjs} +2 -2
  38. package/dist/{middleware-B0yz0pff.mjs.map → middleware-CMr4CHNz.mjs.map} +1 -1
  39. package/dist/{plan-DOddRU_l.d.mts → plan-DObuWSWi.d.mts} +3 -3
  40. package/dist/plan-DObuWSWi.d.mts.map +1 -0
  41. package/dist/{query-lane-context-Dw1Tz0kv.d.mts → query-lane-context-CY0-e8Qo.d.mts} +8 -6
  42. package/dist/query-lane-context-CY0-e8Qo.d.mts.map +1 -0
  43. package/dist/{sql-execution-plan-DeBoZUre.d.mts → sql-execution-plan-JwVeAzXt.d.mts} +2 -2
  44. package/dist/{sql-execution-plan-DeBoZUre.d.mts.map → sql-execution-plan-JwVeAzXt.d.mts.map} +1 -1
  45. package/dist/{types-BKeEhnEl.d.mts → types-BbGUx5Bi.d.mts} +13 -6
  46. package/dist/types-BbGUx5Bi.d.mts.map +1 -0
  47. package/dist/{types-ptGgzUQd.d.mts → types-CQVke4QO.d.mts} +7 -7
  48. package/dist/{types-ptGgzUQd.d.mts.map → types-CQVke4QO.d.mts.map} +1 -1
  49. package/dist/{types-BS8Mm93x.mjs → types-D72v8s92.mjs} +16 -5
  50. package/dist/{types-BS8Mm93x.mjs.map → types-D72v8s92.mjs.map} +1 -1
  51. package/dist/{types-CkfUpAlx.d.mts → types-LGikJRYV.d.mts} +3 -3
  52. package/dist/{types-CkfUpAlx.d.mts.map → types-LGikJRYV.d.mts.map} +1 -1
  53. package/dist/{util-DWmhUCEO.mjs → util-DQQgv2j1.mjs} +1 -1
  54. package/dist/{util-DWmhUCEO.mjs.map → util-DQQgv2j1.mjs.map} +1 -1
  55. package/package.json +14 -13
  56. package/src/ast/adapter-types.ts +0 -5
  57. package/src/ast/codec-types.ts +5 -3
  58. package/src/ast/ddl-types.ts +198 -0
  59. package/src/ast/types.ts +22 -6
  60. package/src/codec-descriptor-registry.ts +2 -2
  61. package/src/codec-ref-for-column.ts +26 -20
  62. package/src/contract-free/column.ts +56 -0
  63. package/src/contract-free/dml.ts +17 -0
  64. package/src/contract-free/table.ts +390 -0
  65. package/src/exports/ast.ts +1 -0
  66. package/src/exports/contract-free.ts +26 -0
  67. package/src/query-lane-context.ts +5 -3
  68. package/src/types.ts +3 -3
  69. package/dist/codec-types-Cezo7k-i.d.mts.map +0 -1
  70. package/dist/plan-DOddRU_l.d.mts.map +0 -1
  71. package/dist/query-lane-context-Dw1Tz0kv.d.mts.map +0 -1
  72. package/dist/types-BKeEhnEl.d.mts.map +0 -1
@@ -0,0 +1,198 @@
1
+ import type { ColumnDefaultLiteralInputValue } from '@prisma-next/contract/types';
2
+ import { isColumnDefaultLiteralInputValue } from '@prisma-next/contract/types';
3
+ import type { ReferentialAction } from '@prisma-next/sql-contract/types';
4
+ import type { AnyParamRef } from './types';
5
+
6
+ /**
7
+ * Render-time context the column-default visitor needs to make dialect
8
+ * decisions that depend on the parent column. Today only the parent
9
+ * column's native type (`"jsonb"`, `"text"`, …) — the Postgres renderer
10
+ * uses it to decide whether to emit a `::jsonb` / `::json` cast on JSON
11
+ * literal defaults so the emitted DDL matches the column type without
12
+ * relying on Postgres's implicit text → jsonb cast at default-evaluation
13
+ * time. Additional fields can join without re-shaping the interface.
14
+ */
15
+ export interface DdlColumnRenderContext {
16
+ readonly nativeType: string;
17
+ }
18
+
19
+ export interface DdlColumnDefaultVisitor<R> {
20
+ literal(node: LiteralColumnDefault, ctx: DdlColumnRenderContext): R;
21
+ function(node: FunctionColumnDefault, ctx: DdlColumnRenderContext): R;
22
+ }
23
+
24
+ export abstract class DdlColumnDefault {
25
+ abstract readonly kind: string;
26
+ abstract accept<R>(visitor: DdlColumnDefaultVisitor<R>, ctx: DdlColumnRenderContext): R;
27
+
28
+ protected freeze(): void {
29
+ Object.freeze(this);
30
+ }
31
+ }
32
+
33
+ export class LiteralColumnDefault extends DdlColumnDefault {
34
+ readonly kind = 'literal' as const;
35
+ readonly value: ColumnDefaultLiteralInputValue;
36
+
37
+ constructor(value: ColumnDefaultLiteralInputValue) {
38
+ super();
39
+ if (!isColumnDefaultLiteralInputValue(value)) {
40
+ throw new Error('Invalid column default literal value');
41
+ }
42
+ this.value = value;
43
+ this.freeze();
44
+ }
45
+
46
+ override accept<R>(visitor: DdlColumnDefaultVisitor<R>, ctx: DdlColumnRenderContext): R {
47
+ return visitor.literal(this, ctx);
48
+ }
49
+ }
50
+
51
+ export class FunctionColumnDefault extends DdlColumnDefault {
52
+ readonly kind = 'function' as const;
53
+ readonly expression: string;
54
+
55
+ constructor(expression: string) {
56
+ super();
57
+ this.expression = expression;
58
+ this.freeze();
59
+ }
60
+
61
+ override accept<R>(visitor: DdlColumnDefaultVisitor<R>, ctx: DdlColumnRenderContext): R {
62
+ return visitor.function(this, ctx);
63
+ }
64
+ }
65
+
66
+ export type AnyDdlColumnDefault = LiteralColumnDefault | FunctionColumnDefault;
67
+
68
+ export class DdlColumn {
69
+ readonly name: string;
70
+ readonly type: string;
71
+ readonly notNull?: boolean | undefined;
72
+ readonly primaryKey?: boolean | undefined;
73
+ readonly default?: AnyDdlColumnDefault | undefined;
74
+
75
+ constructor(options: {
76
+ readonly name: string;
77
+ readonly type: string;
78
+ readonly notNull?: boolean;
79
+ readonly primaryKey?: boolean;
80
+ readonly default?: AnyDdlColumnDefault;
81
+ }) {
82
+ this.name = options.name;
83
+ this.type = options.type;
84
+ this.notNull = options.notNull;
85
+ this.primaryKey = options.primaryKey;
86
+ this.default = options.default;
87
+ Object.freeze(this);
88
+ }
89
+ }
90
+
91
+ export abstract class DdlNode {
92
+ abstract readonly kind: string;
93
+
94
+ /**
95
+ * Structural brand: every DDL node answers `true`. Lets {@link isDdlNode}
96
+ * recognise any `DdlNode` subclass — including target-contributed kinds —
97
+ * without a central kind registry that subclasses would have to register
98
+ * into.
99
+ */
100
+ isDdlNode(): true {
101
+ return true;
102
+ }
103
+
104
+ protected freeze(): void {
105
+ Object.freeze(this);
106
+ }
107
+
108
+ collectParamRefs(): AnyParamRef[] {
109
+ return [];
110
+ }
111
+ }
112
+
113
+ export function isDdlNode(value: unknown): value is DdlNode {
114
+ return (
115
+ typeof value === 'object' &&
116
+ value !== null &&
117
+ 'isDdlNode' in value &&
118
+ typeof value.isDdlNode === 'function'
119
+ );
120
+ }
121
+
122
+ // ---------------------------------------------------------------------------
123
+ // Table-level constraint nodes
124
+ // ---------------------------------------------------------------------------
125
+
126
+ /**
127
+ * A composite (or single-column) PRIMARY KEY constraint on a `CreateTable`
128
+ * node. When `name` is set, the adapter renders `CONSTRAINT <name> PRIMARY KEY
129
+ * (…)`; otherwise it renders an anonymous `PRIMARY KEY (…)`.
130
+ *
131
+ * Frozen on construction — immutable after creation.
132
+ */
133
+ export class PrimaryKeyConstraint {
134
+ readonly kind = 'primary-key' as const;
135
+ readonly columns: ReadonlyArray<string>;
136
+ readonly name: string | undefined;
137
+
138
+ constructor(options: { readonly columns: readonly string[]; readonly name?: string }) {
139
+ this.columns = Object.freeze([...options.columns]);
140
+ this.name = options.name;
141
+ Object.freeze(this);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * A FOREIGN KEY constraint on a `CreateTable` node. `onDelete` and `onUpdate`
147
+ * use the same `ReferentialAction` vocabulary already used by the migration
148
+ * planner and the contract IR — no parallel string enum.
149
+ *
150
+ * Frozen on construction — immutable after creation.
151
+ */
152
+ export class ForeignKeyConstraint {
153
+ readonly kind = 'foreign-key' as const;
154
+ readonly columns: ReadonlyArray<string>;
155
+ readonly refTable: string;
156
+ readonly refColumns: ReadonlyArray<string>;
157
+ readonly onDelete: ReferentialAction | undefined;
158
+ readonly onUpdate: ReferentialAction | undefined;
159
+ readonly name: string | undefined;
160
+
161
+ constructor(options: {
162
+ readonly columns: readonly string[];
163
+ readonly refTable: string;
164
+ readonly refColumns: readonly string[];
165
+ readonly onDelete?: ReferentialAction;
166
+ readonly onUpdate?: ReferentialAction;
167
+ readonly name?: string;
168
+ }) {
169
+ this.columns = Object.freeze([...options.columns]);
170
+ this.refTable = options.refTable;
171
+ this.refColumns = Object.freeze([...options.refColumns]);
172
+ this.onDelete = options.onDelete;
173
+ this.onUpdate = options.onUpdate;
174
+ this.name = options.name;
175
+ Object.freeze(this);
176
+ }
177
+ }
178
+
179
+ /**
180
+ * A table-level UNIQUE constraint on a `CreateTable` node. When `name` is
181
+ * set, the adapter renders `CONSTRAINT <name> UNIQUE (…)`; otherwise it
182
+ * renders an anonymous `UNIQUE (…)`.
183
+ *
184
+ * Frozen on construction — immutable after creation.
185
+ */
186
+ export class UniqueConstraint {
187
+ readonly kind = 'unique' as const;
188
+ readonly columns: ReadonlyArray<string>;
189
+ readonly name: string | undefined;
190
+
191
+ constructor(options: { readonly columns: readonly string[]; readonly name?: string }) {
192
+ this.columns = Object.freeze([...options.columns]);
193
+ this.name = options.name;
194
+ Object.freeze(this);
195
+ }
196
+ }
197
+
198
+ export type DdlTableConstraint = PrimaryKeyConstraint | ForeignKeyConstraint | UniqueConstraint;
package/src/ast/types.ts CHANGED
@@ -80,7 +80,7 @@ export interface ExpressionFolder<T> {
80
80
  }
81
81
 
82
82
  export type ProjectionExpr = AnyExpression;
83
- export type InsertValue = ColumnRef | ParamRef | PreparedParamRef | DefaultValueExpr;
83
+ export type InsertValue = ColumnRef | ParamRef | PreparedParamRef | DefaultValueExpr | RawExpr;
84
84
  export type JoinOnExpr = EqColJoinOn | AnyExpression;
85
85
  export type WhereArg = AnyExpression | ToWhereExpr;
86
86
  export type JsonObjectEntry = {
@@ -205,6 +205,11 @@ function rewriteInsertValue(value: InsertValue, rewriter: AstRewriter): InsertVa
205
205
  return rewriter.columnRef ? rewriteColumnRefForInsert(value, rewriter) : value;
206
206
  case 'default-value':
207
207
  return value;
208
+ // RawExpr insert values are opaque DB-side expressions (e.g. `now()` /
209
+ // `datetime('now')`) carried in value position; they are not a rewrite
210
+ // target on the insert path.
211
+ case 'raw-expr':
212
+ return value;
208
213
  }
209
214
  }
210
215
 
@@ -312,16 +317,25 @@ export class TableSource extends FromSource {
312
317
  readonly kind = 'table-source' as const;
313
318
  readonly name: string;
314
319
  readonly alias: string | undefined;
320
+ /**
321
+ * Resolved storage namespace coordinate for this table, stamped when the
322
+ * table proxy constructs the AST. Renderers qualify via the namespace
323
+ * concretion's `qualifyTable()` using this id — never by re-resolving the
324
+ * bare table name at render time.
325
+ */
326
+ readonly namespaceId: string | undefined;
315
327
 
316
- constructor(name: string, alias?: string) {
328
+ protected constructor(name: string, alias?: string, namespaceId?: string) {
317
329
  super();
318
330
  this.name = name;
319
331
  this.alias = alias;
320
- this.freeze();
332
+ this.namespaceId = namespaceId;
321
333
  }
322
334
 
323
- static named(name: string, alias?: string): TableSource {
324
- return new TableSource(name, alias);
335
+ static named(name: string, alias?: string, namespaceId?: string): TableSource {
336
+ const source = new TableSource(name, alias, namespaceId);
337
+ source.freeze();
338
+ return source;
325
339
  }
326
340
 
327
341
  override rewrite(rewriter: AstRewriter): AnyFromSource {
@@ -1683,6 +1697,8 @@ export class InsertAst extends QueryAst {
1683
1697
  for (const value of Object.values(row)) {
1684
1698
  if (value.kind === 'param-ref' || value.kind === 'prepared-param-ref') {
1685
1699
  refs.push(value);
1700
+ } else if (value.kind === 'raw-expr') {
1701
+ refs.push(...value.collectParamRefs());
1686
1702
  }
1687
1703
  }
1688
1704
  }
@@ -1906,7 +1922,7 @@ export type AnyExpression =
1906
1922
  | RawExpr;
1907
1923
  export type AnyParamRef = ParamRef | PreparedParamRef;
1908
1924
  export type AnyInsertOnConflictAction = DoNothingConflictAction | DoUpdateSetConflictAction;
1909
- export type AnyInsertValue = ColumnRef | ParamRef | PreparedParamRef | DefaultValueExpr;
1925
+ export type AnyInsertValue = ColumnRef | ParamRef | PreparedParamRef | DefaultValueExpr | RawExpr;
1910
1926
  export type AnyOperationArg = AnyExpression | ParamRef | PreparedParamRef | LiteralExpr;
1911
1927
 
1912
1928
  export const queryAstKinds: ReadonlySet<string> = new Set<AnyQueryAst['kind']>([
@@ -45,9 +45,9 @@ export function buildCodecDescriptorRegistry(
45
45
  descriptorFor(codecId: string): AnyDescriptor | undefined {
46
46
  return byId.get(codecId);
47
47
  },
48
- codecRefForColumn(table: string, column: string): CodecRef | undefined {
48
+ codecRefForColumn(namespaceId: string, table: string, column: string): CodecRef | undefined {
49
49
  if (!storage) return undefined;
50
- return codecRefForStorageColumn(storage, table, column);
50
+ return codecRefForStorageColumn(storage, namespaceId, table, column);
51
51
  },
52
52
  *values(): IterableIterator<AnyDescriptor> {
53
53
  yield* byId.values();
@@ -1,50 +1,47 @@
1
1
  import type { JsonValue } from '@prisma-next/contract/types';
2
2
  import type { CodecRef } from '@prisma-next/framework-components/codec';
3
+ import { resolveStorageTable } from '@prisma-next/sql-contract/resolve-storage-table';
3
4
  import {
4
5
  isPostgresEnumStorageEntry,
5
6
  isStorageTypeInstance,
6
7
  type SqlStorage,
7
- type StorageTable,
8
8
  } from '@prisma-next/sql-contract/types';
9
9
 
10
10
  /**
11
11
  * Derive the canonical {@link CodecRef} for a `(table, column)` pair against a {@link SqlStorage}. This is the build-time path every column-bound `ParamRef` / `ProjectionItem` uses to stamp its `codec` slot before the AST is handed to the runtime — the runtime resolver then materialises a memoised {@link import('@prisma-next/sql-relational-core/ast').Codec} for the same `CodecRef` via `forCodecRef`.
12
12
  *
13
- * Resolution rules over `storage.tables[table].columns[column]`:
13
+ * Resolution rules over namespace `entries.table[table].columns[column]`:
14
14
  *
15
15
  * - `typeRef` column → `{codecId, typeParams}` from `storage.types[typeRef]` (multiple columns sharing the typeRef share one ref → one memoised codec).
16
16
  * - inline `typeParams` column → `{codecId, typeParams}` from the column itself.
17
17
  * - non-parameterized column → `{codecId}` with `typeParams` undefined.
18
18
  *
19
19
  * Returns `undefined` when the table or column is unknown, or when a `typeRef` column references a `storage.types` entry that does not exist.
20
+ *
21
+ * `namespaceId` leads the coordinate args and is always supplied: every
22
+ * model/table sits in an explicit namespace, so the table is resolved strictly
23
+ * within that namespace (see {@link resolveStorageTable}).
20
24
  */
21
25
  export function codecRefForStorageColumn(
22
26
  storage: SqlStorage,
27
+ namespaceId: string,
23
28
  tableName: string,
24
29
  columnName: string,
25
30
  ): CodecRef | undefined {
26
- let tableDef: StorageTable | undefined;
27
- for (const ns of Object.values(storage.namespaces)) {
28
- const candidate = ns.tables[tableName] as StorageTable | undefined;
29
- if (candidate !== undefined) {
30
- tableDef = candidate;
31
- break;
32
- }
33
- }
34
- if (!tableDef) return undefined;
31
+ const resolved = resolveStorageTable(storage, tableName, namespaceId);
32
+ if (resolved === undefined) return undefined;
33
+ const tableDef = resolved.table;
35
34
  const columnDef = tableDef.columns[columnName];
36
35
  if (!columnDef) return undefined;
37
36
  if (columnDef.typeRef !== undefined) {
38
37
  let instance: unknown = storage.types?.[columnDef.typeRef];
39
38
  if (!instance) {
40
39
  for (const ns of Object.values(storage.namespaces)) {
41
- const nsEnums = (ns as { enum?: Record<string, unknown> }).enum;
42
- if (nsEnums) {
43
- const nsEntry = nsEnums[columnDef.typeRef];
44
- if (nsEntry !== undefined) {
45
- instance = nsEntry;
46
- break;
47
- }
40
+ const typeSlot = (ns.entries as { type?: Record<string, unknown> }).type;
41
+ const nsEntry = typeSlot?.[columnDef.typeRef];
42
+ if (nsEntry !== undefined) {
43
+ instance = nsEntry;
44
+ break;
48
45
  }
49
46
  }
50
47
  }
@@ -64,11 +61,20 @@ export function codecRefForStorageColumn(
64
61
  };
65
62
  }
66
63
  if (isStorageTypeInstance(instance)) {
67
- return { codecId: instance.codecId, typeParams: instance.typeParams as JsonValue };
64
+ // Empty-state canonicalization: a `StorageTypeInstance` with absent
65
+ // (or empty) `typeParams` produces a `CodecRef` with no `typeParams`
66
+ // field. Equivalent to the non-parameterized-column branch below.
67
+ // Carrying `{}` here would break content-keyed memoisation and trip
68
+ // the runtime validator against non-parameterized codec descriptors.
69
+ const instanceParams = instance.typeParams;
70
+ const hasParamKeys = instanceParams !== undefined && Object.keys(instanceParams).length > 0;
71
+ return hasParamKeys
72
+ ? { codecId: instance.codecId, typeParams: instanceParams as JsonValue }
73
+ : { codecId: instance.codecId };
68
74
  }
69
75
  return undefined;
70
76
  }
71
- if (columnDef.typeParams !== undefined) {
77
+ if (columnDef.typeParams !== undefined && Object.keys(columnDef.typeParams).length > 0) {
72
78
  return { codecId: columnDef.codecId, typeParams: columnDef.typeParams as JsonValue };
73
79
  }
74
80
  return { codecId: columnDef.codecId };
@@ -0,0 +1,56 @@
1
+ import type { ColumnDefaultLiteralInputValue } from '@prisma-next/contract/types';
2
+ import type { ReferentialAction } from '@prisma-next/sql-contract/types';
3
+ import type { AnyDdlColumnDefault } from '../ast/ddl-types';
4
+ import {
5
+ DdlColumn,
6
+ ForeignKeyConstraint,
7
+ FunctionColumnDefault,
8
+ LiteralColumnDefault,
9
+ PrimaryKeyConstraint,
10
+ UniqueConstraint,
11
+ } from '../ast/ddl-types';
12
+
13
+ export interface DdlColumnOptions {
14
+ readonly notNull?: boolean;
15
+ readonly primaryKey?: boolean;
16
+ readonly default?: AnyDdlColumnDefault;
17
+ }
18
+
19
+ export function lit(value: ColumnDefaultLiteralInputValue): LiteralColumnDefault {
20
+ return new LiteralColumnDefault(value);
21
+ }
22
+
23
+ export function fn(expression: string): FunctionColumnDefault {
24
+ return new FunctionColumnDefault(expression);
25
+ }
26
+
27
+ export function col(name: string, type: string, options?: DdlColumnOptions): DdlColumn {
28
+ return new DdlColumn({ name, type, ...options });
29
+ }
30
+
31
+ export function primaryKey(
32
+ columns: readonly string[],
33
+ options?: { readonly name?: string },
34
+ ): PrimaryKeyConstraint {
35
+ return new PrimaryKeyConstraint({ columns, ...options });
36
+ }
37
+
38
+ export function foreignKey(
39
+ columns: readonly string[],
40
+ refTable: string,
41
+ refColumns: readonly string[],
42
+ options?: {
43
+ readonly name?: string;
44
+ readonly onDelete?: ReferentialAction;
45
+ readonly onUpdate?: ReferentialAction;
46
+ },
47
+ ): ForeignKeyConstraint {
48
+ return new ForeignKeyConstraint({ columns, refTable, refColumns, ...options });
49
+ }
50
+
51
+ export function unique(
52
+ columns: readonly string[],
53
+ options?: { readonly name?: string },
54
+ ): UniqueConstraint {
55
+ return new UniqueConstraint({ columns, ...options });
56
+ }
@@ -0,0 +1,17 @@
1
+ export {
2
+ CfConflictClause,
3
+ CfExpr,
4
+ CfInsertQuery,
5
+ CfSelectQuery,
6
+ CfUpdateQuery,
7
+ CfUpsertBuilder,
8
+ CfUpsertQuery,
9
+ type ColumnDescriptor,
10
+ type ColumnProxy,
11
+ type ColumnSchema,
12
+ type ExcludedProxy,
13
+ type TableHandle,
14
+ type TableInsertRow,
15
+ type TableSetValues,
16
+ table,
17
+ } from './table';