turbine-orm 0.49.0 → 0.50.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.
- package/README.md +122 -39
- package/dist/cjs/adapters/cockroachdb.d.ts +39 -0
- package/dist/cjs/adapters/index.d.ts +110 -0
- package/dist/cjs/adapters/yugabytedb.d.ts +51 -0
- package/dist/cjs/cli/config.d.ts +181 -0
- package/dist/cjs/cli/config.js +32 -6
- package/dist/cjs/cli/destructive.d.ts +38 -0
- package/dist/cjs/cli/index.d.ts +359 -0
- package/dist/cjs/cli/index.js +228 -56
- package/dist/cjs/cli/loader.d.ts +61 -0
- package/dist/cjs/cli/mcp.d.ts +42 -0
- package/dist/cjs/cli/migrate.d.ts +356 -0
- package/dist/cjs/cli/migrate.js +131 -40
- package/dist/cjs/cli/observe-ui.d.ts +1 -0
- package/dist/cjs/cli/observe-ui.js +14 -5
- package/dist/cjs/cli/observe.d.ts +25 -0
- package/dist/cjs/cli/observe.js +49 -12
- package/dist/cjs/cli/pii-tags.d.ts +53 -0
- package/dist/cjs/cli/prisma-report.d.ts +33 -0
- package/dist/cjs/cli/prisma-report.js +73 -0
- package/dist/cjs/cli/prisma-resolve.d.ts +106 -0
- package/dist/cjs/cli/prisma-resolve.js +1 -0
- package/dist/cjs/cli/prisma-schema.d.ts +176 -0
- package/dist/cjs/cli/prisma-schema.js +82 -4
- package/dist/cjs/cli/rate-limit.d.ts +32 -0
- package/dist/cjs/cli/rate-limit.js +45 -0
- package/dist/cjs/cli/studio-demo.d.ts +43 -0
- package/dist/cjs/cli/studio-ui.generated.d.ts +1 -0
- package/dist/cjs/cli/studio.d.ts +207 -0
- package/dist/cjs/cli/studio.js +136 -71
- package/dist/cjs/cli/ui.d.ts +73 -0
- package/dist/cjs/cli/ui.js +51 -9
- package/dist/cjs/client.d.ts +837 -0
- package/dist/cjs/client.js +3 -0
- package/dist/cjs/dialect.d.ts +516 -0
- package/dist/cjs/dialect.js +37 -12
- package/dist/cjs/errors.d.ts +370 -0
- package/dist/cjs/generate.d.ts +137 -0
- package/dist/cjs/generate.js +39 -6
- package/dist/cjs/index-advisor.d.ts +153 -0
- package/dist/cjs/index-stats.d.ts +384 -0
- package/dist/cjs/index.d.ts +55 -0
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/introspect.d.ts +269 -0
- package/dist/cjs/mssql.d.ts +232 -0
- package/dist/cjs/mssql.js +6 -0
- package/dist/cjs/mysql.d.ts +173 -0
- package/dist/cjs/mysql.js +16 -0
- package/dist/cjs/nested-write.d.ts +96 -0
- package/dist/cjs/nested-write.js +414 -24
- package/dist/cjs/observe.d.ts +115 -0
- package/dist/cjs/optional-peer-import.d.cts +72 -0
- package/dist/cjs/pipeline-submittable.d.ts +93 -0
- package/dist/cjs/pipeline.d.ts +71 -0
- package/dist/cjs/powdb-introspect.d.ts +84 -0
- package/dist/cjs/powdb.d.ts +931 -0
- package/dist/cjs/powdb.js +106 -21
- package/dist/cjs/powql.d.ts +592 -0
- package/dist/cjs/powql.js +42 -6
- package/dist/cjs/prisma-compat.d.ts +283 -0
- package/dist/cjs/prisma-compat.js +167 -9
- package/dist/cjs/query/aggregates.d.ts +92 -0
- package/dist/cjs/query/aggregates.js +7 -3
- package/dist/cjs/query/batched-loader.d.ts +193 -0
- package/dist/cjs/query/builder.d.ts +849 -0
- package/dist/cjs/query/builder.js +571 -65
- package/dist/cjs/query/compound-unique.d.ts +51 -0
- package/dist/cjs/query/deferred.d.ts +223 -0
- package/dist/cjs/query/filters.d.ts +201 -0
- package/dist/cjs/query/index.d.ts +14 -0
- package/dist/cjs/query/index.js +6 -1
- package/dist/cjs/query/relations.d.ts +609 -0
- package/dist/cjs/query/relations.js +693 -46
- package/dist/cjs/query/types.d.ts +1300 -0
- package/dist/cjs/query/utils.d.ts +209 -0
- package/dist/cjs/query/utils.js +208 -1
- package/dist/cjs/query/warn-registry.d.ts +68 -0
- package/dist/cjs/query/warn-registry.js +9 -0
- package/dist/cjs/query/where-compile.d.ts +139 -0
- package/dist/cjs/query/where.d.ts +548 -0
- package/dist/cjs/query/where.js +58 -22
- package/dist/cjs/query/writes.d.ts +172 -0
- package/dist/cjs/query/writes.js +105 -12
- package/dist/cjs/realtime.d.ts +70 -0
- package/dist/cjs/schema-builder.d.ts +354 -0
- package/dist/cjs/schema-metadata.d.ts +83 -0
- package/dist/cjs/schema-sql.d.ts +217 -0
- package/dist/cjs/schema-sql.js +23 -5
- package/dist/cjs/schema.d.ts +356 -0
- package/dist/cjs/schema.js +125 -0
- package/dist/cjs/seed.d.ts +15 -0
- package/dist/cjs/serverless.d.ts +142 -0
- package/dist/cjs/sqlite.d.ts +143 -0
- package/dist/cjs/sqlite.js +4 -0
- package/dist/cjs/typed-sql.d.ts +102 -0
- package/dist/cli/config.d.ts +18 -4
- package/dist/cli/config.js +31 -6
- package/dist/cli/index.d.ts +123 -0
- package/dist/cli/index.js +223 -58
- package/dist/cli/migrate.d.ts +59 -10
- package/dist/cli/migrate.js +128 -41
- package/dist/cli/observe-ui.d.ts +1 -1
- package/dist/cli/observe-ui.js +14 -5
- package/dist/cli/observe.d.ts +7 -1
- package/dist/cli/observe.js +48 -12
- package/dist/cli/prisma-report.d.ts +14 -0
- package/dist/cli/prisma-report.js +72 -0
- package/dist/cli/prisma-resolve.d.ts +6 -0
- package/dist/cli/prisma-resolve.js +1 -0
- package/dist/cli/prisma-schema.d.ts +62 -2
- package/dist/cli/prisma-schema.js +81 -4
- package/dist/cli/rate-limit.d.ts +32 -0
- package/dist/cli/rate-limit.js +40 -0
- package/dist/cli/studio.d.ts +5 -5
- package/dist/cli/studio.js +135 -70
- package/dist/cli/ui.d.ts +1 -1
- package/dist/cli/ui.js +51 -9
- package/dist/client.d.ts +40 -0
- package/dist/client.js +3 -0
- package/dist/dialect.d.ts +17 -1
- package/dist/dialect.js +37 -12
- package/dist/generate.js +40 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mssql.js +6 -0
- package/dist/mysql.js +16 -0
- package/dist/nested-write.d.ts +2 -0
- package/dist/nested-write.js +415 -25
- package/dist/powdb.d.ts +4 -2
- package/dist/powdb.js +106 -21
- package/dist/powql.d.ts +5 -0
- package/dist/powql.js +42 -6
- package/dist/prisma-compat.d.ts +2 -0
- package/dist/prisma-compat.js +166 -8
- package/dist/query/aggregates.js +7 -3
- package/dist/query/builder.d.ts +292 -21
- package/dist/query/builder.js +570 -64
- package/dist/query/deferred.d.ts +39 -0
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +1 -1
- package/dist/query/relations.d.ts +173 -5
- package/dist/query/relations.js +688 -47
- package/dist/query/types.d.ts +123 -39
- package/dist/query/utils.d.ts +116 -0
- package/dist/query/utils.js +198 -0
- package/dist/query/warn-registry.d.ts +9 -0
- package/dist/query/warn-registry.js +9 -0
- package/dist/query/where.d.ts +38 -1
- package/dist/query/where.js +58 -23
- package/dist/query/writes.d.ts +42 -1
- package/dist/query/writes.js +104 -13
- package/dist/schema-sql.d.ts +14 -0
- package/dist/schema-sql.js +23 -5
- package/dist/schema.d.ts +38 -0
- package/dist/schema.js +123 -0
- package/dist/sqlite.js +4 -0
- package/package.json +77 -28
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm — Schema Builder
|
|
3
|
+
*
|
|
4
|
+
* TypeScript-first schema definition API. Define your database schema
|
|
5
|
+
* as plain objects — no method chaining, no DSL. Fully type-checked,
|
|
6
|
+
* JSON-serializable, and easy to read.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { defineSchema } from 'turbine-orm';
|
|
11
|
+
*
|
|
12
|
+
* export default defineSchema({
|
|
13
|
+
* users: {
|
|
14
|
+
* id: { type: 'serial', primaryKey: true },
|
|
15
|
+
* email: { type: 'text', unique: true, notNull: true },
|
|
16
|
+
* name: { type: 'text', notNull: true },
|
|
17
|
+
* bio: { type: 'text' },
|
|
18
|
+
* role: { type: 'varchar', maxLength: 50, default: "'user'" },
|
|
19
|
+
* orgId: { type: 'bigint', notNull: true, references: 'organizations.id' },
|
|
20
|
+
* createdAt: { type: 'timestamp', default: 'now()' },
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import type { ReferentialAction, SchemaMetadata } from './schema.js';
|
|
26
|
+
export type { ReferentialAction } from './schema.js';
|
|
27
|
+
/** Shorthand type names that map to Postgres column types */
|
|
28
|
+
export type ColumnTypeName = 'serial' | 'bigserial' | 'bigint' | 'integer' | 'smallint' | 'text' | 'varchar' | 'boolean' | 'timestamp' | 'timestamptz' | 'date' | 'json' | 'jsonb' | 'uuid' | 'real' | 'double' | 'numeric' | 'bytea' | 'enum' | 'vector';
|
|
29
|
+
/** Foreign key reference with optional referential actions. */
|
|
30
|
+
export interface ReferenceDef {
|
|
31
|
+
/** REFERENCES target in "table.column" form. */
|
|
32
|
+
target: string;
|
|
33
|
+
/** `ON DELETE` action. Omit for the Postgres default (`NO ACTION`). */
|
|
34
|
+
onDelete?: ReferentialAction;
|
|
35
|
+
/** `ON UPDATE` action. Omit for the Postgres default (`NO ACTION`). */
|
|
36
|
+
onUpdate?: ReferentialAction;
|
|
37
|
+
}
|
|
38
|
+
/** Column definition as a plain object. This is what users write. */
|
|
39
|
+
export interface ColumnDef {
|
|
40
|
+
/** Column type (required) */
|
|
41
|
+
type: ColumnTypeName;
|
|
42
|
+
/** PRIMARY KEY constraint */
|
|
43
|
+
primaryKey?: boolean;
|
|
44
|
+
/** NOT NULL constraint */
|
|
45
|
+
notNull?: boolean;
|
|
46
|
+
/** Explicitly nullable */
|
|
47
|
+
nullable?: boolean;
|
|
48
|
+
/** UNIQUE constraint */
|
|
49
|
+
unique?: boolean;
|
|
50
|
+
/** DEFAULT expression (raw SQL, e.g. 'now()' or "'active'") */
|
|
51
|
+
default?: string;
|
|
52
|
+
/**
|
|
53
|
+
* REFERENCES target. Either the "table.column" string form or an object with
|
|
54
|
+
* referential actions ({@link ReferenceDef}).
|
|
55
|
+
*/
|
|
56
|
+
references?: string | ReferenceDef;
|
|
57
|
+
/** Max length for varchar columns */
|
|
58
|
+
maxLength?: number;
|
|
59
|
+
/** Enum type name — required when `type: 'enum'`. */
|
|
60
|
+
enumName?: string;
|
|
61
|
+
/** pgvector dimension count — required when `type: 'vector'`. */
|
|
62
|
+
dimensions?: number;
|
|
63
|
+
/** When true, the column is an array of `type` (e.g. `text[]`). */
|
|
64
|
+
array?: boolean;
|
|
65
|
+
/** Column-level `CHECK` expression (raw SQL, e.g. `price >= 0`). */
|
|
66
|
+
check?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Marks this column as personally identifiable information (PII). Purely a
|
|
69
|
+
* code-first declaration: it carries onto {@link ColumnConfig.pii} and, via
|
|
70
|
+
* `schemaDefToMetadata` / codegen, onto
|
|
71
|
+
* {@link import('./schema.js').ColumnMetadata.pii}. A PII column is excluded
|
|
72
|
+
* from default projections (read back only via an explicit `select` or
|
|
73
|
+
* `includePii: true`) and redacted by Studio. Introspection never auto-tags PII.
|
|
74
|
+
*/
|
|
75
|
+
pii?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/** Postgres-level column type (uppercase, as used in DDL) */
|
|
78
|
+
export type ColumnType = 'SERIAL' | 'BIGSERIAL' | 'BIGINT' | 'INTEGER' | 'SMALLINT' | 'TEXT' | 'BOOLEAN' | 'TIMESTAMPTZ' | 'JSONB' | 'UUID' | 'REAL' | 'DOUBLE PRECISION' | 'NUMERIC' | 'BYTEA' | 'DATE' | 'VARCHAR' | 'ENUM' | 'VECTOR';
|
|
79
|
+
export interface ColumnConfig {
|
|
80
|
+
type: ColumnType;
|
|
81
|
+
isPrimaryKey: boolean;
|
|
82
|
+
isNotNull: boolean;
|
|
83
|
+
isNullable: boolean;
|
|
84
|
+
isUnique: boolean;
|
|
85
|
+
defaultValue: string | null;
|
|
86
|
+
referencesTarget: string | null;
|
|
87
|
+
maxLength: number | null;
|
|
88
|
+
/** FK `ON DELETE` action, or null for the Postgres default. */
|
|
89
|
+
onDelete: ReferentialAction | null;
|
|
90
|
+
/** FK `ON UPDATE` action, or null for the Postgres default. */
|
|
91
|
+
onUpdate: ReferentialAction | null;
|
|
92
|
+
/** Enum type name when `type === 'ENUM'`, else null. */
|
|
93
|
+
enumName: string | null;
|
|
94
|
+
/** pgvector dimensions when `type === 'VECTOR'`, else null. */
|
|
95
|
+
vectorDimensions: number | null;
|
|
96
|
+
/** Whether the column is an array of its base type. */
|
|
97
|
+
isArray: boolean;
|
|
98
|
+
/** Column-level `CHECK` expression, or null. */
|
|
99
|
+
check: string | null;
|
|
100
|
+
/** Whether this column is tagged as PII (personally identifiable information). */
|
|
101
|
+
pii: boolean;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Explicit many-to-many relation declaration for the code-first schema.
|
|
105
|
+
*
|
|
106
|
+
* Auto-detecting m2m from a junction table is intentionally conservative (a
|
|
107
|
+
* junction with payload columns is treated as a first-class entity, not a join
|
|
108
|
+
* table — see `introspect.ts`). This declaration lets users opt in to an m2m
|
|
109
|
+
* relation explicitly, mirroring how Prisma/Drizzle require an explicit
|
|
110
|
+
* `@relation` / `relation()` for join tables.
|
|
111
|
+
*
|
|
112
|
+
* All names are the JS-facing accessor / camelCase field names you wrote in
|
|
113
|
+
* `defineSchema({ ... })`; they are normalized to snake_case when merged into
|
|
114
|
+
* the introspected {@link SchemaMetadata} via {@link applyManyToManyRelations}.
|
|
115
|
+
*/
|
|
116
|
+
export interface ManyToManyDef {
|
|
117
|
+
/** Relation field name on the source table (e.g. `tags`). */
|
|
118
|
+
name: string;
|
|
119
|
+
/** Target table accessor (e.g. `tags`). */
|
|
120
|
+
target: string;
|
|
121
|
+
/** Junction (join) table accessor (e.g. `postsTags`). */
|
|
122
|
+
through: string;
|
|
123
|
+
/** Junction column(s) referencing the SOURCE table's PK. */
|
|
124
|
+
sourceKey: string | readonly string[];
|
|
125
|
+
/** Junction column(s) referencing the TARGET table's PK. */
|
|
126
|
+
targetKey: string | readonly string[];
|
|
127
|
+
/**
|
|
128
|
+
* Optional: the SOURCE table's referenced column(s) that `sourceKey` points
|
|
129
|
+
* at. Defaults to `id`. Use for sources keyed on a non-`id` / composite PK.
|
|
130
|
+
*/
|
|
131
|
+
references?: string | readonly string[];
|
|
132
|
+
}
|
|
133
|
+
/** A table-level named (or unnamed) `CHECK` constraint. */
|
|
134
|
+
export interface CheckDef {
|
|
135
|
+
/** Optional constraint name → `CONSTRAINT "name" CHECK (...)`. */
|
|
136
|
+
name?: string;
|
|
137
|
+
/** Raw SQL boolean expression, e.g. `price > cost`. */
|
|
138
|
+
expression: string;
|
|
139
|
+
}
|
|
140
|
+
/** A plain (column-list) index declaration. */
|
|
141
|
+
export interface ColumnIndexDef {
|
|
142
|
+
/** camelCase field name(s) the index covers. */
|
|
143
|
+
columns: string[];
|
|
144
|
+
/** Whether the index enforces uniqueness. */
|
|
145
|
+
unique?: boolean;
|
|
146
|
+
/** Optional explicit index name (auto-derived when omitted). */
|
|
147
|
+
name?: string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A doc-field expression index on a JSON document column (PowDB ≥ 0.13).
|
|
151
|
+
* Indexes the value at `docField-><path>` inside the json document, so a
|
|
152
|
+
* `JsonFilter`/`orderBy` on that path can use an index instead of a scan.
|
|
153
|
+
*/
|
|
154
|
+
export interface DocFieldIndexDef {
|
|
155
|
+
/** camelCase field name of the json document column. */
|
|
156
|
+
docField: string;
|
|
157
|
+
/** JSON path into the document: string keys and integer array indexes. */
|
|
158
|
+
path: (string | number)[];
|
|
159
|
+
/** Whether the expression index enforces uniqueness. */
|
|
160
|
+
unique?: boolean;
|
|
161
|
+
/** Optional explicit index name (auto-derived when omitted). */
|
|
162
|
+
name?: string;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* A single index declaration on a table: either a plain column-list index
|
|
166
|
+
* ({@link ColumnIndexDef}) or a doc-field expression index into a json column
|
|
167
|
+
* ({@link DocFieldIndexDef}).
|
|
168
|
+
*
|
|
169
|
+
* Consumed by the PowDB DDL generator (`powqlSchemaDDL`), carried onto
|
|
170
|
+
* {@link import('./schema.js').IndexMetadata} by `schemaDefToMetadata`, and
|
|
171
|
+
* since 0.36 emitted as `CREATE [UNIQUE] INDEX` by the SQL DDL generators:
|
|
172
|
+
* `schemaToSQL` emits plain column-list indexes, and `schemaDiff` adds ones
|
|
173
|
+
* missing from the live database (matching by name; it warns on definition
|
|
174
|
+
* mismatches and never drops). Doc-field indexes stay PowDB-only.
|
|
175
|
+
*/
|
|
176
|
+
export type SchemaIndexDef = ColumnIndexDef | DocFieldIndexDef;
|
|
177
|
+
/** Type guard: is this index declaration a doc-field expression index? */
|
|
178
|
+
export declare function isDocFieldIndexDef(idx: SchemaIndexDef): idx is DocFieldIndexDef;
|
|
179
|
+
export interface TableDef {
|
|
180
|
+
/**
|
|
181
|
+
* DDL-facing table name (snake_case). This is the name used when generating
|
|
182
|
+
* `CREATE TABLE` and other DDL statements. Set automatically during
|
|
183
|
+
* `defineSchema()` by converting the JS-facing accessor key from camelCase
|
|
184
|
+
* to snake_case (e.g. `postTags` → `post_tags`).
|
|
185
|
+
*/
|
|
186
|
+
name: string;
|
|
187
|
+
/**
|
|
188
|
+
* JS-facing accessor name (camelCase). This is the original key the user
|
|
189
|
+
* supplied to `defineSchema({ ... })` and is used as the property name on
|
|
190
|
+
* the generated `TurbineClient` (e.g. `db.postTags`). For schemas that
|
|
191
|
+
* already use snake_case keys, this matches `name`.
|
|
192
|
+
*/
|
|
193
|
+
accessor: string;
|
|
194
|
+
/** Column definitions keyed by camelCase field name */
|
|
195
|
+
columns: Record<string, ColumnConfig>;
|
|
196
|
+
/**
|
|
197
|
+
* Optional composite primary key. When present, takes precedence over any
|
|
198
|
+
* column-level `primaryKey: true` flags. Column names listed here are the
|
|
199
|
+
* camelCase JS-facing field names — they will be converted to snake_case
|
|
200
|
+
* when emitted as a `PRIMARY KEY (...)` table constraint.
|
|
201
|
+
*/
|
|
202
|
+
primaryKey?: readonly string[];
|
|
203
|
+
/**
|
|
204
|
+
* Explicit many-to-many relations declared on this table. These never affect
|
|
205
|
+
* DDL emission (junction tables are still ordinary `CREATE TABLE`s); they are
|
|
206
|
+
* consumed by {@link applyManyToManyRelations} to enrich an introspected
|
|
207
|
+
* {@link SchemaMetadata} with `manyToMany` {@link RelationDef}s.
|
|
208
|
+
*/
|
|
209
|
+
manyToMany?: readonly ManyToManyDef[];
|
|
210
|
+
/** Table-level `CHECK` constraints. */
|
|
211
|
+
checks?: readonly CheckDef[];
|
|
212
|
+
/**
|
|
213
|
+
* Index declarations for this table (plain column indexes and/or PowDB
|
|
214
|
+
* doc-field expression indexes). Consumed by the PowDB DDL generator
|
|
215
|
+
* (`powqlSchemaDDL`) and carried onto `IndexMetadata` by
|
|
216
|
+
* `schemaDefToMetadata`; the SQL DDL generators do not consume them yet.
|
|
217
|
+
*/
|
|
218
|
+
indexes?: readonly SchemaIndexDef[];
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* User-facing input shape for a single table when using the object format.
|
|
222
|
+
* The optional `primaryKey` field declares a composite primary key.
|
|
223
|
+
*/
|
|
224
|
+
export interface TableInput {
|
|
225
|
+
/** Optional composite primary key (camelCase field names) */
|
|
226
|
+
primaryKey?: readonly string[];
|
|
227
|
+
/** Optional explicit many-to-many relations on this table */
|
|
228
|
+
manyToMany?: readonly ManyToManyDef[];
|
|
229
|
+
/** Optional table-level CHECK constraints */
|
|
230
|
+
checks?: readonly CheckDef[];
|
|
231
|
+
/** Optional index declarations (plain column and/or doc-field expression) */
|
|
232
|
+
indexes?: readonly SchemaIndexDef[];
|
|
233
|
+
/** Column definitions keyed by camelCase field name */
|
|
234
|
+
[columnName: string]: ColumnDef | readonly string[] | readonly ManyToManyDef[] | readonly CheckDef[] | readonly SchemaIndexDef[] | undefined;
|
|
235
|
+
}
|
|
236
|
+
export interface SchemaDef {
|
|
237
|
+
/**
|
|
238
|
+
* All tables keyed by their JS-facing accessor name (camelCase, exactly as
|
|
239
|
+
* the user wrote them in `defineSchema({ ... })`). The DDL-facing snake_case
|
|
240
|
+
* name is available as `tables[key].name`.
|
|
241
|
+
*/
|
|
242
|
+
tables: Record<string, TableDef>;
|
|
243
|
+
/**
|
|
244
|
+
* Schema-level enum declarations (`CREATE TYPE "<name>" AS ENUM (...)`),
|
|
245
|
+
* keyed by DDL enum type name → ordered labels. Consumed by `schema-sql.ts`
|
|
246
|
+
* to emit `CREATE TYPE` before the tables that reference them and by
|
|
247
|
+
* `generate.ts` for string-literal union codegen. Omitted when no enums are
|
|
248
|
+
* declared (back-compat with `{ tables }`-only consumers).
|
|
249
|
+
*/
|
|
250
|
+
enums?: Record<string, readonly string[]>;
|
|
251
|
+
}
|
|
252
|
+
/** Options accepted by {@link defineSchema}. */
|
|
253
|
+
export interface DefineSchemaOptions {
|
|
254
|
+
/**
|
|
255
|
+
* Schema-level enum declarations, keyed by DDL enum type name → ordered
|
|
256
|
+
* labels. Columns opt in via `{ type: 'enum', enumName: '<name>' }`.
|
|
257
|
+
*/
|
|
258
|
+
enums?: Record<string, readonly string[]>;
|
|
259
|
+
}
|
|
260
|
+
/** Input format: table name -> column defs (object format) or TableDef (legacy builder) */
|
|
261
|
+
type SchemaInput = Record<string, Record<string, ColumnDef> | TableDef | TableInput>;
|
|
262
|
+
/**
|
|
263
|
+
* Define the full database schema using plain objects.
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```ts
|
|
267
|
+
* export default defineSchema({
|
|
268
|
+
* users: {
|
|
269
|
+
* id: { type: 'serial', primaryKey: true },
|
|
270
|
+
* email: { type: 'text', unique: true, notNull: true },
|
|
271
|
+
* name: { type: 'text', notNull: true },
|
|
272
|
+
* },
|
|
273
|
+
* posts: {
|
|
274
|
+
* id: { type: 'serial', primaryKey: true },
|
|
275
|
+
* userId: { type: 'bigint', notNull: true, references: 'users.id' },
|
|
276
|
+
* title: { type: 'text', notNull: true },
|
|
277
|
+
* },
|
|
278
|
+
* });
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
export declare function defineSchema(input: SchemaInput, options?: DefineSchemaOptions): SchemaDef;
|
|
282
|
+
export declare class ColumnBuilder {
|
|
283
|
+
private _config;
|
|
284
|
+
constructor();
|
|
285
|
+
serial(): this;
|
|
286
|
+
bigserial(): this;
|
|
287
|
+
bigint(): this;
|
|
288
|
+
integer(): this;
|
|
289
|
+
smallint(): this;
|
|
290
|
+
text(): this;
|
|
291
|
+
varchar(length: number): this;
|
|
292
|
+
boolean(): this;
|
|
293
|
+
timestamp(): this;
|
|
294
|
+
timestamptz(): this;
|
|
295
|
+
date(): this;
|
|
296
|
+
json(): this;
|
|
297
|
+
jsonb(): this;
|
|
298
|
+
uuid(): this;
|
|
299
|
+
real(): this;
|
|
300
|
+
doublePrecision(): this;
|
|
301
|
+
numeric(): this;
|
|
302
|
+
bytea(): this;
|
|
303
|
+
primaryKey(): this;
|
|
304
|
+
notNull(): this;
|
|
305
|
+
nullable(): this;
|
|
306
|
+
unique(): this;
|
|
307
|
+
default(val: string): this;
|
|
308
|
+
references(target: string, opts?: {
|
|
309
|
+
onDelete?: ReferentialAction;
|
|
310
|
+
onUpdate?: ReferentialAction;
|
|
311
|
+
}): this;
|
|
312
|
+
check(expression: string): this;
|
|
313
|
+
pii(): this;
|
|
314
|
+
array(): this;
|
|
315
|
+
build(): ColumnConfig;
|
|
316
|
+
}
|
|
317
|
+
/** @deprecated Use defineSchema() with plain objects instead */
|
|
318
|
+
type ColumnProxy = {
|
|
319
|
+
[K in 'serial' | 'bigserial' | 'bigint' | 'integer' | 'smallint' | 'text' | 'boolean' | 'timestamp' | 'timestamptz' | 'date' | 'json' | 'jsonb' | 'uuid' | 'real' | 'doublePrecision' | 'numeric' | 'bytea']: () => ColumnBuilder;
|
|
320
|
+
} & {
|
|
321
|
+
varchar: (length: number) => ColumnBuilder;
|
|
322
|
+
};
|
|
323
|
+
/** @deprecated Use defineSchema() with plain objects instead */
|
|
324
|
+
export declare const column: ColumnProxy;
|
|
325
|
+
/** @deprecated Use defineSchema() with plain objects instead */
|
|
326
|
+
export declare function table(columns: Record<string, ColumnBuilder>): TableDef;
|
|
327
|
+
/**
|
|
328
|
+
* Merge the explicit `manyToMany` declarations from a code-first {@link SchemaDef}
|
|
329
|
+
* into an introspected {@link SchemaMetadata}, returning a new metadata object
|
|
330
|
+
* with the `manyToMany` {@link RelationDef}s added.
|
|
331
|
+
*
|
|
332
|
+
* This is the runtime bridge for the code-first m2m API: `defineSchema` only
|
|
333
|
+
* produces DDL, so after `introspect()`ing the live database you call this to
|
|
334
|
+
* attach the m2m relations you declared. It is PURELY ADDITIVE — existing
|
|
335
|
+
* belongsTo/hasMany/hasOne relations are preserved, and a declared relation is
|
|
336
|
+
* skipped (not overwritten) if its name already exists on the source table.
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```ts
|
|
340
|
+
* const def = defineSchema({
|
|
341
|
+
* posts: { id: { type: 'serial', primaryKey: true },
|
|
342
|
+
* manyToMany: [{ name: 'tags', target: 'tags', through: 'postsTags',
|
|
343
|
+
* sourceKey: 'postId', targetKey: 'tagId' }] },
|
|
344
|
+
* tags: { id: { type: 'serial', primaryKey: true } },
|
|
345
|
+
* postsTags: { postId: { type: 'integer', references: 'posts.id' },
|
|
346
|
+
* tagId: { type: 'integer', references: 'tags.id' },
|
|
347
|
+
* primaryKey: ['postId', 'tagId'] },
|
|
348
|
+
* });
|
|
349
|
+
* let meta = await introspect({ connectionString });
|
|
350
|
+
* meta = applyManyToManyRelations(meta, def);
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
export declare function applyManyToManyRelations(meta: SchemaMetadata, def: SchemaDef): SchemaMetadata;
|
|
354
|
+
export { camelToSnake } from './schema.js';
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm — defineSchema() → SchemaMetadata bridge
|
|
3
|
+
*
|
|
4
|
+
* Converts a code-first {@link SchemaDef} (the output of `defineSchema()`)
|
|
5
|
+
* into the runtime {@link SchemaMetadata} shape that the query builder,
|
|
6
|
+
* `TurbineClient`, and the non-SQL engines consume — without touching a
|
|
7
|
+
* live database.
|
|
8
|
+
*
|
|
9
|
+
* Why this exists: the historical converter path (`introspect()` +
|
|
10
|
+
* `generate()`) requires a running SQL database, but code-first engines
|
|
11
|
+
* (PowDB, in-memory SQLite bootstraps, tests) only have the `SchemaDef`.
|
|
12
|
+
* `schemaDefToMetadata()` is the pure-function equivalent: its output
|
|
13
|
+
* matches what `turbine generate` would emit into `metadata.ts` for the
|
|
14
|
+
* same schema, minus the pieces only a live catalog can know (real index
|
|
15
|
+
* names, constraint names, view flags).
|
|
16
|
+
*
|
|
17
|
+
* Parity notes (ground truth = introspect.ts + generate.ts):
|
|
18
|
+
* - Relations are derived from `references:` exactly like introspection
|
|
19
|
+
* derives them from foreign keys: a `belongsTo` on the child table and
|
|
20
|
+
* a `hasMany` on the parent, with the same disambiguation rules when
|
|
21
|
+
* multiple FKs point at the same target.
|
|
22
|
+
* - Pure junction tables (2-column composite PK that IS the two
|
|
23
|
+
* single-column FKs to two distinct tables, no payload columns) get
|
|
24
|
+
* the same conservative auto-`manyToMany` treatment as introspection.
|
|
25
|
+
* - Explicit `manyToMany` declarations on the SchemaDef are merged via
|
|
26
|
+
* {@link applyManyToManyRelations} (additive, never clobbering).
|
|
27
|
+
* - `indexes` carries any declared `TableDef.indexes` (plain column and/or
|
|
28
|
+
* PowDB doc-field expression indexes); a table with none declared gets
|
|
29
|
+
* `[]`, which keeps `schemaHasIndexInfo()` false so the index advisor and
|
|
30
|
+
* the dev-mode missing-index warning stay silent instead of producing
|
|
31
|
+
* blanket false positives. Doc-field (docPath) indexes are ignored by the
|
|
32
|
+
* advisor, so a doc-only index set never flips `schemaHasIndexInfo()`.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { defineSchema, schemaDefToMetadata } from 'turbine-orm';
|
|
37
|
+
*
|
|
38
|
+
* const def = defineSchema({
|
|
39
|
+
* users: { id: { type: 'serial', primaryKey: true }, name: { type: 'text', notNull: true } },
|
|
40
|
+
* posts: { id: { type: 'serial', primaryKey: true },
|
|
41
|
+
* userId: { type: 'integer', notNull: true, references: 'users.id' } },
|
|
42
|
+
* });
|
|
43
|
+
* const metadata = schemaDefToMetadata(def);
|
|
44
|
+
* // → usable anywhere SchemaMetadata is expected (e.g. turbinePowDB, TurbineClient)
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
import { type SchemaMetadata } from './schema.js';
|
|
48
|
+
import { type SchemaDef } from './schema-builder.js';
|
|
49
|
+
/**
|
|
50
|
+
* Convert a code-first {@link SchemaDef} into runtime {@link SchemaMetadata}.
|
|
51
|
+
*
|
|
52
|
+
* Pure function — no database connection, no side effects, input untouched.
|
|
53
|
+
* The output is shaped identically to the `SCHEMA` constant `turbine generate`
|
|
54
|
+
* emits from introspection, so it can be handed to any consumer that expects
|
|
55
|
+
* introspected metadata: `new TurbineClient(config, metadata)`,
|
|
56
|
+
* `turbinePowDB(..., metadata)`, `QueryInterface`, the index advisor, etc.
|
|
57
|
+
*
|
|
58
|
+
* What maps:
|
|
59
|
+
* - Columns → full {@link ColumnMetadata} (snake_case name, camelCase field,
|
|
60
|
+
* pg type names, TS types, nullability, defaults, `isGenerated` for
|
|
61
|
+
* serial/bigserial, array + varchar length info, date-column tracking).
|
|
62
|
+
* - Column-level `primaryKey` and table-level composite `primaryKey`.
|
|
63
|
+
* - `unique: true` columns → single-column `uniqueColumns` entries.
|
|
64
|
+
* - `references:` FKs → `belongsTo` (child) + `hasMany` (parent) relations,
|
|
65
|
+
* including `onDelete`/`onUpdate` actions (the `'no action'` default is
|
|
66
|
+
* omitted, matching introspection).
|
|
67
|
+
* - Pure junction tables → auto-detected `manyToMany` relations (same
|
|
68
|
+
* conservative rules as introspection).
|
|
69
|
+
* - Explicit `manyToMany` declarations → merged additively.
|
|
70
|
+
* - Schema-level `enums`.
|
|
71
|
+
*
|
|
72
|
+
* What maps (continued):
|
|
73
|
+
* - `indexes` → declared `TableDef.indexes` become `IndexMetadata` (plain
|
|
74
|
+
* column indexes and PowDB doc-field expression indexes, the latter
|
|
75
|
+
* carrying `docPath`). A table with no declared indexes gets `[]`, keeping
|
|
76
|
+
* `schemaHasIndexInfo()` false so index-advisor consumers produce no false
|
|
77
|
+
* positives on index-less code-first metadata.
|
|
78
|
+
*
|
|
79
|
+
* What SchemaDef cannot express (and how it degrades):
|
|
80
|
+
* - Views → never marked (`isView` is introspection-only).
|
|
81
|
+
* - Composite foreign keys → `references:` is single-column by design.
|
|
82
|
+
*/
|
|
83
|
+
export declare function schemaDefToMetadata(def: SchemaDef): SchemaMetadata;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* turbine-orm — Schema SQL Generator
|
|
3
|
+
*
|
|
4
|
+
* Converts a SchemaDef (from defineSchema) into executable DDL statements.
|
|
5
|
+
* Also provides diff and push commands for syncing schema to a live database.
|
|
6
|
+
*/
|
|
7
|
+
import { type DestructiveStatement } from './cli/destructive.js';
|
|
8
|
+
import { type Dialect } from './dialect.js';
|
|
9
|
+
import { ValidationError } from './errors.js';
|
|
10
|
+
import { type ReferentialAction } from './schema.js';
|
|
11
|
+
import { type ColumnIndexDef, type SchemaDef, type TableDef } from './schema-builder.js';
|
|
12
|
+
export interface SchemaSqlOptions {
|
|
13
|
+
/** SQL dialect used for DDL generation. Defaults to PostgreSQL. */
|
|
14
|
+
dialect?: Dialect;
|
|
15
|
+
/**
|
|
16
|
+
* How to handle the pgvector extension when the schema contains a `vector`
|
|
17
|
+
* column. `'auto'` (default) prepends `CREATE EXTENSION IF NOT EXISTS vector;`
|
|
18
|
+
* — appropriate for `push`. `'manual'` emits a leading comment only, so the
|
|
19
|
+
* generated `.sql` migration doesn't silently require superuser privileges.
|
|
20
|
+
*/
|
|
21
|
+
extensions?: 'auto' | 'manual';
|
|
22
|
+
}
|
|
23
|
+
/** Map a {@link ReferentialAction} to its SQL keyword form. */
|
|
24
|
+
export declare function referentialActionToSql(action: ReferentialAction): string;
|
|
25
|
+
/**
|
|
26
|
+
* Convert a SchemaDef into an ordered array of SQL DDL statements.
|
|
27
|
+
*
|
|
28
|
+
* Returns CREATE TABLE statements (in dependency order based on references)
|
|
29
|
+
* followed by CREATE INDEX statements for foreign key columns.
|
|
30
|
+
*/
|
|
31
|
+
export declare function schemaToSQL(schema: SchemaDef, options?: SchemaSqlOptions): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Compare a declared plain index against a pg_indexes `indexdef` string.
|
|
34
|
+
* Returns a human-readable description of the first mismatch (uniqueness or
|
|
35
|
+
* column list), or null when the definitions agree. Expression/partial indexes
|
|
36
|
+
* in the DB never structurally match a plain column list, which is the
|
|
37
|
+
* intended outcome: the operator gets a warning rather than a silent skip.
|
|
38
|
+
*/
|
|
39
|
+
export declare function describeIndexDefMismatch(idx: ColumnIndexDef, indexdef: string): string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Pure decision for the "index exists in the DB but is not declared" warning
|
|
42
|
+
* pass. Extracted so the scope rule is unit-testable without a live database.
|
|
43
|
+
*
|
|
44
|
+
* The pass runs only when the table opts into index management by DEFINING an
|
|
45
|
+
* `indexes` array (`indexesDefined: true`), even when that array is empty or
|
|
46
|
+
* all-doc-field: deleting the last declared index must NOT silence the pass.
|
|
47
|
+
* Tables with no `indexes` key stay silent (the user is not managing indexes
|
|
48
|
+
* there). Recognized names (declared, unique-constraint / FK-column, `*_pkey`)
|
|
49
|
+
* are never flagged; everything else in the DB yields one warning.
|
|
50
|
+
*/
|
|
51
|
+
export declare function undeclaredIndexWarnings(opts: {
|
|
52
|
+
tableName: string;
|
|
53
|
+
indexesDefined: boolean;
|
|
54
|
+
dbIndexNames: Iterable<string>;
|
|
55
|
+
declaredNames: ReadonlySet<string>;
|
|
56
|
+
recognizedNames: ReadonlySet<string>;
|
|
57
|
+
}): string[];
|
|
58
|
+
export interface AlterColumnDef {
|
|
59
|
+
/** Column name in snake_case */
|
|
60
|
+
column: string;
|
|
61
|
+
/** What changed */
|
|
62
|
+
action: 'add' | 'drop' | 'alter_type' | 'set_not_null' | 'drop_not_null' | 'set_default' | 'drop_default' | 'add_unique' | 'drop_unique';
|
|
63
|
+
/** SQL fragment for the alteration */
|
|
64
|
+
sql: string;
|
|
65
|
+
/** SQL to reverse this change (for DOWN migrations) */
|
|
66
|
+
reverseSql: string;
|
|
67
|
+
}
|
|
68
|
+
export interface AlterDef {
|
|
69
|
+
/** Table name */
|
|
70
|
+
table: string;
|
|
71
|
+
/** Column-level alterations */
|
|
72
|
+
columns: AlterColumnDef[];
|
|
73
|
+
}
|
|
74
|
+
export interface DiffResult {
|
|
75
|
+
/** Tables that exist in schema but not in DB — need CREATE TABLE */
|
|
76
|
+
create: TableDef[];
|
|
77
|
+
/** Tables that exist in both but differ — need ALTER TABLE */
|
|
78
|
+
alter: AlterDef[];
|
|
79
|
+
/** Table names that exist in DB but not in schema — would need DROP TABLE */
|
|
80
|
+
drop: string[];
|
|
81
|
+
/** SQL statements to execute the diff (UP direction) */
|
|
82
|
+
statements: string[];
|
|
83
|
+
/** SQL statements to reverse the diff (DOWN direction, for migrations) */
|
|
84
|
+
reverseStatements: string[];
|
|
85
|
+
/**
|
|
86
|
+
* Human-readable warnings for changes the diff detected but refuses to apply
|
|
87
|
+
* automatically because they are destructive or otherwise unsafe (enum value
|
|
88
|
+
* removal/reorder, etc.). Never executed — surfaced for the operator.
|
|
89
|
+
*/
|
|
90
|
+
warnings?: string[];
|
|
91
|
+
}
|
|
92
|
+
/** A FK's current referential actions as read from the DB. */
|
|
93
|
+
export interface DbForeignKey {
|
|
94
|
+
constraintName: string;
|
|
95
|
+
column: string;
|
|
96
|
+
targetTable: string;
|
|
97
|
+
targetColumn: string;
|
|
98
|
+
onDelete: ReferentialAction;
|
|
99
|
+
onUpdate: ReferentialAction;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Build the `ADD CONSTRAINT ... FOREIGN KEY` statement for a FK with the given
|
|
103
|
+
* referential actions. Default (`no action`) clauses are omitted, matching how
|
|
104
|
+
* Postgres normalizes them, so re-diffing is stable.
|
|
105
|
+
*/
|
|
106
|
+
export declare function buildAddForeignKeyStatement(table: string, constraintName: string, column: string, targetTable: string, targetColumn: string, onDelete: ReferentialAction, onUpdate: ReferentialAction, dialect?: Dialect): string;
|
|
107
|
+
/**
|
|
108
|
+
* Decide whether a FK's referential actions changed. When they differ, returns
|
|
109
|
+
* the DROP + ADD CONSTRAINT statements (and their reverse) — Postgres has no
|
|
110
|
+
* `ALTER CONSTRAINT` for referential actions, so drop-and-recreate is the only
|
|
111
|
+
* path. Returns null when the actions already match.
|
|
112
|
+
*/
|
|
113
|
+
export declare function diffReferentialAction(table: string, db: DbForeignKey, schemaOnDelete: ReferentialAction, schemaOnUpdate: ReferentialAction, dialect?: Dialect): {
|
|
114
|
+
statements: string[];
|
|
115
|
+
reverseStatements: string[];
|
|
116
|
+
} | null;
|
|
117
|
+
/**
|
|
118
|
+
* Compute append-only enum value changes. Returns `ALTER TYPE ... ADD VALUE`
|
|
119
|
+
* statements for labels present in the schema but not the DB (in order), plus a
|
|
120
|
+
* destructive warning for any DB label the schema dropped or any reorder —
|
|
121
|
+
* Postgres cannot remove or reorder enum values without recreating the type.
|
|
122
|
+
*/
|
|
123
|
+
export declare function diffEnumValues(enumName: string, schemaLabels: readonly string[], dbLabels: readonly string[], dialect?: Dialect): {
|
|
124
|
+
statements: string[];
|
|
125
|
+
warnings: string[];
|
|
126
|
+
};
|
|
127
|
+
/** A check constraint as declared or read from the DB. */
|
|
128
|
+
export interface CheckSpec {
|
|
129
|
+
/** Constraint name. Always emitted through `dialect.quoteIdentifier`. */
|
|
130
|
+
name: string;
|
|
131
|
+
/**
|
|
132
|
+
* RAW SQL boolean expression (e.g. `price >= 0`), emitted VERBATIM into the
|
|
133
|
+
* `CHECK (...)` clause.
|
|
134
|
+
*
|
|
135
|
+
* This is a deliberate escape hatch: a CHECK body is an arbitrary SQL
|
|
136
|
+
* expression, so it cannot be quoted, parameterized, or validated by the DDL
|
|
137
|
+
* builder without reimplementing the server's expression parser. The contract
|
|
138
|
+
* is therefore on the caller: the expression MUST come from the project's own
|
|
139
|
+
* schema definition (a `defineSchema` literal or an introspected constraint),
|
|
140
|
+
* and must NEVER be built from user input, request data, or any other
|
|
141
|
+
* untrusted source. Anything interpolated into it runs with the privileges of
|
|
142
|
+
* the migration.
|
|
143
|
+
*/
|
|
144
|
+
expression: string;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Diff a table's CHECK constraints (matched by name). Adds constraints missing
|
|
148
|
+
* from the DB, drops DB constraints absent from the schema, and drop+adds when a
|
|
149
|
+
* same-named constraint's expression changed. Expression comparison is a naive
|
|
150
|
+
* whitespace-insensitive match — semantically-equal-but-different-spelled
|
|
151
|
+
* expressions may re-emit (documented; harmless drop+add).
|
|
152
|
+
*/
|
|
153
|
+
export declare function diffCheckConstraints(table: string, schemaChecks: readonly CheckSpec[], dbChecks: readonly CheckSpec[], dialect?: Dialect): {
|
|
154
|
+
statements: string[];
|
|
155
|
+
reverseStatements: string[];
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Compare a SchemaDef against a live Postgres database and return the diff.
|
|
159
|
+
*
|
|
160
|
+
* Connects to the database, inspects the public schema, and computes what
|
|
161
|
+
* DDL is needed to make the database match the schema definition.
|
|
162
|
+
*/
|
|
163
|
+
export declare function schemaDiff(schema: SchemaDef, connectionString: string): Promise<DiffResult>;
|
|
164
|
+
/**
|
|
165
|
+
* Scan a set of diff statements for data-destroying operations, using the same
|
|
166
|
+
* conservative scanner (`scanDestructiveSql`) that gates `migrate up`/`down`.
|
|
167
|
+
* Push mostly emits additive DDL, but a type change surfaces as a lossy
|
|
168
|
+
* `ALTER COLUMN ... TYPE` cast, exactly the kind of silent data loss `push`
|
|
169
|
+
* must never apply without an explicit opt-in.
|
|
170
|
+
*/
|
|
171
|
+
export declare function findDestructivePushStatements(statements: readonly string[]): DestructiveStatement[];
|
|
172
|
+
export interface PushResult {
|
|
173
|
+
/** Number of statements executed */
|
|
174
|
+
statementsExecuted: number;
|
|
175
|
+
/** The SQL statements that were run */
|
|
176
|
+
statements: string[];
|
|
177
|
+
/** Tables created */
|
|
178
|
+
tablesCreated: string[];
|
|
179
|
+
/** Tables altered */
|
|
180
|
+
tablesAltered: string[];
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Thrown by {@link schemaPush} when the diff contains data-destroying statements
|
|
184
|
+
* and `allowDestructive` was not set. A typed subclass of {@link ValidationError}
|
|
185
|
+
* (same `TURBINE_E003` code, no new taxonomy entry) so callers can branch on
|
|
186
|
+
* `instanceof DestructivePushRefusal` instead of sniffing the message text. The
|
|
187
|
+
* offending statements are carried on `.destructive` for programmatic display.
|
|
188
|
+
*/
|
|
189
|
+
export declare class DestructivePushRefusal extends ValidationError {
|
|
190
|
+
/** The destructive statements the push refused to apply. */
|
|
191
|
+
readonly destructive: DestructiveStatement[];
|
|
192
|
+
constructor(destructive: DestructiveStatement[]);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Push a schema definition to a live database.
|
|
196
|
+
*
|
|
197
|
+
* Computes the diff, then executes the resulting DDL statements in a
|
|
198
|
+
* single transaction. It will NOT drop tables or columns.
|
|
199
|
+
*
|
|
200
|
+
* Data-loss gate: if the diff contains a destructive statement (e.g. a lossy
|
|
201
|
+
* `ALTER COLUMN ... TYPE` cast), `schemaPush` throws a
|
|
202
|
+
* {@link DestructivePushRefusal} (a {@link ValidationError} subclass carrying
|
|
203
|
+
* the offending statements on `.destructive`) listing the statements UNLESS
|
|
204
|
+
* `allowDestructive: true` is passed. The CLI (`turbine push`) catches this and
|
|
205
|
+
* prompts for the same typed confirmation as `migrate up`; programmatic callers
|
|
206
|
+
* must opt in explicitly.
|
|
207
|
+
*/
|
|
208
|
+
export declare function schemaPush(schema: SchemaDef, connectionString: string, options?: {
|
|
209
|
+
dryRun?: boolean;
|
|
210
|
+
allowDestructive?: boolean;
|
|
211
|
+
precomputedDiff?: DiffResult;
|
|
212
|
+
}): Promise<PushResult>;
|
|
213
|
+
/**
|
|
214
|
+
* Generate the full DDL as a single formatted string.
|
|
215
|
+
* Useful for printing or saving to a .sql file.
|
|
216
|
+
*/
|
|
217
|
+
export declare function schemaToSQLString(schema: SchemaDef, options?: SchemaSqlOptions): string;
|