@remix-run/data-table 0.2.0 → 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.
Files changed (66) hide show
  1. package/README.md +77 -75
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/lib/adapter.d.ts +10 -271
  5. package/dist/lib/adapter.d.ts.map +1 -1
  6. package/dist/lib/column.d.ts.map +1 -1
  7. package/dist/lib/column.js +10 -1
  8. package/dist/lib/migrations/directive.d.ts +12 -0
  9. package/dist/lib/migrations/directive.d.ts.map +1 -0
  10. package/dist/lib/migrations/directive.js +28 -0
  11. package/dist/lib/migrations/directory-name.d.ts +12 -0
  12. package/dist/lib/migrations/directory-name.d.ts.map +1 -0
  13. package/dist/lib/migrations/directory-name.js +18 -0
  14. package/dist/lib/migrations/journal-store.d.ts +1 -1
  15. package/dist/lib/migrations/journal-store.d.ts.map +1 -1
  16. package/dist/lib/migrations/journal-store.js +18 -18
  17. package/dist/lib/migrations/registry.d.ts +1 -1
  18. package/dist/lib/migrations/registry.js +1 -1
  19. package/dist/lib/migrations/runner.d.ts +2 -2
  20. package/dist/lib/migrations/runner.d.ts.map +1 -1
  21. package/dist/lib/migrations/runner.js +44 -71
  22. package/dist/lib/migrations-node.d.ts +7 -4
  23. package/dist/lib/migrations-node.d.ts.map +1 -1
  24. package/dist/lib/migrations-node.js +52 -41
  25. package/dist/lib/migrations.d.ts +19 -200
  26. package/dist/lib/migrations.d.ts.map +1 -1
  27. package/dist/lib/migrations.js +1 -38
  28. package/dist/lib/query.d.ts +33 -0
  29. package/dist/lib/query.d.ts.map +1 -1
  30. package/dist/lib/query.js +28 -0
  31. package/dist/lib/sql-helpers.d.ts +1 -7
  32. package/dist/lib/sql-helpers.d.ts.map +1 -1
  33. package/dist/lib/sql-helpers.js +0 -16
  34. package/dist/migrations.d.ts +2 -5
  35. package/dist/migrations.d.ts.map +1 -1
  36. package/dist/migrations.js +1 -3
  37. package/dist/sql-helpers.d.ts +1 -1
  38. package/dist/sql-helpers.d.ts.map +1 -1
  39. package/dist/sql-helpers.js +1 -1
  40. package/package.json +7 -8
  41. package/src/index.ts +1 -34
  42. package/src/lib/adapter.ts +10 -330
  43. package/src/lib/column.ts +14 -2
  44. package/src/lib/migrations/directive.ts +38 -0
  45. package/src/lib/migrations/directory-name.ts +23 -0
  46. package/src/lib/migrations/journal-store.ts +22 -18
  47. package/src/lib/migrations/registry.ts +1 -1
  48. package/src/lib/migrations/runner.ts +51 -85
  49. package/src/lib/migrations-node.ts +58 -38
  50. package/src/lib/migrations.ts +19 -224
  51. package/src/lib/query.ts +33 -0
  52. package/src/lib/sql-helpers.ts +1 -22
  53. package/src/migrations.ts +3 -13
  54. package/src/sql-helpers.ts +0 -1
  55. package/dist/lib/migrations/filename.d.ts +0 -12
  56. package/dist/lib/migrations/filename.d.ts.map +0 -1
  57. package/dist/lib/migrations/filename.js +0 -20
  58. package/dist/lib/migrations/helpers.d.ts +0 -11
  59. package/dist/lib/migrations/helpers.d.ts.map +0 -1
  60. package/dist/lib/migrations/helpers.js +0 -77
  61. package/dist/lib/migrations/schema-api.d.ts +0 -7
  62. package/dist/lib/migrations/schema-api.d.ts.map +0 -1
  63. package/dist/lib/migrations/schema-api.js +0 -326
  64. package/src/lib/migrations/filename.ts +0 -25
  65. package/src/lib/migrations/helpers.ts +0 -108
  66. package/src/lib/migrations/schema-api.ts +0 -417
@@ -1,11 +1,7 @@
1
- import { createDatabase, createDatabaseWithTransaction } from '../database.ts'
2
- import type { Database } from '../database.ts'
3
1
  import type { DatabaseAdapter, TransactionToken } from '../adapter.ts'
4
- import type { SqlStatement } from '../sql.ts'
5
2
  import type {
6
3
  MigrateOptions,
7
4
  MigrateResult,
8
- MigrationContext,
9
5
  MigrationDescriptor,
10
6
  MigrationDirection,
11
7
  MigrationJournalRow,
@@ -14,8 +10,10 @@ import type {
14
10
  MigrationRunnerOptions,
15
11
  MigrationStatus,
16
12
  MigrationStatusEntry,
13
+ MigrationTransactionMode,
17
14
  } from '../migrations.ts'
18
15
 
16
+ import { parseTransactionDirective } from './directive.ts'
19
17
  import {
20
18
  deleteJournalRow,
21
19
  ensureMigrationJournal,
@@ -23,10 +21,9 @@ import {
23
21
  hasMigrationJournal,
24
22
  insertJournalRow,
25
23
  loadJournalRows,
26
- normalizeChecksum,
24
+ computeChecksum,
27
25
  } from './journal-store.ts'
28
26
  import { resolveMigrations } from './registry.ts'
29
- import { createMigrationSchema } from './schema-api.ts'
30
27
 
31
28
  type RunMigrationsInput = {
32
29
  adapter: DatabaseAdapter
@@ -64,10 +61,10 @@ function assertTargetOption(migrations: MigrationDescriptor[], to: string | unde
64
61
  }
65
62
  }
66
63
 
67
- function assertNoMigrationDrift(
64
+ async function assertNoMigrationDrift(
68
65
  migrations: MigrationDescriptor[],
69
66
  journal: MigrationJournalRow[],
70
- ): void {
67
+ ): Promise<void> {
71
68
  let migrationMap = new Map(migrations.map((migration) => [migration.id, migration]))
72
69
 
73
70
  for (let row of journal) {
@@ -77,7 +74,7 @@ function assertNoMigrationDrift(
77
74
  continue
78
75
  }
79
76
 
80
- let expected = normalizeChecksum(migration)
77
+ let expected = await computeChecksum(migration)
81
78
 
82
79
  if (expected !== row.checksum) {
83
80
  throw new Error(
@@ -93,34 +90,18 @@ function assertNoMigrationDrift(
93
90
  }
94
91
  }
95
92
 
96
- function createDryRunDatabase(adapter: DatabaseAdapter): Database {
97
- let error = new Error('Cannot execute data operations while running migrations with dryRun')
98
- let throwDryRunError = async (): Promise<never> => {
99
- throw error
93
+ function resolveTransactionMode(migration: MigrationDescriptor): MigrationTransactionMode {
94
+ if (migration.transaction) {
95
+ return migration.transaction
100
96
  }
101
- let dryRunAdapter: DatabaseAdapter = {
102
- dialect: adapter.dialect,
103
- capabilities: adapter.capabilities,
104
- compileSql(operation) {
105
- return adapter.compileSql(operation)
106
- },
107
- async hasTable(table) {
108
- return adapter.hasTable(table)
109
- },
110
- async hasColumn(table, column) {
111
- return adapter.hasColumn(table, column)
112
- },
113
- execute: throwDryRunError,
114
- migrate: throwDryRunError,
115
- beginTransaction: throwDryRunError,
116
- commitTransaction: throwDryRunError,
117
- rollbackTransaction: throwDryRunError,
118
- createSavepoint: throwDryRunError,
119
- rollbackToSavepoint: throwDryRunError,
120
- releaseSavepoint: throwDryRunError,
97
+
98
+ let directive = parseTransactionDirective(migration.up)
99
+
100
+ if (directive) {
101
+ return directive
121
102
  }
122
103
 
123
- return createDatabase(dryRunAdapter)
104
+ return 'auto'
124
105
  }
125
106
 
126
107
  async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult> {
@@ -135,7 +116,7 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
135
116
  assertStepOption(step)
136
117
  assertTargetOption(migrations, target)
137
118
 
138
- let sql: SqlStatement[] = []
119
+ let sql: string[] = []
139
120
 
140
121
  await adapter.acquireMigrationLock?.()
141
122
 
@@ -154,7 +135,7 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
154
135
  }
155
136
 
156
137
  let appliedMap = new Map(journal.map((row) => [row.id, row]))
157
- assertNoMigrationDrift(migrations, journal)
138
+ await assertNoMigrationDrift(migrations, journal)
158
139
  let toRun: MigrationDescriptor[] = []
159
140
 
160
141
  if (input.direction === 'up') {
@@ -172,19 +153,21 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
172
153
  toRun = toRun.slice(0, step)
173
154
  }
174
155
  } else {
175
- let appliedMigrations = migrations
176
- .filter((migration) => appliedMap.has(migration.id))
177
- .reverse()
156
+ toRun = migrations.filter((migration) => appliedMap.has(migration.id)).reverse()
178
157
 
179
158
  if (target) {
180
- appliedMigrations = appliedMigrations.filter((migration) => migration.id >= target)
159
+ toRun = toRun.filter((migration) => migration.id >= target)
181
160
  }
182
161
 
183
162
  if (step !== undefined) {
184
- appliedMigrations = appliedMigrations.slice(0, step)
163
+ toRun = toRun.slice(0, step)
185
164
  }
186
165
 
187
- toRun = appliedMigrations
166
+ for (let migration of toRun) {
167
+ if (migration.down === undefined) {
168
+ throw new Error('Migration "' + migration.id + '" has no down script')
169
+ }
170
+ }
188
171
  }
189
172
 
190
173
  let applied: MigrationStatusEntry[] = []
@@ -192,10 +175,10 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
192
175
  let batch = getBatch(journal)
193
176
 
194
177
  for (let migration of toRun) {
195
- if (
196
- migration.migration.transaction === 'required' &&
197
- !adapter.capabilities.transactionalDdl
198
- ) {
178
+ let script = (input.direction === 'up' ? migration.up : migration.down) as string
179
+ let mode = resolveTransactionMode(migration)
180
+
181
+ if (mode === 'required' && !adapter.capabilities.transactionalDdl) {
199
182
  throw new Error(
200
183
  'Migration "' +
201
184
  migration.id +
@@ -203,43 +186,23 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
203
186
  )
204
187
  }
205
188
 
206
- let shouldUseTransaction =
207
- !dryRun &&
208
- migration.migration.transaction !== 'none' &&
209
- adapter.capabilities.transactionalDdl
189
+ let shouldUseTransaction = !dryRun && mode !== 'none' && adapter.capabilities.transactionalDdl
210
190
  let token: TransactionToken | undefined
211
191
 
212
192
  if (shouldUseTransaction) {
213
193
  token = await adapter.beginTransaction()
214
194
  }
215
195
 
216
- let db = dryRun
217
- ? createDryRunDatabase(adapter)
218
- : token
219
- ? createDatabaseWithTransaction(adapter, token)
220
- : createDatabase(adapter)
221
-
222
- let schema = createMigrationSchema(
223
- db,
224
- async (operation) => {
225
- let compiled = adapter.compileSql(operation)
226
- sql.push(...compiled)
196
+ sql.push(script)
227
197
 
228
- if (!dryRun) {
229
- await adapter.migrate({ operation, transaction: token })
198
+ try {
199
+ if (!dryRun) {
200
+ if (script.trim().length > 0) {
201
+ await adapter.executeScript(script, token)
230
202
  }
231
- },
232
- { transaction: token },
233
- )
234
- let context: MigrationContext = {
235
- db,
236
- schema,
237
- }
203
+ }
238
204
 
239
- try {
240
205
  if (input.direction === 'up') {
241
- await migration.migration.up(context)
242
-
243
206
  if (!dryRun) {
244
207
  await insertJournalRow(
245
208
  adapter,
@@ -247,7 +210,7 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
247
210
  {
248
211
  id: migration.id,
249
212
  name: migration.name,
250
- checksum: normalizeChecksum(migration),
213
+ checksum: await computeChecksum(migration),
251
214
  batch,
252
215
  },
253
216
  token,
@@ -260,8 +223,6 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
260
223
  status: 'applied',
261
224
  })
262
225
  } else {
263
- await migration.migration.down(context)
264
-
265
226
  if (!dryRun) {
266
227
  await deleteJournalRow(adapter, journalTable, migration.id, token)
267
228
  }
@@ -296,8 +257,8 @@ async function runMigrations(input: RunMigrationsInput): Promise<MigrateResult>
296
257
  }
297
258
 
298
259
  /**
299
- * Creates a migration runner for applying/reverting migrations against an adapter.
300
- * @param adapter Database adapter used to compile and execute migration operations.
260
+ * Creates a migration runner for applying/reverting SQL migrations against an adapter.
261
+ * @param adapter Database adapter used to execute migration scripts.
301
262
  * @param migrations Migration descriptors or registry.
302
263
  * @param options Optional runner configuration.
303
264
  * @returns A migration runner instance.
@@ -344,20 +305,23 @@ export function createMigrationRunner(
344
305
  let journalMap = new Map(journal.map((row) => [row.id, row]))
345
306
  let sortedMigrations = resolveMigrations(migrations)
346
307
 
347
- return sortedMigrations.map((migration) => {
308
+ let statuses: MigrationStatusEntry[] = []
309
+
310
+ for (let migration of sortedMigrations) {
348
311
  let journalRow = journalMap.get(migration.id)
349
312
 
350
313
  if (!journalRow) {
351
- return {
314
+ statuses.push({
352
315
  id: migration.id,
353
316
  name: migration.name,
354
317
  status: 'pending' as MigrationStatus,
355
- }
318
+ })
319
+ continue
356
320
  }
357
321
 
358
- let checksum = normalizeChecksum(migration)
322
+ let checksum = await computeChecksum(migration)
359
323
 
360
- return {
324
+ statuses.push({
361
325
  id: migration.id,
362
326
  name: migration.name,
363
327
  status:
@@ -367,8 +331,10 @@ export function createMigrationRunner(
367
331
  appliedAt: journalRow.appliedAt,
368
332
  batch: journalRow.batch,
369
333
  checksum: journalRow.checksum,
370
- }
371
- })
334
+ })
335
+ }
336
+
337
+ return statuses
372
338
  },
373
339
  }
374
340
  }
@@ -1,16 +1,18 @@
1
- import { createHash } from 'node:crypto'
2
1
  import { promises as fs } from 'node:fs'
3
2
  import path from 'node:path'
4
- import { pathToFileURL } from 'node:url'
5
- import type { Migration, MigrationDescriptor } from './migrations.ts'
6
- import { parseMigrationFilename } from './migrations/filename.ts'
3
+
4
+ import type { MigrationDescriptor } from './migrations.ts'
5
+ import { parseMigrationDirectoryName } from './migrations/directory-name.ts'
7
6
 
8
7
  /**
9
- * Loads migration modules from a directory on Node.js.
8
+ * Loads SQL-file migrations from a directory on Node.js.
9
+ *
10
+ * Each migration is a directory named `YYYYMMDDHHmmss_<slug>` containing:
11
+ * - `up.sql` (required)
12
+ * - `down.sql` (optional; omit for irreversible migrations)
10
13
  *
11
- * Filenames are used to infer migration `id` and `name`.
12
- * Each file must default-export `createMigration(...)`.
13
- * @param directory Absolute or relative directory containing migration files.
14
+ * `id` and `name` are inferred from the directory name.
15
+ * @param directory Absolute or relative directory containing migration directories.
14
16
  * @returns A sorted list of loaded migration descriptors.
15
17
  * @example
16
18
  * ```ts
@@ -20,52 +22,70 @@ import { parseMigrationFilename } from './migrations/filename.ts'
20
22
  * ```
21
23
  */
22
24
  export async function loadMigrations(directory: string): Promise<MigrationDescriptor[]> {
23
- let allFiles = (await fs.readdir(directory, { withFileTypes: true }))
24
- .filter((entry) => entry.isFile())
25
+ let entries = await fs.readdir(directory, { withFileTypes: true })
26
+ let directories = entries
27
+ .filter((entry) => entry.isDirectory())
25
28
  .map((entry) => entry.name)
26
29
  .sort((left, right) => left.localeCompare(right))
27
- let files: Array<{ file: string; id: string; name: string }> = []
28
-
29
- for (let file of allFiles) {
30
- if (!/\.(?:m?ts|m?js|cts|cjs)$/.test(file)) {
31
- continue
32
- }
33
-
34
- let parsed = parseMigrationFilename(file)
35
- files.push({ file, id: parsed.id, name: parsed.name })
36
- }
37
30
 
38
31
  let migrations: MigrationDescriptor[] = []
39
32
  let seenIds = new Set<string>()
40
33
 
41
- for (let entry of files) {
42
- if (seenIds.has(entry.id)) {
34
+ for (let directoryName of directories) {
35
+ let parsed = parseMigrationDirectoryName(directoryName)
36
+
37
+ if (seenIds.has(parsed.id)) {
43
38
  throw new Error(
44
- 'Duplicate migration id "' + entry.id + '" inferred from filename "' + entry.file + '"',
39
+ 'Duplicate migration id "' +
40
+ parsed.id +
41
+ '" inferred from directory "' +
42
+ directoryName +
43
+ '"',
45
44
  )
46
45
  }
47
46
 
48
- seenIds.add(entry.id)
49
- let fullPath = path.join(directory, entry.file)
50
- let source = await fs.readFile(fullPath, 'utf8')
51
- let checksum = createHash('sha256').update(source).digest('hex')
52
- let module = (await import(pathToFileURL(fullPath).href)) as { default?: Migration }
53
- let migration = module.default
47
+ seenIds.add(parsed.id)
54
48
 
55
- if (!migration || typeof migration.up !== 'function' || typeof migration.down !== 'function') {
56
- throw new Error(
57
- 'Migration file "' + entry.file + '" must default-export createMigration(...)',
58
- )
49
+ let directoryPath = path.join(directory, directoryName)
50
+ let upPath = path.join(directoryPath, 'up.sql')
51
+ let downPath = path.join(directoryPath, 'down.sql')
52
+
53
+ let up: string
54
+ try {
55
+ up = await fs.readFile(upPath, 'utf8')
56
+ } catch (error) {
57
+ if (isNodeFileNotFoundError(error)) {
58
+ throw new Error('Migration directory "' + directoryName + '" is missing up.sql')
59
+ }
60
+ throw error
61
+ }
62
+
63
+ let down: string | undefined
64
+ try {
65
+ down = await fs.readFile(downPath, 'utf8')
66
+ } catch (error) {
67
+ if (!isNodeFileNotFoundError(error)) {
68
+ throw error
69
+ }
59
70
  }
60
71
 
61
72
  migrations.push({
62
- id: entry.id,
63
- name: entry.name,
64
- path: fullPath,
65
- checksum,
66
- migration,
73
+ id: parsed.id,
74
+ name: parsed.name,
75
+ up,
76
+ down,
77
+ path: directoryPath,
67
78
  })
68
79
  }
69
80
 
70
81
  return migrations
71
82
  }
83
+
84
+ function isNodeFileNotFoundError(error: unknown): boolean {
85
+ return (
86
+ typeof error === 'object' &&
87
+ error !== null &&
88
+ 'code' in error &&
89
+ (error as { code?: unknown }).code === 'ENOENT'
90
+ )
91
+ }
@@ -1,94 +1,31 @@
1
- import type { Database } from './database.ts'
2
- import type { ColumnDefinition, ForeignKeyAction, IndexDefinition } from './adapter.ts'
3
- import type { ColumnBuilder } from './column.ts'
4
- import type { SqlStatement } from './sql.ts'
5
- import type { AnyTable } from './table.ts'
6
-
7
1
  /**
8
2
  * Controls how each migration is wrapped in transactions.
9
- */
10
- export type MigrationTransactionMode = 'auto' | 'required' | 'none'
11
-
12
- /**
13
- * Runtime context passed to migration `up`/`down` handlers.
14
- */
15
- export type MigrationContext = {
16
- /**
17
- * Immediate data runtime (`query/create/update/exec/transaction`).
18
- */
19
- db: Database
20
- /**
21
- * Migration schema runtime (`createTable/alterTable/createIndex/...`).
22
- */
23
- schema: MigrationSchema
24
- }
25
-
26
- /**
27
- * Authoring shape for `createMigration(...)`.
28
- */
29
- export type CreateMigrationInput = {
30
- up: (context: MigrationContext) => Promise<void> | void
31
- down: (context: MigrationContext) => Promise<void> | void
32
- transaction?: MigrationTransactionMode
33
- }
34
-
35
- /**
36
- * Normalized migration object consumed by the registry/runner.
37
- */
38
- export type Migration = {
39
- up: CreateMigrationInput['up']
40
- down: CreateMigrationInput['down']
41
- transaction: MigrationTransactionMode
42
- }
43
-
44
- /**
45
- * Creates a migration descriptor with normalized defaults.
46
- * @param input Migration handlers and transaction mode.
47
- * @returns A normalized migration object.
48
- * @example
49
- * ```ts
50
- * import { createMigration, column as c } from 'remix/data-table/migrations'
51
- * import { table } from 'remix/data-table'
52
- *
53
- * let users = table({
54
- * name: 'users',
55
- * columns: {
56
- * id: c.integer().primaryKey().autoIncrement(),
57
- * email: c.varchar(255).notNull().unique(),
58
- * },
59
- * })
60
3
  *
61
- * export default createMigration({
62
- * async up({ db, schema }) {
63
- * await schema.createTable(users)
64
- *
65
- * if (db.adapter.dialect === 'sqlite') {
66
- * await db.exec('pragma foreign_keys = on')
67
- * }
68
- * },
69
- * async down({ schema }) {
70
- * await schema.dropTable('users', { ifExists: true })
71
- * },
72
- * })
73
- * ```
4
+ * - `auto` (default): wrap when the adapter supports transactional DDL.
5
+ * - `required`: wrap; throws when the adapter does not support transactional DDL.
6
+ * - `none`: never wrap.
74
7
  */
75
- export function createMigration(input: CreateMigrationInput): Migration {
76
- return {
77
- up: input.up,
78
- down: input.down,
79
- transaction: input.transaction ?? 'auto',
80
- }
81
- }
8
+ export type MigrationTransactionMode = 'auto' | 'required' | 'none'
82
9
 
83
10
  /**
84
- * Migration metadata stored in registries and returned by loaders.
11
+ * Migration metadata + SQL consumed by the registry/runner.
85
12
  */
86
13
  export type MigrationDescriptor = {
14
+ /** Migration id (typically a `YYYYMMDDHHmmss` timestamp). */
87
15
  id: string
16
+ /** Human-readable migration slug. */
88
17
  name: string
18
+ /** SQL executed for `runner.up(...)`. May contain multiple statements. */
19
+ up: string
20
+ /**
21
+ * SQL executed for `runner.down(...)`. May contain multiple statements.
22
+ * Omit (or pass `undefined`) for irreversible migrations.
23
+ */
24
+ down?: string
25
+ /** Transaction wrapping mode. Defaults to `auto`. */
26
+ transaction?: MigrationTransactionMode
27
+ /** Optional source path used in error messages. */
89
28
  path?: string
90
- checksum?: string
91
- migration: Migration
92
29
  }
93
30
 
94
31
  /**
@@ -152,151 +89,9 @@ export type MigrateResult = {
152
89
  applied: MigrationStatusEntry[]
153
90
  reverted: MigrationStatusEntry[]
154
91
  /**
155
- * Compiled SQL statements for operations processed during this run.
156
- * Includes planned SQL when running with `dryRun: true`.
157
- */
158
- sql: SqlStatement[]
159
- }
160
-
161
- /**
162
- * Options for `schema.createTable(...)` migration operations.
163
- */
164
- export type CreateTableOptions = { ifNotExists?: boolean }
165
- /**
166
- * Options for `schema.alterTable(...)` migration operations.
167
- */
168
- export type AlterTableOptions = { ifExists?: boolean }
169
- /**
170
- * Options for `schema.dropTable(...)` migration operations.
171
- */
172
- export type DropTableOptions = { ifExists?: boolean; cascade?: boolean }
173
- /**
174
- * Accepts either one index column or multiple (compound index).
175
- */
176
- export type IndexColumns = string | string[]
177
-
178
- /**
179
- * Accepts either one key column or multiple (compound key).
180
- */
181
- export type KeyColumns = string | string[]
182
-
183
- /**
184
- * Accepts either a SQL table name or a `table(...)` object.
185
- */
186
- export type TableInput = string | AnyTable
187
-
188
- /**
189
- * Optional name override for constraints and indexes.
190
- */
191
- export type NamedConstraintOptions = {
192
- name?: string
193
- }
194
-
195
- /**
196
- * Foreign key options for migration APIs.
197
- */
198
- export type ForeignKeyOptions = NamedConstraintOptions & {
199
- onDelete?: ForeignKeyAction
200
- onUpdate?: ForeignKeyAction
201
- }
202
-
203
- /**
204
- * Index options for migration APIs.
205
- */
206
- export type CreateIndexOptions = NamedConstraintOptions &
207
- Omit<IndexDefinition, 'table' | 'name' | 'columns'> & {
208
- ifNotExists?: boolean
209
- }
210
-
211
- /**
212
- * Builder API available inside `schema.alterTable(name, table => ...)`.
213
- */
214
- export interface AlterTableBuilder {
215
- /** Adds a column during an `alterTable` migration. */
216
- addColumn(name: string, definition: ColumnDefinition | ColumnBuilder): void
217
- /** Changes an existing column during an `alterTable` migration. */
218
- changeColumn(name: string, definition: ColumnDefinition | ColumnBuilder): void
219
- /** Renames a column during an `alterTable` migration. */
220
- renameColumn(from: string, to: string): void
221
- /** Drops a column during an `alterTable` migration. */
222
- dropColumn(name: string, options?: { ifExists?: boolean }): void
223
- /** Adds a primary key during an `alterTable` migration. */
224
- addPrimaryKey(columns: KeyColumns, options?: NamedConstraintOptions): void
225
- /** Drops a primary key during an `alterTable` migration. */
226
- dropPrimaryKey(name: string): void
227
- /** Adds a unique constraint during an `alterTable` migration. */
228
- addUnique(columns: KeyColumns, options?: NamedConstraintOptions): void
229
- /** Drops a unique constraint during an `alterTable` migration. */
230
- dropUnique(name: string): void
231
- /** Adds a foreign key during an `alterTable` migration. */
232
- addForeignKey(
233
- columns: KeyColumns,
234
- refTable: TableInput,
235
- refColumns?: KeyColumns,
236
- options?: ForeignKeyOptions,
237
- ): void
238
- /** Drops a foreign key during an `alterTable` migration. */
239
- dropForeignKey(name: string): void
240
- /** Adds a check constraint during an `alterTable` migration. */
241
- addCheck(expression: string, options?: NamedConstraintOptions): void
242
- /** Drops a check constraint during an `alterTable` migration. */
243
- dropCheck(name: string): void
244
- /** Adds an index during an `alterTable` migration. */
245
- addIndex(columns: IndexColumns, options?: CreateIndexOptions): void
246
- /** Drops an index during an `alterTable` migration. */
247
- dropIndex(name: string): void
248
- /** Sets the table comment during an `alterTable` migration. */
249
- comment(text: string): void
250
- }
251
-
252
- /**
253
- * DDL-focused operations mixed into the migration `db` object.
254
- */
255
- export interface MigrationSchema {
256
- /** Creates a table in the migration schema. */
257
- createTable<table extends AnyTable>(table: table, options?: CreateTableOptions): Promise<void>
258
- /** Alters an existing table in the migration schema. */
259
- alterTable(
260
- table: TableInput,
261
- migrate: (table: AlterTableBuilder) => void,
262
- options?: AlterTableOptions,
263
- ): Promise<void>
264
- /** Renames a table in the migration schema. */
265
- renameTable(from: TableInput, to: string): Promise<void>
266
- /** Drops a table from the migration schema. */
267
- dropTable(table: TableInput, options?: DropTableOptions): Promise<void>
268
- /** Creates an index in the migration schema. */
269
- createIndex(table: TableInput, columns: IndexColumns, options?: CreateIndexOptions): Promise<void>
270
- /** Drops an index from the migration schema. */
271
- dropIndex(table: TableInput, name: string, options?: { ifExists?: boolean }): Promise<void>
272
- /** Renames an index in the migration schema. */
273
- renameIndex(table: TableInput, from: string, to: string): Promise<void>
274
- /** Adds a foreign key in the migration schema. */
275
- addForeignKey(
276
- table: TableInput,
277
- columns: KeyColumns,
278
- refTable: TableInput,
279
- refColumns?: KeyColumns,
280
- options?: ForeignKeyOptions,
281
- ): Promise<void>
282
- /** Drops a foreign key in the migration schema. */
283
- dropForeignKey(table: TableInput, name: string): Promise<void>
284
- /** Adds a check constraint in the migration schema. */
285
- addCheck(table: TableInput, expression: string, options?: NamedConstraintOptions): Promise<void>
286
- /** Drops a check constraint in the migration schema. */
287
- dropCheck(table: TableInput, name: string): Promise<void>
288
- /**
289
- * Adds raw SQL to the migration plan as a migration operation.
290
- */
291
- plan(sql: string | SqlStatement): Promise<void>
292
- /**
293
- * Returns `true` when the table exists in the current database.
294
- */
295
- hasTable(table: TableInput): Promise<boolean>
296
- /**
297
- * Returns `true` when the column exists on the given table.
92
+ * SQL scripts that were (or, for `dryRun`, would have been) executed.
298
93
  */
299
- hasColumn(table: TableInput, column: string): Promise<boolean>
94
+ sql: string[]
300
95
  }
301
96
 
302
97
  /**