@prisma-next/family-sql 0.3.0-pr.99.6 → 0.3.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/LICENSE +201 -0
- package/README.md +58 -22
- package/dist/authoring-type-constructors-DgU-RFaP.mjs +203 -0
- package/dist/authoring-type-constructors-DgU-RFaP.mjs.map +1 -0
- package/dist/control-adapter.d.mts +54 -0
- package/dist/control-adapter.d.mts.map +1 -0
- package/dist/control-adapter.mjs +1 -0
- package/dist/control.d.mts +386 -0
- package/dist/control.d.mts.map +1 -0
- package/dist/control.mjs +643 -0
- package/dist/control.mjs.map +1 -0
- package/dist/operation-descriptors.d.mts +380 -0
- package/dist/operation-descriptors.d.mts.map +1 -0
- package/dist/operation-descriptors.mjs +294 -0
- package/dist/operation-descriptors.mjs.map +1 -0
- package/dist/pack.d.mts +248 -0
- package/dist/pack.d.mts.map +1 -0
- package/dist/pack.mjs +18 -0
- package/dist/pack.mjs.map +1 -0
- package/dist/runtime.d.mts +27 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +38 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/schema-verify.d.mts +48 -0
- package/dist/schema-verify.d.mts.map +1 -0
- package/dist/schema-verify.mjs +3 -0
- package/dist/test-utils.d.mts +2 -0
- package/dist/test-utils.mjs +3 -0
- package/dist/types-BaUzKt6Q.d.mts +353 -0
- package/dist/types-BaUzKt6Q.d.mts.map +1 -0
- package/dist/verify-DZHtfcmj.mjs +108 -0
- package/dist/verify-DZHtfcmj.mjs.map +1 -0
- package/dist/verify-sql-schema-BBhkqEDo.d.mts +67 -0
- package/dist/verify-sql-schema-BBhkqEDo.d.mts.map +1 -0
- package/dist/verify-sql-schema-lR-tlboL.mjs +1174 -0
- package/dist/verify-sql-schema-lR-tlboL.mjs.map +1 -0
- package/dist/verify.d.mts +31 -0
- package/dist/verify.d.mts.map +1 -0
- package/dist/verify.mjs +3 -0
- package/package.json +36 -44
- package/src/core/assembly.ts +123 -155
- package/src/core/authoring-field-presets.ts +207 -0
- package/src/core/authoring-type-constructors.ts +17 -0
- package/src/core/control-adapter.ts +18 -10
- package/src/core/control-descriptor.ts +28 -0
- package/src/core/control-instance.ts +700 -0
- package/src/core/migrations/contract-to-schema-ir.ts +269 -0
- package/src/core/migrations/descriptor-schemas.ts +172 -0
- package/src/core/migrations/operation-descriptors.ts +213 -0
- package/src/core/migrations/policies.ts +1 -1
- package/src/core/migrations/types.ts +199 -175
- package/src/core/runtime-descriptor.ts +19 -41
- package/src/core/runtime-instance.ts +11 -133
- package/src/core/schema-verify/verify-helpers.ts +104 -22
- package/src/core/schema-verify/verify-sql-schema.ts +964 -418
- package/src/core/verify.ts +4 -13
- package/src/exports/control.ts +31 -8
- package/src/exports/operation-descriptors.ts +52 -0
- package/src/exports/pack.ts +16 -0
- package/src/exports/runtime.ts +2 -6
- package/src/exports/schema-verify.ts +4 -1
- package/src/exports/test-utils.ts +3 -4
- package/dist/chunk-GYEG3I7U.js +0 -624
- package/dist/chunk-GYEG3I7U.js.map +0 -1
- package/dist/chunk-SU7LN2UH.js +0 -96
- package/dist/chunk-SU7LN2UH.js.map +0 -1
- package/dist/chunk-XH2Y5NTD.js +0 -715
- package/dist/chunk-XH2Y5NTD.js.map +0 -1
- package/dist/core/assembly.d.ts +0 -43
- package/dist/core/assembly.d.ts.map +0 -1
- package/dist/core/control-adapter.d.ts +0 -42
- package/dist/core/control-adapter.d.ts.map +0 -1
- package/dist/core/descriptor.d.ts +0 -28
- package/dist/core/descriptor.d.ts.map +0 -1
- package/dist/core/instance.d.ts +0 -140
- package/dist/core/instance.d.ts.map +0 -1
- package/dist/core/migrations/plan-helpers.d.ts +0 -20
- package/dist/core/migrations/plan-helpers.d.ts.map +0 -1
- package/dist/core/migrations/policies.d.ts +0 -6
- package/dist/core/migrations/policies.d.ts.map +0 -1
- package/dist/core/migrations/types.d.ts +0 -280
- package/dist/core/migrations/types.d.ts.map +0 -1
- package/dist/core/runtime-descriptor.d.ts +0 -19
- package/dist/core/runtime-descriptor.d.ts.map +0 -1
- package/dist/core/runtime-instance.d.ts +0 -54
- package/dist/core/runtime-instance.d.ts.map +0 -1
- package/dist/core/schema-verify/verify-helpers.d.ts +0 -96
- package/dist/core/schema-verify/verify-helpers.d.ts.map +0 -1
- package/dist/core/schema-verify/verify-sql-schema.d.ts +0 -45
- package/dist/core/schema-verify/verify-sql-schema.d.ts.map +0 -1
- package/dist/core/verify.d.ts +0 -39
- package/dist/core/verify.d.ts.map +0 -1
- package/dist/exports/control-adapter.d.ts +0 -2
- package/dist/exports/control-adapter.d.ts.map +0 -1
- package/dist/exports/control-adapter.js +0 -1
- package/dist/exports/control-adapter.js.map +0 -1
- package/dist/exports/control.d.ts +0 -13
- package/dist/exports/control.d.ts.map +0 -1
- package/dist/exports/control.js +0 -149
- package/dist/exports/control.js.map +0 -1
- package/dist/exports/runtime.d.ts +0 -8
- package/dist/exports/runtime.d.ts.map +0 -1
- package/dist/exports/runtime.js +0 -64
- package/dist/exports/runtime.js.map +0 -1
- package/dist/exports/schema-verify.d.ts +0 -11
- package/dist/exports/schema-verify.d.ts.map +0 -1
- package/dist/exports/schema-verify.js +0 -15
- package/dist/exports/schema-verify.js.map +0 -1
- package/dist/exports/test-utils.d.ts +0 -7
- package/dist/exports/test-utils.d.ts.map +0 -1
- package/dist/exports/test-utils.js +0 -17
- package/dist/exports/test-utils.js.map +0 -1
- package/dist/exports/verify.d.ts +0 -2
- package/dist/exports/verify.d.ts.map +0 -1
- package/dist/exports/verify.js +0 -11
- package/dist/exports/verify.js.map +0 -1
- package/src/core/descriptor.ts +0 -33
- package/src/core/instance.ts +0 -909
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import type { ColumnDefault, Contract } from '@prisma-next/contract/types';
|
|
2
|
+
import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
|
|
3
|
+
import type { MigrationPlannerConflict } from '@prisma-next/framework-components/control';
|
|
4
|
+
import type {
|
|
5
|
+
ForeignKey,
|
|
6
|
+
Index,
|
|
7
|
+
SqlStorage,
|
|
8
|
+
StorageColumn,
|
|
9
|
+
StorageTable,
|
|
10
|
+
UniqueConstraint,
|
|
11
|
+
} from '@prisma-next/sql-contract/types';
|
|
12
|
+
import { defaultIndexName } from '@prisma-next/sql-schema-ir/naming';
|
|
13
|
+
import type {
|
|
14
|
+
DependencyIR,
|
|
15
|
+
SqlAnnotations,
|
|
16
|
+
SqlColumnIR,
|
|
17
|
+
SqlForeignKeyIR,
|
|
18
|
+
SqlIndexIR,
|
|
19
|
+
SqlSchemaIR,
|
|
20
|
+
SqlTableIR,
|
|
21
|
+
SqlUniqueIR,
|
|
22
|
+
} from '@prisma-next/sql-schema-ir/types';
|
|
23
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
24
|
+
import { collectInitDependencies } from './types';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Target-specific callback that expands a column's base `nativeType` and optional
|
|
28
|
+
* `typeParams` into the fully-qualified type string used by the database
|
|
29
|
+
* (e.g. `character` + `{ length: 36 }` → `character(36)`).
|
|
30
|
+
*
|
|
31
|
+
* This lives in the family layer as a callback rather than importing a concrete
|
|
32
|
+
* implementation because each target (Postgres, MySQL, SQLite, …) has its own
|
|
33
|
+
* parameterization syntax. The target wires its expander when calling
|
|
34
|
+
* `contractToSchemaIR`, keeping the family layer target-agnostic.
|
|
35
|
+
*/
|
|
36
|
+
export type NativeTypeExpander = (input: {
|
|
37
|
+
readonly nativeType: string;
|
|
38
|
+
readonly codecId?: string;
|
|
39
|
+
readonly typeParams?: Record<string, unknown>;
|
|
40
|
+
}) => string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Target-specific callback that renders a `ColumnDefault` into the raw SQL literal
|
|
44
|
+
* string stored in `SqlColumnIR.default`.
|
|
45
|
+
*
|
|
46
|
+
* Default value serialization is target-specific (quoting, casting, type syntax vary
|
|
47
|
+
* between Postgres, MySQL, SQLite, …). This callback follows the same IoC pattern as
|
|
48
|
+
* `NativeTypeExpander`: the target provides its renderer when calling
|
|
49
|
+
* `contractToSchemaIR`, keeping the family layer target-agnostic.
|
|
50
|
+
*/
|
|
51
|
+
export type DefaultRenderer = (def: ColumnDefault, column: StorageColumn) => string;
|
|
52
|
+
|
|
53
|
+
function convertColumn(
|
|
54
|
+
name: string,
|
|
55
|
+
column: StorageColumn,
|
|
56
|
+
expandNativeType: NativeTypeExpander | undefined,
|
|
57
|
+
renderDefault: DefaultRenderer | undefined,
|
|
58
|
+
): SqlColumnIR {
|
|
59
|
+
const nativeType = expandNativeType
|
|
60
|
+
? expandNativeType({
|
|
61
|
+
nativeType: column.nativeType,
|
|
62
|
+
codecId: column.codecId,
|
|
63
|
+
...ifDefined('typeParams', column.typeParams),
|
|
64
|
+
})
|
|
65
|
+
: column.nativeType;
|
|
66
|
+
return {
|
|
67
|
+
name,
|
|
68
|
+
nativeType,
|
|
69
|
+
nullable: column.nullable,
|
|
70
|
+
...ifDefined(
|
|
71
|
+
'default',
|
|
72
|
+
column.default != null && renderDefault ? renderDefault(column.default, column) : undefined,
|
|
73
|
+
),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function convertUnique(unique: UniqueConstraint): SqlUniqueIR {
|
|
78
|
+
return {
|
|
79
|
+
columns: unique.columns,
|
|
80
|
+
...ifDefined('name', unique.name),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function convertIndex(index: Index): SqlIndexIR {
|
|
85
|
+
return {
|
|
86
|
+
columns: index.columns,
|
|
87
|
+
unique: false,
|
|
88
|
+
...ifDefined('name', index.name),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function convertForeignKey(fk: ForeignKey): SqlForeignKeyIR {
|
|
93
|
+
return {
|
|
94
|
+
columns: fk.columns,
|
|
95
|
+
referencedTable: fk.references.table,
|
|
96
|
+
referencedColumns: fk.references.columns,
|
|
97
|
+
...ifDefined('name', fk.name),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function convertTable(
|
|
102
|
+
name: string,
|
|
103
|
+
table: StorageTable,
|
|
104
|
+
expandNativeType: NativeTypeExpander | undefined,
|
|
105
|
+
renderDefault: DefaultRenderer | undefined,
|
|
106
|
+
): SqlTableIR {
|
|
107
|
+
const columns: Record<string, SqlColumnIR> = {};
|
|
108
|
+
for (const [colName, colDef] of Object.entries(table.columns)) {
|
|
109
|
+
columns[colName] = convertColumn(colName, colDef, expandNativeType, renderDefault);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const satisfiedIndexColumns = new Set([
|
|
113
|
+
...table.indexes.map((idx) => idx.columns.join(',')),
|
|
114
|
+
...table.uniques.map((unique) => unique.columns.join(',')),
|
|
115
|
+
...(table.primaryKey ? [table.primaryKey.columns.join(',')] : []),
|
|
116
|
+
]);
|
|
117
|
+
const fkBackingIndexes: SqlIndexIR[] = [];
|
|
118
|
+
for (const fk of table.foreignKeys) {
|
|
119
|
+
if (fk.index === false) continue;
|
|
120
|
+
const key = fk.columns.join(',');
|
|
121
|
+
if (satisfiedIndexColumns.has(key)) continue;
|
|
122
|
+
fkBackingIndexes.push({
|
|
123
|
+
columns: fk.columns,
|
|
124
|
+
unique: false,
|
|
125
|
+
name: defaultIndexName(name, fk.columns),
|
|
126
|
+
});
|
|
127
|
+
satisfiedIndexColumns.add(key);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
name,
|
|
132
|
+
columns,
|
|
133
|
+
...ifDefined('primaryKey', table.primaryKey),
|
|
134
|
+
foreignKeys: table.foreignKeys.map(convertForeignKey),
|
|
135
|
+
uniques: table.uniques.map(convertUnique),
|
|
136
|
+
indexes: [...table.indexes.map(convertIndex), ...fkBackingIndexes],
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Detects destructive changes between two contract storages.
|
|
142
|
+
*
|
|
143
|
+
* The additive-only planner silently ignores removals (tables, columns).
|
|
144
|
+
* This function detects those removals so callers can report them as conflicts
|
|
145
|
+
* rather than silently producing an empty plan.
|
|
146
|
+
*
|
|
147
|
+
* Returns an empty array if no destructive changes are found.
|
|
148
|
+
*/
|
|
149
|
+
export function detectDestructiveChanges(
|
|
150
|
+
from: SqlStorage | null,
|
|
151
|
+
to: SqlStorage,
|
|
152
|
+
): readonly MigrationPlannerConflict[] {
|
|
153
|
+
if (!from) return [];
|
|
154
|
+
|
|
155
|
+
const hasOwn = (value: object, key: string): boolean => Object.hasOwn(value, key);
|
|
156
|
+
|
|
157
|
+
const conflicts: MigrationPlannerConflict[] = [];
|
|
158
|
+
|
|
159
|
+
for (const tableName of Object.keys(from.tables)) {
|
|
160
|
+
if (!hasOwn(to.tables, tableName)) {
|
|
161
|
+
conflicts.push({
|
|
162
|
+
kind: 'tableRemoved',
|
|
163
|
+
summary: `Table "${tableName}" was removed`,
|
|
164
|
+
});
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const toTable = to.tables[tableName] as StorageTable;
|
|
169
|
+
const fromTable = from.tables[tableName];
|
|
170
|
+
if (!fromTable) continue;
|
|
171
|
+
|
|
172
|
+
for (const columnName of Object.keys(fromTable.columns)) {
|
|
173
|
+
if (!hasOwn(toTable.columns, columnName)) {
|
|
174
|
+
conflicts.push({
|
|
175
|
+
kind: 'columnRemoved',
|
|
176
|
+
summary: `Column "${tableName}"."${columnName}" was removed`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return conflicts;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface ContractToSchemaIROptions {
|
|
186
|
+
readonly annotationNamespace: string;
|
|
187
|
+
readonly expandNativeType?: NativeTypeExpander;
|
|
188
|
+
readonly renderDefault?: DefaultRenderer;
|
|
189
|
+
readonly frameworkComponents?: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Converts a `Contract` to `SqlSchemaIR`.
|
|
194
|
+
*
|
|
195
|
+
* Reads `contract.storage` for tables, `contract.storage.types` for type
|
|
196
|
+
* annotations, and derives database dependencies from `frameworkComponents`
|
|
197
|
+
* (each component's `databaseDependencies.init[].id`).
|
|
198
|
+
* Storage-type annotations are written under `options.annotationNamespace`.
|
|
199
|
+
*
|
|
200
|
+
* Drops codec metadata (`codecId`, `typeRef`) since the schema IR only represents
|
|
201
|
+
* structural information. When `expandNativeType` is provided, parameterized types
|
|
202
|
+
* are expanded (e.g. `character` + `{ length: 36 }` → `character(36)`) so the
|
|
203
|
+
* resulting IR compares correctly against the "to" contract during planning.
|
|
204
|
+
*
|
|
205
|
+
* Returns an empty schema IR when `contract` is `null` (new project).
|
|
206
|
+
*/
|
|
207
|
+
export function contractToSchemaIR(
|
|
208
|
+
contract: Contract<SqlStorage> | null,
|
|
209
|
+
options: ContractToSchemaIROptions,
|
|
210
|
+
): SqlSchemaIR {
|
|
211
|
+
if (options.annotationNamespace.length === 0) {
|
|
212
|
+
throw new Error('annotationNamespace must be a non-empty string');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (!contract) {
|
|
216
|
+
return { tables: {}, dependencies: [] };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const storage = contract.storage;
|
|
220
|
+
const tables: Record<string, SqlTableIR> = {};
|
|
221
|
+
for (const [tableName, tableDef] of Object.entries(storage.tables)) {
|
|
222
|
+
tables[tableName] = convertTable(
|
|
223
|
+
tableName,
|
|
224
|
+
tableDef,
|
|
225
|
+
options.expandNativeType,
|
|
226
|
+
options.renderDefault,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const dependencies = deduplicateDependencyIRs(
|
|
231
|
+
collectInitDependencies(options.frameworkComponents ?? []),
|
|
232
|
+
);
|
|
233
|
+
const annotations = deriveAnnotations(storage, options.annotationNamespace);
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
tables,
|
|
237
|
+
dependencies,
|
|
238
|
+
...ifDefined('annotations', annotations),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function deduplicateDependencyIRs(
|
|
243
|
+
deps: readonly { readonly id: string }[],
|
|
244
|
+
): readonly DependencyIR[] {
|
|
245
|
+
const seen = new Set<string>();
|
|
246
|
+
const result: DependencyIR[] = [];
|
|
247
|
+
for (const dep of deps) {
|
|
248
|
+
if (dep.id.trim().length === 0) {
|
|
249
|
+
throw new Error('Dependency id must be a non-empty string');
|
|
250
|
+
}
|
|
251
|
+
if (seen.has(dep.id)) continue;
|
|
252
|
+
seen.add(dep.id);
|
|
253
|
+
result.push({ id: dep.id });
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function deriveAnnotations(
|
|
259
|
+
storage: SqlStorage,
|
|
260
|
+
annotationNamespace: string,
|
|
261
|
+
): SqlAnnotations | undefined {
|
|
262
|
+
if (!storage.types || Object.keys(storage.types).length === 0) return undefined;
|
|
263
|
+
// Re-key by nativeType to match the structure produced by introspection
|
|
264
|
+
const byNativeType: Record<string, (typeof storage.types)[string]> = {};
|
|
265
|
+
for (const typeInstance of Object.values(storage.types)) {
|
|
266
|
+
byNativeType[typeInstance.nativeType] = typeInstance;
|
|
267
|
+
}
|
|
268
|
+
return { [annotationNamespace]: { storageTypes: byNativeType } };
|
|
269
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arktype schemas for SQL migration operation descriptors.
|
|
3
|
+
*
|
|
4
|
+
* These schemas are the source of truth for descriptor shapes.
|
|
5
|
+
* TypeScript types are derived via `typeof schema.infer`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { type } from 'arktype';
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Table descriptors
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
export const CreateTableSchema = type({ kind: "'createTable'", table: 'string' });
|
|
15
|
+
export const DropTableSchema = type({ kind: "'dropTable'", table: 'string' });
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Column descriptors
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
export const AddColumnSchema = type({
|
|
22
|
+
kind: "'addColumn'",
|
|
23
|
+
table: 'string',
|
|
24
|
+
column: 'string',
|
|
25
|
+
'overrides?': { 'nullable?': 'boolean' },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export const DropColumnSchema = type({ kind: "'dropColumn'", table: 'string', column: 'string' });
|
|
29
|
+
|
|
30
|
+
export const AlterColumnTypeSchema = type({
|
|
31
|
+
kind: "'alterColumnType'",
|
|
32
|
+
table: 'string',
|
|
33
|
+
column: 'string',
|
|
34
|
+
'using?': 'string',
|
|
35
|
+
'toType?': 'string',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const SetNotNullSchema = type({ kind: "'setNotNull'", table: 'string', column: 'string' });
|
|
39
|
+
export const DropNotNullSchema = type({ kind: "'dropNotNull'", table: 'string', column: 'string' });
|
|
40
|
+
export const SetDefaultSchema = type({ kind: "'setDefault'", table: 'string', column: 'string' });
|
|
41
|
+
export const DropDefaultSchema = type({ kind: "'dropDefault'", table: 'string', column: 'string' });
|
|
42
|
+
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Constraint descriptors
|
|
45
|
+
// ============================================================================
|
|
46
|
+
|
|
47
|
+
export const AddPrimaryKeySchema = type({ kind: "'addPrimaryKey'", table: 'string' });
|
|
48
|
+
export const AddUniqueSchema = type({ kind: "'addUnique'", table: 'string', columns: 'string[]' });
|
|
49
|
+
export const AddForeignKeySchema = type({
|
|
50
|
+
kind: "'addForeignKey'",
|
|
51
|
+
table: 'string',
|
|
52
|
+
columns: 'string[]',
|
|
53
|
+
});
|
|
54
|
+
export const DropConstraintSchema = type({
|
|
55
|
+
kind: "'dropConstraint'",
|
|
56
|
+
table: 'string',
|
|
57
|
+
constraintName: 'string',
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Index descriptors
|
|
62
|
+
// ============================================================================
|
|
63
|
+
|
|
64
|
+
export const CreateIndexSchema = type({
|
|
65
|
+
kind: "'createIndex'",
|
|
66
|
+
table: 'string',
|
|
67
|
+
columns: 'string[]',
|
|
68
|
+
});
|
|
69
|
+
export const DropIndexSchema = type({
|
|
70
|
+
kind: "'dropIndex'",
|
|
71
|
+
table: 'string',
|
|
72
|
+
indexName: 'string',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// Type descriptors
|
|
77
|
+
// ============================================================================
|
|
78
|
+
|
|
79
|
+
export const CreateEnumTypeSchema = type({
|
|
80
|
+
kind: "'createEnumType'",
|
|
81
|
+
typeName: 'string',
|
|
82
|
+
'values?': 'string[]',
|
|
83
|
+
});
|
|
84
|
+
export const AddEnumValuesSchema = type({
|
|
85
|
+
kind: "'addEnumValues'",
|
|
86
|
+
typeName: 'string',
|
|
87
|
+
values: 'string[]',
|
|
88
|
+
});
|
|
89
|
+
export const DropEnumTypeSchema = type({ kind: "'dropEnumType'", typeName: 'string' });
|
|
90
|
+
export const RenameTypeSchema = type({
|
|
91
|
+
kind: "'renameType'",
|
|
92
|
+
fromName: 'string',
|
|
93
|
+
toName: 'string',
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// Dependency descriptors
|
|
98
|
+
// ============================================================================
|
|
99
|
+
|
|
100
|
+
export const CreateDependencySchema = type({
|
|
101
|
+
kind: "'createDependency'",
|
|
102
|
+
dependencyId: 'string',
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// ============================================================================
|
|
106
|
+
// Data transform descriptor
|
|
107
|
+
// ============================================================================
|
|
108
|
+
|
|
109
|
+
export const DataTransformSchema = type({
|
|
110
|
+
kind: "'dataTransform'",
|
|
111
|
+
name: 'string',
|
|
112
|
+
source: 'string',
|
|
113
|
+
check: 'boolean | Function | symbol | object',
|
|
114
|
+
run: '(Function | symbol | object)[]',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// Union schema
|
|
119
|
+
// ============================================================================
|
|
120
|
+
|
|
121
|
+
export const SqlMigrationOpDescriptorSchema = type.or(
|
|
122
|
+
CreateTableSchema,
|
|
123
|
+
DropTableSchema,
|
|
124
|
+
AddColumnSchema,
|
|
125
|
+
DropColumnSchema,
|
|
126
|
+
AlterColumnTypeSchema,
|
|
127
|
+
SetNotNullSchema,
|
|
128
|
+
DropNotNullSchema,
|
|
129
|
+
SetDefaultSchema,
|
|
130
|
+
DropDefaultSchema,
|
|
131
|
+
AddPrimaryKeySchema,
|
|
132
|
+
AddUniqueSchema,
|
|
133
|
+
AddForeignKeySchema,
|
|
134
|
+
DropConstraintSchema,
|
|
135
|
+
CreateIndexSchema,
|
|
136
|
+
DropIndexSchema,
|
|
137
|
+
CreateEnumTypeSchema,
|
|
138
|
+
AddEnumValuesSchema,
|
|
139
|
+
DropEnumTypeSchema,
|
|
140
|
+
RenameTypeSchema,
|
|
141
|
+
CreateDependencySchema,
|
|
142
|
+
DataTransformSchema,
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
export const MigrationDescriptorArraySchema = SqlMigrationOpDescriptorSchema.array();
|
|
146
|
+
|
|
147
|
+
// ============================================================================
|
|
148
|
+
// Derived types
|
|
149
|
+
// ============================================================================
|
|
150
|
+
|
|
151
|
+
export type CreateTableDescriptor = typeof CreateTableSchema.infer;
|
|
152
|
+
export type DropTableDescriptor = typeof DropTableSchema.infer;
|
|
153
|
+
export type AddColumnDescriptor = typeof AddColumnSchema.infer;
|
|
154
|
+
export type DropColumnDescriptor = typeof DropColumnSchema.infer;
|
|
155
|
+
export type AlterColumnTypeDescriptor = typeof AlterColumnTypeSchema.infer;
|
|
156
|
+
export type SetNotNullDescriptor = typeof SetNotNullSchema.infer;
|
|
157
|
+
export type DropNotNullDescriptor = typeof DropNotNullSchema.infer;
|
|
158
|
+
export type SetDefaultDescriptor = typeof SetDefaultSchema.infer;
|
|
159
|
+
export type DropDefaultDescriptor = typeof DropDefaultSchema.infer;
|
|
160
|
+
export type AddPrimaryKeyDescriptor = typeof AddPrimaryKeySchema.infer;
|
|
161
|
+
export type AddUniqueDescriptor = typeof AddUniqueSchema.infer;
|
|
162
|
+
export type AddForeignKeyDescriptor = typeof AddForeignKeySchema.infer;
|
|
163
|
+
export type DropConstraintDescriptor = typeof DropConstraintSchema.infer;
|
|
164
|
+
export type CreateIndexDescriptor = typeof CreateIndexSchema.infer;
|
|
165
|
+
export type DropIndexDescriptor = typeof DropIndexSchema.infer;
|
|
166
|
+
export type CreateEnumTypeDescriptor = typeof CreateEnumTypeSchema.infer;
|
|
167
|
+
export type AddEnumValuesDescriptor = typeof AddEnumValuesSchema.infer;
|
|
168
|
+
export type DropEnumTypeDescriptor = typeof DropEnumTypeSchema.infer;
|
|
169
|
+
export type RenameTypeDescriptor = typeof RenameTypeSchema.infer;
|
|
170
|
+
export type CreateDependencyDescriptor = typeof CreateDependencySchema.infer;
|
|
171
|
+
export type DataTransformDescriptor = typeof DataTransformSchema.infer;
|
|
172
|
+
export type SqlMigrationOpDescriptor = typeof SqlMigrationOpDescriptorSchema.infer;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL migration operation descriptors — builder functions and re-exports.
|
|
3
|
+
*
|
|
4
|
+
* Types are defined by arktype schemas in descriptor-schemas.ts and derived
|
|
5
|
+
* via `typeof schema.infer`. This file provides the builder functions that
|
|
6
|
+
* construct descriptors, plus re-exports the types and schemas.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
10
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
11
|
+
|
|
12
|
+
// Re-export types and schemas from the schema source of truth
|
|
13
|
+
export type {
|
|
14
|
+
AddColumnDescriptor,
|
|
15
|
+
AddEnumValuesDescriptor,
|
|
16
|
+
AddForeignKeyDescriptor,
|
|
17
|
+
AddPrimaryKeyDescriptor,
|
|
18
|
+
AddUniqueDescriptor,
|
|
19
|
+
AlterColumnTypeDescriptor,
|
|
20
|
+
CreateDependencyDescriptor,
|
|
21
|
+
CreateEnumTypeDescriptor,
|
|
22
|
+
CreateIndexDescriptor,
|
|
23
|
+
CreateTableDescriptor,
|
|
24
|
+
DataTransformDescriptor,
|
|
25
|
+
DropColumnDescriptor,
|
|
26
|
+
DropConstraintDescriptor,
|
|
27
|
+
DropDefaultDescriptor,
|
|
28
|
+
DropEnumTypeDescriptor,
|
|
29
|
+
DropIndexDescriptor,
|
|
30
|
+
DropNotNullDescriptor,
|
|
31
|
+
DropTableDescriptor,
|
|
32
|
+
RenameTypeDescriptor,
|
|
33
|
+
SetDefaultDescriptor,
|
|
34
|
+
SetNotNullDescriptor,
|
|
35
|
+
SqlMigrationOpDescriptor,
|
|
36
|
+
} from './descriptor-schemas';
|
|
37
|
+
|
|
38
|
+
export { MigrationDescriptorArraySchema } from './descriptor-schemas';
|
|
39
|
+
|
|
40
|
+
import type {
|
|
41
|
+
AddColumnDescriptor,
|
|
42
|
+
AddEnumValuesDescriptor,
|
|
43
|
+
AddForeignKeyDescriptor,
|
|
44
|
+
AddPrimaryKeyDescriptor,
|
|
45
|
+
AddUniqueDescriptor,
|
|
46
|
+
AlterColumnTypeDescriptor,
|
|
47
|
+
CreateDependencyDescriptor,
|
|
48
|
+
CreateEnumTypeDescriptor,
|
|
49
|
+
CreateIndexDescriptor,
|
|
50
|
+
CreateTableDescriptor,
|
|
51
|
+
DropColumnDescriptor,
|
|
52
|
+
DropConstraintDescriptor,
|
|
53
|
+
DropDefaultDescriptor,
|
|
54
|
+
DropEnumTypeDescriptor,
|
|
55
|
+
DropIndexDescriptor,
|
|
56
|
+
DropNotNullDescriptor,
|
|
57
|
+
DropTableDescriptor,
|
|
58
|
+
RenameTypeDescriptor,
|
|
59
|
+
SetDefaultDescriptor,
|
|
60
|
+
SetNotNullDescriptor,
|
|
61
|
+
} from './descriptor-schemas';
|
|
62
|
+
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// Data transform support types (not validated by arktype — runtime values)
|
|
65
|
+
// ============================================================================
|
|
66
|
+
|
|
67
|
+
/** Something that can produce a SqlQueryPlan via .build(). */
|
|
68
|
+
export interface Buildable {
|
|
69
|
+
build(): SqlQueryPlan;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Sentinel value for unimplemented data transform queries.
|
|
74
|
+
* The scaffold renders this as a TODO comment. The resolver throws if it encounters one.
|
|
75
|
+
*/
|
|
76
|
+
export const TODO = Symbol.for('prisma-next.migration.todo');
|
|
77
|
+
export type TodoMarker = typeof TODO;
|
|
78
|
+
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// Builder functions
|
|
81
|
+
// ============================================================================
|
|
82
|
+
|
|
83
|
+
export function createTable(table: string): CreateTableDescriptor {
|
|
84
|
+
return { kind: 'createTable', table };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function dropTable(table: string): DropTableDescriptor {
|
|
88
|
+
return { kind: 'dropTable', table };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function addColumn(
|
|
92
|
+
table: string,
|
|
93
|
+
column: string,
|
|
94
|
+
overrides?: { nullable?: boolean },
|
|
95
|
+
): AddColumnDescriptor {
|
|
96
|
+
return { kind: 'addColumn', table, column, ...ifDefined('overrides', overrides) };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function dropColumn(table: string, column: string): DropColumnDescriptor {
|
|
100
|
+
return { kind: 'dropColumn', table, column };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function alterColumnType(
|
|
104
|
+
table: string,
|
|
105
|
+
column: string,
|
|
106
|
+
opts?: string | { using?: string; toType?: string },
|
|
107
|
+
): AlterColumnTypeDescriptor {
|
|
108
|
+
const using = typeof opts === 'string' ? opts : opts?.using;
|
|
109
|
+
const toType = typeof opts === 'string' ? undefined : opts?.toType;
|
|
110
|
+
return {
|
|
111
|
+
kind: 'alterColumnType',
|
|
112
|
+
table,
|
|
113
|
+
column,
|
|
114
|
+
...ifDefined('using', using),
|
|
115
|
+
...ifDefined('toType', toType),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function setNotNull(table: string, column: string): SetNotNullDescriptor {
|
|
120
|
+
return { kind: 'setNotNull', table, column };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function dropNotNull(table: string, column: string): DropNotNullDescriptor {
|
|
124
|
+
return { kind: 'dropNotNull', table, column };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function setDefault(table: string, column: string): SetDefaultDescriptor {
|
|
128
|
+
return { kind: 'setDefault', table, column };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function dropDefault(table: string, column: string): DropDefaultDescriptor {
|
|
132
|
+
return { kind: 'dropDefault', table, column };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function addPrimaryKey(table: string): AddPrimaryKeyDescriptor {
|
|
136
|
+
return { kind: 'addPrimaryKey', table };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function addUnique(table: string, columns: readonly string[]): AddUniqueDescriptor {
|
|
140
|
+
return { kind: 'addUnique', table, columns: [...columns] };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function addForeignKey(table: string, columns: readonly string[]): AddForeignKeyDescriptor {
|
|
144
|
+
return { kind: 'addForeignKey', table, columns: [...columns] };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function dropConstraint(table: string, constraintName: string): DropConstraintDescriptor {
|
|
148
|
+
return { kind: 'dropConstraint', table, constraintName };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function createIndex(table: string, columns: readonly string[]): CreateIndexDescriptor {
|
|
152
|
+
return { kind: 'createIndex', table, columns: [...columns] };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function dropIndex(table: string, indexName: string): DropIndexDescriptor {
|
|
156
|
+
return { kind: 'dropIndex', table, indexName };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function createEnumType(
|
|
160
|
+
typeName: string,
|
|
161
|
+
values?: readonly string[],
|
|
162
|
+
): CreateEnumTypeDescriptor {
|
|
163
|
+
return {
|
|
164
|
+
kind: 'createEnumType',
|
|
165
|
+
typeName,
|
|
166
|
+
...ifDefined('values', values ? [...values] : undefined),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function addEnumValues(
|
|
171
|
+
typeName: string,
|
|
172
|
+
values: readonly string[],
|
|
173
|
+
): AddEnumValuesDescriptor {
|
|
174
|
+
return { kind: 'addEnumValues', typeName, values: [...values] };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function dropEnumType(typeName: string): DropEnumTypeDescriptor {
|
|
178
|
+
return { kind: 'dropEnumType', typeName };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function renameType(fromName: string, toName: string): RenameTypeDescriptor {
|
|
182
|
+
return { kind: 'renameType', fromName, toName };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function createDependency(dependencyId: string): CreateDependencyDescriptor {
|
|
186
|
+
return { kind: 'createDependency', dependencyId };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* All structural builder functions keyed by descriptor kind.
|
|
191
|
+
*/
|
|
192
|
+
export const builders = {
|
|
193
|
+
createTable,
|
|
194
|
+
dropTable,
|
|
195
|
+
addColumn,
|
|
196
|
+
dropColumn,
|
|
197
|
+
alterColumnType,
|
|
198
|
+
setNotNull,
|
|
199
|
+
dropNotNull,
|
|
200
|
+
setDefault,
|
|
201
|
+
dropDefault,
|
|
202
|
+
addPrimaryKey,
|
|
203
|
+
addUnique,
|
|
204
|
+
addForeignKey,
|
|
205
|
+
dropConstraint,
|
|
206
|
+
createIndex,
|
|
207
|
+
dropIndex,
|
|
208
|
+
createEnumType,
|
|
209
|
+
addEnumValues,
|
|
210
|
+
dropEnumType,
|
|
211
|
+
renameType,
|
|
212
|
+
createDependency,
|
|
213
|
+
} as const;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MigrationOperationPolicy } from '@prisma-next/
|
|
1
|
+
import type { MigrationOperationPolicy } from '@prisma-next/framework-components/control';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Policy used by `db init`: additive-only operations, no widening/destructive steps.
|