@minnowdb/core 0.4.1 → 0.6.0

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 (47) hide show
  1. package/README.md +5 -5
  2. package/dist/engine/cancellation.d.ts +2 -0
  3. package/dist/engine/cancellation.js +4 -0
  4. package/dist/engine/catalog.d.ts +5 -1
  5. package/dist/engine/catalog.js +5 -1
  6. package/dist/engine/client.d.ts +34 -6
  7. package/dist/engine/client.js +87 -19
  8. package/dist/engine/database.d.ts +43 -20
  9. package/dist/engine/database.js +823 -164
  10. package/dist/engine/defaults.js +11 -0
  11. package/dist/engine/errors.d.ts +19 -0
  12. package/dist/engine/errors.js +31 -0
  13. package/dist/engine/fts.d.ts +2 -15
  14. package/dist/engine/live.d.ts +1 -7
  15. package/dist/engine/live.js +12 -13
  16. package/dist/engine/optimizer.js +546 -39
  17. package/dist/engine/query-cache.js +1 -0
  18. package/dist/engine/query.d.ts +16 -278
  19. package/dist/engine/query.js +260 -74
  20. package/dist/engine/result-wire.d.ts +2 -0
  21. package/dist/engine/result-wire.js +21 -5
  22. package/dist/engine/schema-wire.d.ts +14 -1
  23. package/dist/engine/schema-wire.js +7 -1
  24. package/dist/engine/schema.d.ts +83 -32
  25. package/dist/engine/schema.js +180 -14
  26. package/dist/engine/sql-domains.d.ts +11 -0
  27. package/dist/engine/sql-domains.js +65 -1
  28. package/dist/engine/sql-json.js +22 -3
  29. package/dist/engine/sql-semantics.js +21 -3
  30. package/dist/engine/vector.d.ts +2 -2
  31. package/dist/engine/vector.js +328 -79
  32. package/dist/engine/worker-host.js +119 -44
  33. package/dist/plan/index.d.ts +5 -4
  34. package/dist/plan/index.js +3 -3
  35. package/dist/plan/model.d.ts +218 -0
  36. package/dist/plan/model.js +1 -0
  37. package/dist/storage/indexeddb.js +4 -12
  38. package/dist/storage/toolkit/record-core.js +7 -22
  39. package/dist/storage/types.d.ts +26 -8
  40. package/dist/storage/types.js +85 -0
  41. package/dist/transactions/index.d.ts +5 -3
  42. package/dist/transactions/index.js +58 -8
  43. package/dist/worker-protocol/index.d.ts +6 -1
  44. package/dist/worker-protocol/index.js +5 -2
  45. package/package.json +1 -1
  46. package/postgres-feature-profile.json +5 -0
  47. package/sql-feature-matrix.json +75 -19
@@ -1,3 +1,4 @@
1
+ import type { SqlDomain } from "../storage/types.js";
1
2
  import type { QueryResult, QueryRow, QueryValue } from "./query.js";
2
3
  /**
3
4
  * The shape a query result takes on the worker channel. A result is rows of objects at the
@@ -49,6 +50,7 @@ export type WireResultColumn = {
49
50
  export interface WireQueryResult {
50
51
  readonly kind: "columnar-result";
51
52
  readonly columns: string[];
53
+ readonly columnDomains: Array<SqlDomain | null>;
52
54
  readonly rowCount: number;
53
55
  readonly values: WireResultColumn[];
54
56
  }
@@ -1,6 +1,7 @@
1
1
  import { dateMilliseconds } from "../date-value.js";
2
+ import { unknownColumnDomains } from "./query.js";
2
3
  export function encodeQueryResult(result) {
3
- return encodeRows(result.columns, result.rows);
4
+ return encodeRows(result.columns, result.rows, result.columnDomains);
4
5
  }
5
6
  /**
6
7
  * Encodes a bare row array (`run()` returns rows without a column list). Every row of one result
@@ -8,13 +9,18 @@ export function encodeQueryResult(result) {
8
9
  */
9
10
  export function encodeQueryRows(rows) {
10
11
  const first = rows[0];
11
- return encodeRows(first === undefined ? [] : Object.keys(first), rows);
12
+ const columns = first === undefined ? [] : Object.keys(first);
13
+ return encodeRows(columns, rows, unknownColumnDomains(columns));
12
14
  }
13
15
  export function decodeQueryResult(payload) {
14
16
  if (!isWireQueryResult(payload)) {
15
17
  throw new TypeError("Expected a columnar query result frame");
16
18
  }
17
19
  const columns = [...payload.columns];
20
+ if (payload.values.length !== columns.length || payload.columnDomains.length !== columns.length) {
21
+ throw new TypeError("Columnar result frame metadata is not aligned");
22
+ }
23
+ const columnDomains = structuredClone(payload.columnDomains);
18
24
  const rows = [];
19
25
  for (let index = 0; index < payload.rowCount; index += 1)
20
26
  rows.push({});
@@ -26,17 +32,21 @@ export function decodeQueryResult(payload) {
26
32
  throw new TypeError("Columnar result frame is missing a column");
27
33
  fillColumn(rows, name, column);
28
34
  }
29
- return { columns, rows };
35
+ return { columns, columnDomains, rows };
30
36
  }
31
37
  export function isWireQueryResult(value) {
32
38
  return (typeof value === "object" &&
33
39
  value !== null &&
34
40
  value.kind === "columnar-result" &&
35
41
  Array.isArray(value.columns) &&
42
+ Array.isArray(value.columnDomains) &&
36
43
  Array.isArray(value.values) &&
37
44
  typeof value.rowCount === "number");
38
45
  }
39
- function encodeRows(columns, rows) {
46
+ function encodeRows(columns, rows, columnDomains) {
47
+ if (columnDomains.length !== columns.length) {
48
+ throw new TypeError("Query result column domains must align with the result columns");
49
+ }
40
50
  const transfer = [];
41
51
  const values = columns.map((name) => {
42
52
  const column = encodeColumn(name, rows);
@@ -53,7 +63,13 @@ function encodeRows(columns, rows) {
53
63
  return column;
54
64
  });
55
65
  return {
56
- payload: { kind: "columnar-result", columns: [...columns], rowCount: rows.length, values },
66
+ payload: {
67
+ kind: "columnar-result",
68
+ columns: [...columns],
69
+ columnDomains: structuredClone([...columnDomains]),
70
+ rowCount: rows.length,
71
+ values,
72
+ },
57
73
  transfer,
58
74
  };
59
75
  }
@@ -1,4 +1,4 @@
1
- import type { ColumnDefault, SqlDomain } from "../storage/types.js";
1
+ import type { ColumnDefault, ColumnGenerated, SqlDomain } from "../storage/types.js";
2
2
  import { type AnyTable, type MigrationStep, type ReferentialAction, type SchemaColumnType, type SchemaDefinition, type TableCheck, type TableForeignKey } from "./schema.js";
3
3
  /**
4
4
  * Structured-clone-safe mirror of the schema DSL. Column builders and table validators carry
@@ -12,11 +12,13 @@ export interface WireColumn {
12
12
  readonly integer?: true;
13
13
  readonly sqlDomain?: SqlDomain;
14
14
  readonly defaultSpec?: ColumnDefault;
15
+ readonly generatedSpec?: ColumnGenerated;
15
16
  readonly renamedFromName?: string;
16
17
  readonly reference?: {
17
18
  table: string;
18
19
  column: string;
19
20
  onDelete: ReferentialAction;
21
+ enforced?: boolean;
20
22
  };
21
23
  readonly enumValues?: readonly string[];
22
24
  /** Already frozen by planning, so the wire carries a value and never a generator. */
@@ -83,6 +85,17 @@ export type WireMigrationStep = {
83
85
  tableName: string;
84
86
  columnName: string;
85
87
  defaultValue: ColumnDefault | null;
88
+ } | {
89
+ kind: "alter-generated";
90
+ tableName: string;
91
+ columnName: string;
92
+ generatedValue: ColumnGenerated | null;
93
+ } | {
94
+ kind: "alter-foreign-keys";
95
+ tableName: string;
96
+ foreignKeys: Extract<MigrationStep, {
97
+ kind: "alter-foreign-keys";
98
+ }>["foreignKeys"];
86
99
  } | {
87
100
  kind: "replace-view";
88
101
  view: WireView;
@@ -14,6 +14,9 @@ function serializeColumn(definition, frozen) {
14
14
  ? {}
15
15
  : { sqlDomain: structuredClone(definition.sqlDomain) }),
16
16
  ...(definition.defaultSpec === undefined ? {} : { defaultSpec: { ...definition.defaultSpec } }),
17
+ ...(definition.generatedSpec === undefined
18
+ ? {}
19
+ : { generatedSpec: { ...definition.generatedSpec } }),
17
20
  ...(definition.renamedFromName === undefined
18
21
  ? {}
19
22
  : { renamedFromName: definition.renamedFromName }),
@@ -95,8 +98,11 @@ function deserializeColumn(wire) {
95
98
  integer: wire.integer === true,
96
99
  ...(wire.sqlDomain === undefined ? {} : { sqlDomain: structuredClone(wire.sqlDomain) }),
97
100
  ...(wire.defaultSpec === undefined ? {} : { defaultSpec: wire.defaultSpec }),
101
+ ...(wire.generatedSpec === undefined ? {} : { generatedSpec: wire.generatedSpec }),
98
102
  ...(wire.renamedFromName === undefined ? {} : { renamedFromName: wire.renamedFromName }),
99
- ...(wire.reference === undefined ? {} : { reference: wire.reference }),
103
+ ...(wire.reference === undefined
104
+ ? {}
105
+ : { reference: { ...wire.reference, enforced: wire.reference.enforced !== false } }),
100
106
  ...(wire.enumValues === undefined ? {} : { enumValues: wire.enumValues }),
101
107
  ...(wire.backfillValue === undefined ? {} : { backfillValue: wire.backfillValue }),
102
108
  });
@@ -1,6 +1,6 @@
1
1
  import { type ColumnDefault, type SqlDomain, type TableColumnRecord, type TableRecord } from "../storage/types.js";
2
2
  import { type Catalog, type CatalogColumn, type CatalogTable } from "./catalog.js";
3
- import { type QueryValue } from "./query.js";
3
+ import { type Expression, type QueryValue } from "./query.js";
4
4
  /**
5
5
  * Typed schema DSL and catalog migration planning. Column builders carry compile-time value and
6
6
  * nullability types; `planMigration` diffs a schema against the live catalog into metadata-only
@@ -9,6 +9,14 @@ import { type QueryValue } from "./query.js";
9
9
  * catalog-only, and older segments read the new column as NULL.
10
10
  */
11
11
  export type SchemaColumnType = "boolean" | "number" | "string" | "datetime";
12
+ /** Compiles and validates one immutable, row-local generated-column expression. */
13
+ export declare function compileGeneratedColumnExpression(tableName: string, columnName: string, sql: string, columns: ReadonlyArray<{
14
+ readonly name: string;
15
+ readonly generatedValue?: {
16
+ readonly kind: "stored";
17
+ readonly sql: string;
18
+ };
19
+ }>): Expression;
12
20
  /** What a FOREIGN KEY does to child rows when the parent row is deleted (E141-04). */
13
21
  export type ReferentialAction = "restrict" | "cascade" | "set null";
14
22
  /** A declared relation. `onDelete` defaults to "restrict", matching SQL's own default. */
@@ -16,6 +24,7 @@ export interface ColumnReferenceSpec {
16
24
  readonly table: string;
17
25
  readonly column: string;
18
26
  readonly onDelete: ReferentialAction;
27
+ readonly enforced: boolean;
19
28
  }
20
29
  /** A row condition every write must satisfy (E141-06); `sql` is a boolean expression. */
21
30
  export interface TableCheck {
@@ -31,6 +40,8 @@ export interface TableForeignKey<TColumnName extends string = string> {
31
40
  readonly columns: readonly string[];
32
41
  };
33
42
  readonly onDelete?: ReferentialAction;
43
+ /** False keeps the relationship in the catalog without validating or cascading rows. */
44
+ readonly enforced?: boolean;
34
45
  }
35
46
  /**
36
47
  * The constraint name `migrate()` gives a declared relation. It matches the name the SQL parser
@@ -44,22 +55,29 @@ export declare function foreignKeyName(tableName: string, columnName: string): s
44
55
  export type HasDefault<TValue> = TValue & {
45
56
  readonly __minnowHasDefault?: true;
46
57
  };
47
- export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boolean, TUnique extends boolean = false, THasDefault extends boolean = false, TInput extends SchemaValue = TValue> {
58
+ export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boolean, TUnique extends boolean = false, THasDefault extends boolean = false, TInput extends SchemaValue = TValue, TDomain extends SqlDomain["kind"] | undefined = undefined, TGenerated extends boolean = false> {
48
59
  readonly kind: "column";
49
60
  readonly type: SchemaColumnType;
50
61
  readonly isNullable: TNullable;
51
62
  readonly isUnique: TUnique;
52
63
  readonly hasDefault: THasDefault;
64
+ readonly isGenerated: TGenerated;
53
65
  /** Type-only metadata consumed by adapters; optional so it emits no runtime payload. */
54
66
  readonly "~types"?: {
55
67
  readonly select: TValue;
56
68
  readonly input: TInput;
69
+ readonly domain: TDomain;
70
+ readonly generated: TGenerated;
57
71
  };
58
72
  /** True for exact SQL integer columns; ordinary number columns use Float64 semantics. */
59
73
  readonly integer: boolean;
60
74
  /** Logical SQL semantics layered over the stable string storage encoding. */
61
75
  readonly sqlDomain?: SqlDomain;
62
76
  readonly defaultSpec?: ColumnDefault;
77
+ readonly generatedSpec?: {
78
+ readonly kind: "stored";
79
+ readonly sql: string;
80
+ };
63
81
  /** Present on `column.enum()` builders: the closed set of values writes must draw from. */
64
82
  readonly enumValues?: readonly string[];
65
83
  /** What rows written before this column existed read as; see `.backfill()`. */
@@ -67,11 +85,11 @@ export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boo
67
85
  readonly renamedFromName?: string;
68
86
  readonly reference?: ColumnReferenceSpec;
69
87
  /** Marks the column nullable; inserts may omit it and reads may return null. */
70
- nullable(): ColumnBuilder<TValue, true, TUnique, THasDefault, TInput>;
88
+ nullable(): ColumnBuilder<TValue, true, TUnique, THasDefault, TInput, TDomain, TGenerated>;
71
89
  /** Marks the table's unique key; exactly one non-nullable column may carry it. */
72
- unique(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput>): ColumnBuilder<TValue, TNullable, true, THasDefault, TInput>;
90
+ unique(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput, TDomain, TGenerated>): ColumnBuilder<TValue, TNullable, true, THasDefault, TInput, TDomain, TGenerated>;
73
91
  /** Declares this column as the rename target of an existing catalog column. */
74
- renamedFrom(name: string): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>;
92
+ renamedFrom(name: string): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
75
93
  /**
76
94
  * What rows written before this column existed read as, instead of NULL. Giving one is what
77
95
  * makes adding a non-nullable column possible: no stored byte is rewritten, and reads
@@ -81,7 +99,7 @@ export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boo
81
99
  * catalog — so it can derive a value (a timestamp, a version stamp) without readers ever
82
100
  * disagreeing. It cannot derive from other columns; that would need a value per row.
83
101
  */
84
- backfill(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput>, value: TInput | (() => TInput)): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>;
102
+ backfill(this: ColumnBuilder<TValue, false, TUnique, THasDefault, TInput, TDomain, TGenerated>, value: TInput | (() => TInput)): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
85
103
  /**
86
104
  * Declares a FOREIGN KEY onto another table's unique key. `migrate()` creates it as a real
87
105
  * constraint, so a write naming a parent row that does not exist is rejected — the same
@@ -89,26 +107,33 @@ export interface ColumnBuilder<TValue extends SchemaValue, TNullable extends boo
89
107
  *
90
108
  * `onDelete` defaults to `"restrict"`. `"set null"` requires a nullable column.
91
109
  */
92
- references(this: ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>, table: string, column: string, options?: {
110
+ references(this: ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>, table: string, column: string, options?: {
93
111
  onDelete?: Exclude<ReferentialAction, "set null">;
94
- }): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>;
95
- references(this: ColumnBuilder<TValue, true, TUnique, THasDefault, TInput>, table: string, column: string, options: {
112
+ enforced?: true;
113
+ } | {
114
+ enforced: false;
115
+ onDelete?: never;
116
+ }): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
117
+ references(this: ColumnBuilder<TValue, true, TUnique, THasDefault, TInput, TDomain, TGenerated>, table: string, column: string, options: {
96
118
  onDelete: "set null";
97
- }): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput>;
119
+ enforced?: true;
120
+ }): ColumnBuilder<TValue, TNullable, TUnique, THasDefault, TInput, TDomain, TGenerated>;
98
121
  /** Declares a literal SQL default. Omission or SQL `DEFAULT` invokes it; NULL does not. */
99
- default(value: TInput): ColumnBuilder<TValue, TNullable, TUnique, true, TInput>;
122
+ default(value: TInput): ColumnBuilder<TValue, TNullable, TUnique, true, TInput, TDomain, TGenerated>;
100
123
  /**
101
124
  * Declares a variable-free SQL default expression, such as `CURRENT_TIMESTAMP`,
102
125
  * `gen_random_uuid()`, or `nextval('orders_id_seq')`. The engine parses and type-checks it
103
126
  * before migration and evaluates it once per omitted row.
104
127
  */
105
- defaultSql(sql: string): ColumnBuilder<TValue, TNullable, TUnique, true, TInput>;
128
+ defaultSql(sql: string): ColumnBuilder<TValue, TNullable, TUnique, true, TInput, TDomain, TGenerated>;
129
+ /** Declares a stored expression over sibling columns. Callers never insert or update it. */
130
+ generatedSql(sql: string): ColumnBuilder<TValue, TNullable, TUnique, false, TInput, TDomain, true>;
106
131
  /**
107
132
  * Generates monotonically increasing integers for omitted or SQL `DEFAULT` slots from a persistent
108
133
  * per-table counter that is atomic across tabs. Explicit values are allowed and bump the
109
134
  * counter past their maximum. Number unique-key columns only.
110
135
  */
111
- autoIncrement: TValue extends number ? (this: ColumnBuilder<TValue, false, true, THasDefault, TInput>) => ColumnBuilder<TValue, TNullable, TUnique, true, TInput> : never;
136
+ autoIncrement: TValue extends number ? (this: ColumnBuilder<TValue, false, true, THasDefault, TInput, TDomain, TGenerated>) => ColumnBuilder<TValue, TNullable, TUnique, true, TInput, TDomain, TGenerated> : never;
112
137
  }
113
138
  type SchemaValue = boolean | number | string | Date;
114
139
  /**
@@ -122,9 +147,14 @@ interface AnyColumn {
122
147
  readonly isNullable: boolean;
123
148
  readonly isUnique: boolean;
124
149
  readonly hasDefault: boolean;
150
+ readonly isGenerated: boolean;
125
151
  readonly integer: boolean;
126
152
  readonly sqlDomain?: SqlDomain;
127
153
  readonly defaultSpec?: ColumnDefault;
154
+ readonly generatedSpec?: {
155
+ readonly kind: "stored";
156
+ readonly sql: string;
157
+ };
128
158
  readonly enumValues?: readonly string[];
129
159
  readonly backfillValue?: SchemaValue | (() => SchemaValue);
130
160
  readonly renamedFromName?: string;
@@ -136,28 +166,30 @@ interface AnyColumn {
136
166
  */
137
167
  export declare function columnWithDefaultSpec(base: Pick<AnyColumn, "type" | "isNullable" | "isUnique" | "renamedFromName" | "reference" | "enumValues"> & Partial<Pick<AnyColumn, "integer" | "sqlDomain">>, spec: ColumnDefault): AnyColumn;
138
168
  /** Rebuilds a fluent column from structured-clone-safe metadata. */
139
- export declare function columnFromState(state: Pick<AnyColumn, "type" | "isNullable" | "isUnique"> & Partial<Pick<AnyColumn, "integer" | "sqlDomain" | "renamedFromName" | "reference" | "defaultSpec" | "enumValues" | "backfillValue">>): AnyColumn;
169
+ export declare function columnFromState(state: Pick<AnyColumn, "type" | "isNullable" | "isUnique"> & Partial<Pick<AnyColumn, "integer" | "sqlDomain" | "renamedFromName" | "reference" | "defaultSpec" | "generatedSpec" | "enumValues" | "backfillValue">>): AnyColumn;
140
170
  export declare const column: {
141
- boolean: () => ColumnBuilder<boolean, false, false, false, boolean>;
142
- number: () => ColumnBuilder<number, false, false, false, number>;
171
+ boolean: () => ColumnBuilder<boolean, false, false, false, boolean, undefined, false>;
172
+ number: () => ColumnBuilder<number, false, false, false, number, undefined, false>;
143
173
  /** Exact safe-integer semantics, matching SQL INTEGER/SMALLINT/BIGINT. */
144
- integer: () => ColumnBuilder<number, false, false, false, number>;
145
- string: () => ColumnBuilder<string, false, false, false, string>;
146
- datetime: () => ColumnBuilder<Date, false, false, false, Date>;
174
+ integer: () => ColumnBuilder<number, false, false, false, number, undefined, false>;
175
+ string: () => ColumnBuilder<string, false, false, false, string, undefined, false>;
176
+ datetime: () => ColumnBuilder<Date, false, false, false, Date, undefined, false>;
147
177
  /** Exact decimal SQL NUMERIC. Selects return strings; writes accept strings or numbers. */
148
178
  numeric: (options?: {
149
179
  precision?: number;
150
180
  scale?: number;
151
- }) => ColumnBuilder<string, false, false, false, string | number>;
152
- json: () => ColumnBuilder<string, false, false, false, string>;
153
- jsonb: () => ColumnBuilder<string, false, false, false, string>;
154
- uuid: () => ColumnBuilder<string, false, false, false, string>;
155
- time: () => ColumnBuilder<string, false, false, false, string>;
156
- interval: () => ColumnBuilder<string, false, false, false, string>;
181
+ }) => ColumnBuilder<string, false, false, false, string | number, "numeric", false>;
182
+ json: () => ColumnBuilder<string, false, false, false, string, "json", false>;
183
+ jsonb: () => ColumnBuilder<string, false, false, false, string, "jsonb", false>;
184
+ uuid: () => ColumnBuilder<string, false, false, false, string, "uuid", false>;
185
+ /** A zoneless calendar date, represented publicly as canonical `YYYY-MM-DD` text. */
186
+ date: () => ColumnBuilder<string, false, false, false, string, "date", false>;
187
+ time: () => ColumnBuilder<string, false, false, false, string, "time", false>;
188
+ interval: () => ColumnBuilder<string, false, false, false, string, "interval", false>;
157
189
  /** JSON array text at the JavaScript boundary, with the SQL element type retained in metadata. */
158
- array: (element: string) => ColumnBuilder<string, false, false, false, string>;
190
+ array: (element: string) => ColumnBuilder<string, false, false, false, string, "array", false>;
159
191
  /** A named SQL enum domain, distinct from the lightweight `column.enum()` restriction. */
160
- sqlEnum: <const TValues extends readonly [string, ...string[]]>(name: string, values: TValues) => ColumnBuilder<TValues[number], false>;
192
+ sqlEnum: <const TValues extends readonly [string, ...string[]]>(name: string, values: TValues) => ColumnBuilder<TValues[number], false, false, false, TValues[number], "enum">;
161
193
  /**
162
194
  * A string column restricted to a closed set of values, typed as their literal union:
163
195
  *
@@ -234,6 +266,7 @@ export declare function declaredForeignKeys(definition: AnyTable): Array<{
234
266
  parentTable: string;
235
267
  parentColumns: string[];
236
268
  onDelete: ReferentialAction;
269
+ enforced: boolean;
237
270
  }>;
238
271
  /**
239
272
  * A view declared in the schema: the query it stands for, plus the column shape the author
@@ -299,11 +332,15 @@ type NullableKeys<TTable extends AnyTable> = {
299
332
  type DefaultKeys<TTable extends AnyTable> = {
300
333
  [K in keyof TTable["columns"]]: TTable["columns"][K]["hasDefault"] extends true ? K : never;
301
334
  }[keyof TTable["columns"]];
302
- type OptionalInsertKeys<TTable extends AnyTable> = NullableKeys<TTable> | DefaultKeys<TTable>;
335
+ type GeneratedKeys<TTable extends AnyTable> = {
336
+ [K in keyof TTable["columns"]]: TTable["columns"][K]["isGenerated"] extends true ? K : never;
337
+ }[keyof TTable["columns"]];
338
+ type OptionalInsertKeys<TTable extends AnyTable> = Exclude<NullableKeys<TTable> | DefaultKeys<TTable>, GeneratedKeys<TTable>>;
339
+ type RequiredInsertKeys<TTable extends AnyTable> = Exclude<keyof TTable["columns"], OptionalInsertKeys<TTable> | GeneratedKeys<TTable>>;
303
340
  /** Insert rows require every non-nullable column and may omit nullable or default-bearing ones. */
304
- export type InferInsertRow<TTable extends AnyTable> = Omit<{
305
- [K in keyof TTable["columns"]]: ColumnInputValue<TTable["columns"][K]>;
306
- }, OptionalInsertKeys<TTable>> & {
341
+ export type InferInsertRow<TTable extends AnyTable> = {
342
+ [K in RequiredInsertKeys<TTable>]: ColumnInputValue<TTable["columns"][K]>;
343
+ } & {
307
344
  [K in OptionalInsertKeys<TTable>]?: ColumnInputValue<TTable["columns"][K]>;
308
345
  };
309
346
  /** Scalar `.unique()` keys plus columns named by a table-level primary key. */
@@ -316,7 +353,7 @@ export type PrimaryKeyKeys<TTable extends AnyTable> = {
316
353
  * stays assignable under `exactOptionalPropertyTypes`.
317
354
  */
318
355
  export type InferUpdateChanges<TTable extends AnyTable> = {
319
- [K in keyof TTable["columns"] as K extends PrimaryKeyKeys<TTable> ? never : K]?: ColumnInputValue<TTable["columns"][K]> | undefined;
356
+ [K in keyof TTable["columns"] as K extends PrimaryKeyKeys<TTable> | GeneratedKeys<TTable> ? never : K]?: ColumnInputValue<TTable["columns"][K]> | undefined;
320
357
  };
321
358
  export type MigrationStep = {
322
359
  kind: "create-table";
@@ -365,6 +402,20 @@ export type MigrationStep = {
365
402
  tableName: string;
366
403
  columnName: string;
367
404
  defaultValue: ColumnDefault | null;
405
+ } | {
406
+ kind: "alter-generated";
407
+ tableName: string;
408
+ columnName: string;
409
+ generatedValue: {
410
+ readonly kind: "stored";
411
+ readonly sql: string;
412
+ } | null;
413
+ }
414
+ /** Informational relationships are catalog-only and may change without scanning stored rows. */
415
+ | {
416
+ kind: "alter-foreign-keys";
417
+ tableName: string;
418
+ foreignKeys: ReturnType<typeof declaredForeignKeys>;
368
419
  }
369
420
  /**
370
421
  * A view is derived and disposable: nothing is stored under it, so replacing its body loses no