@syncular/migrations 0.0.6-96 → 0.1.2
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 +51 -8
- package/dist/checksum.d.ts +7 -0
- package/dist/checksum.d.ts.map +1 -0
- package/dist/checksum.js +29 -0
- package/dist/checksum.js.map +1 -0
- package/dist/define.d.ts +22 -14
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +39 -145
- package/dist/define.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/naming.d.ts +38 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +60 -0
- package/dist/naming.js.map +1 -0
- package/dist/runner.d.ts +8 -2
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +50 -17
- package/dist/runner.js.map +1 -1
- package/dist/tracking.d.ts.map +1 -1
- package/dist/tracking.js +11 -3
- package/dist/tracking.js.map +1 -1
- package/dist/types.d.ts +15 -8
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -4
- package/src/checksum.ts +54 -0
- package/src/define.ts +50 -171
- package/src/index.ts +3 -1
- package/src/naming.ts +106 -0
- package/src/runner.ts +94 -19
- package/src/tracking.ts +11 -3
- package/src/types.ts +18 -9
package/dist/runner.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @syncular/migrations - Migration runner
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { DISABLED_MIGRATION_CHECKSUM, DISABLED_MIGRATION_CHECKSUM_ALGORITHM, getMigrationChecksumAlgorithm, getStoredDeterministicChecksum, } from './checksum.js';
|
|
5
|
+
import { DEFAULT_MIGRATION_TRACKING_TABLE } from './naming.js';
|
|
5
6
|
import { clearAppliedMigrations, ensureTrackingTable, getAppliedMigrations, recordAppliedMigration, removeAppliedMigration, } from './tracking.js';
|
|
6
|
-
const DEFAULT_TRACKING_TABLE = 'sync_migration_state';
|
|
7
7
|
const migrationRunQueues = new Map();
|
|
8
8
|
function toErrorMessage(error) {
|
|
9
9
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -13,6 +13,24 @@ function isAlreadyExistsSchemaError(error) {
|
|
|
13
13
|
return (message.includes('already exists') ||
|
|
14
14
|
(message.includes('relation') && message.includes('exists')));
|
|
15
15
|
}
|
|
16
|
+
function isDeterministicMigration(migration) {
|
|
17
|
+
return migration.checksum === 'deterministic';
|
|
18
|
+
}
|
|
19
|
+
function getDeterministicMigrations(migrations) {
|
|
20
|
+
return migrations.migrations.filter(isDeterministicMigration);
|
|
21
|
+
}
|
|
22
|
+
async function getStoredChecksumForMigration(options, migration) {
|
|
23
|
+
return getStoredDeterministicChecksum(migration, options.checksums);
|
|
24
|
+
}
|
|
25
|
+
async function getChecksumForAlgorithm(options, migration, algorithm) {
|
|
26
|
+
if (algorithm === DISABLED_MIGRATION_CHECKSUM_ALGORITHM) {
|
|
27
|
+
return DISABLED_MIGRATION_CHECKSUM;
|
|
28
|
+
}
|
|
29
|
+
if (algorithm === 'sql_trace_v1') {
|
|
30
|
+
return await getStoredChecksumForMigration(options, migration);
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`Unsupported migration checksum algorithm: ${algorithm}`);
|
|
33
|
+
}
|
|
16
34
|
async function runWithMigrationQueue(queueKey, task) {
|
|
17
35
|
const previous = migrationRunQueues.get(queueKey) ?? Promise.resolve();
|
|
18
36
|
let release;
|
|
@@ -40,8 +58,14 @@ async function runWithMigrationQueue(queueKey, task) {
|
|
|
40
58
|
* import { defineMigrations, runMigrations } from '@syncular/migrations';
|
|
41
59
|
*
|
|
42
60
|
* const migrations = defineMigrations({
|
|
43
|
-
* v1:
|
|
44
|
-
*
|
|
61
|
+
* v1: {
|
|
62
|
+
* up: async (db) => { ... },
|
|
63
|
+
* down: async (db) => { ... },
|
|
64
|
+
* },
|
|
65
|
+
* v2: {
|
|
66
|
+
* up: async (db) => { ... },
|
|
67
|
+
* down: async (db) => { ... },
|
|
68
|
+
* },
|
|
45
69
|
* });
|
|
46
70
|
*
|
|
47
71
|
* const result = await runMigrations({
|
|
@@ -70,7 +94,7 @@ export async function runMigrations(options) {
|
|
|
70
94
|
*/
|
|
71
95
|
export async function runMigrationsToVersion(options) {
|
|
72
96
|
const { db, migrations, targetVersion } = options;
|
|
73
|
-
const trackingTable = options.trackingTable ??
|
|
97
|
+
const trackingTable = options.trackingTable ?? DEFAULT_MIGRATION_TRACKING_TABLE;
|
|
74
98
|
const onChecksumMismatch = options.onChecksumMismatch ?? 'error';
|
|
75
99
|
const beforeReset = options.beforeReset;
|
|
76
100
|
if (!Number.isInteger(targetVersion) || targetVersion < 0) {
|
|
@@ -91,14 +115,21 @@ export async function runMigrationsToVersion(options) {
|
|
|
91
115
|
const revertedVersions = [];
|
|
92
116
|
let wasReset = false;
|
|
93
117
|
let recoveredFromSchemaConflict = false;
|
|
118
|
+
const deterministicMigrations = getDeterministicMigrations(migrations);
|
|
94
119
|
// Check for checksum mismatches up-front when reset mode is enabled
|
|
95
120
|
if (onChecksumMismatch === 'reset' && applied.length > 0) {
|
|
96
|
-
|
|
121
|
+
let hasMismatch = false;
|
|
122
|
+
for (const migration of deterministicMigrations) {
|
|
97
123
|
const existing = appliedByVersion.get(migration.version);
|
|
98
|
-
if (!existing)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
124
|
+
if (!existing) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const currentChecksum = await getChecksumForAlgorithm(options, migration, existing.checksum_algorithm);
|
|
128
|
+
if (existing.checksum !== currentChecksum) {
|
|
129
|
+
hasMismatch = true;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
102
133
|
if (hasMismatch) {
|
|
103
134
|
// Let caller drop application tables first
|
|
104
135
|
await options.beforeReset?.(db);
|
|
@@ -115,8 +146,11 @@ export async function runMigrationsToVersion(options) {
|
|
|
115
146
|
if (!existing) {
|
|
116
147
|
continue;
|
|
117
148
|
}
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
if (migration.checksum === 'disabled') {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const currentChecksum = await getChecksumForAlgorithm(options, migration, existing.checksum_algorithm);
|
|
153
|
+
if (existing.checksum !== currentChecksum) {
|
|
120
154
|
throw new Error(`Migration v${migration.version} (${migration.name}) has changed since it was applied. ` +
|
|
121
155
|
`Stored checksum ${existing.checksum} is not compatible with current checksum ${currentChecksum}. ` +
|
|
122
156
|
'Migrations must not be modified after being applied.');
|
|
@@ -155,10 +189,12 @@ export async function runMigrationsToVersion(options) {
|
|
|
155
189
|
index = -1;
|
|
156
190
|
continue;
|
|
157
191
|
}
|
|
192
|
+
const checksum = await getStoredChecksumForMigration(options, migration);
|
|
158
193
|
await recordAppliedMigration(db, trackingTable, {
|
|
159
194
|
version: migration.version,
|
|
160
195
|
name: migration.name,
|
|
161
|
-
checksum
|
|
196
|
+
checksum,
|
|
197
|
+
checksum_algorithm: getMigrationChecksumAlgorithm(migration, options.checksums),
|
|
162
198
|
});
|
|
163
199
|
appliedVersions.push(migration.version);
|
|
164
200
|
}
|
|
@@ -169,9 +205,6 @@ export async function runMigrationsToVersion(options) {
|
|
|
169
205
|
if (!migration) {
|
|
170
206
|
throw new Error(`Cannot revert migration v${version}: migration is not defined in current migration set.`);
|
|
171
207
|
}
|
|
172
|
-
if (typeof migration.down !== 'function') {
|
|
173
|
-
throw new Error(`Cannot revert migration v${version} (${migration.name}): down migration is not defined.`);
|
|
174
|
-
}
|
|
175
208
|
await migration.down(db);
|
|
176
209
|
await removeAppliedMigration(db, trackingTable, version);
|
|
177
210
|
revertedVersions.push(version);
|
|
@@ -189,7 +222,7 @@ export async function runMigrationsToVersion(options) {
|
|
|
189
222
|
* Get the current schema version without running any migrations.
|
|
190
223
|
*/
|
|
191
224
|
export async function getSchemaVersion(db, trackingTable) {
|
|
192
|
-
const tableName = trackingTable ??
|
|
225
|
+
const tableName = trackingTable ?? DEFAULT_MIGRATION_TRACKING_TABLE;
|
|
193
226
|
const applied = await getAppliedMigrations(db, tableName);
|
|
194
227
|
if (applied.length === 0)
|
|
195
228
|
return 0;
|
package/dist/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/tracking.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracking.d.ts","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAC1C,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"tracking.d.ts","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAC1C,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,UAAU,SAAS,MAAM,EACtE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAU9B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,UAAU,SAAS,MAAM,EACxE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,GAC/C,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,UAAU,SAAS,MAAM,EACxE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,EAAE,EAC7C,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,UAAU,SAAS,MAAM,EACnE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,MAAM,CAAC,CAIjB"}
|
package/dist/tracking.js
CHANGED
|
@@ -13,6 +13,7 @@ export async function ensureTrackingTable(db, tableName) {
|
|
|
13
13
|
.addColumn('name', 'text', (col) => col.notNull())
|
|
14
14
|
.addColumn('applied_at', 'text', (col) => col.notNull())
|
|
15
15
|
.addColumn('checksum', 'text', (col) => col.notNull())
|
|
16
|
+
.addColumn('checksum_algorithm', 'text', (col) => col.notNull())
|
|
16
17
|
.execute();
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
@@ -21,7 +22,7 @@ export async function ensureTrackingTable(db, tableName) {
|
|
|
21
22
|
export async function getAppliedMigrations(db, tableName) {
|
|
22
23
|
await ensureTrackingTable(db, tableName);
|
|
23
24
|
const result = await sql `
|
|
24
|
-
select version, name, applied_at, checksum
|
|
25
|
+
select version, name, applied_at, checksum, checksum_algorithm
|
|
25
26
|
from ${sql.table(tableName)}
|
|
26
27
|
order by version asc
|
|
27
28
|
`.execute(db);
|
|
@@ -33,12 +34,19 @@ export async function getAppliedMigrations(db, tableName) {
|
|
|
33
34
|
export async function recordAppliedMigration(db, tableName, migration) {
|
|
34
35
|
await ensureTrackingTable(db, tableName);
|
|
35
36
|
await sql `
|
|
36
|
-
insert into ${sql.table(tableName)} (
|
|
37
|
+
insert into ${sql.table(tableName)} (
|
|
38
|
+
version,
|
|
39
|
+
name,
|
|
40
|
+
applied_at,
|
|
41
|
+
checksum,
|
|
42
|
+
checksum_algorithm
|
|
43
|
+
)
|
|
37
44
|
values (
|
|
38
45
|
${migration.version},
|
|
39
46
|
${migration.name},
|
|
40
47
|
${new Date().toISOString()},
|
|
41
|
-
${migration.checksum}
|
|
48
|
+
${migration.checksum},
|
|
49
|
+
${migration.checksum_algorithm}
|
|
42
50
|
)
|
|
43
51
|
`.execute(db);
|
|
44
52
|
}
|
package/dist/tracking.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracking.js","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAe,GAAG,EAAE,MAAM,QAAQ,CAAC;AAG1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAc,EACd,SAAiB
|
|
1
|
+
{"version":3,"file":"tracking.js","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAe,GAAG,EAAE,MAAM,QAAQ,CAAC;AAG1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAc,EACd,SAAiB;IAEjB,MAAM,EAAE,CAAC,MAAM;SACZ,WAAW,CAAC,SAAS,CAAC;SACtB,WAAW,EAAE;SACb,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;SAC1D,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACjD,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACvD,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACrD,SAAS,CAAC,oBAAoB,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SAC/D,OAAO,EAAE,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAc,EACd,SAAqB;IAErB,MAAM,mBAAmB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAEzC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAmB;;WAElC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;;GAE5B,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEd,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,EAAc,EACd,SAAqB,EACrB,SAAgD;IAEhD,MAAM,mBAAmB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAEzC,MAAM,GAAG,CAAA;kBACO,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;;;;;;;;QAQ9B,SAAS,CAAC,OAAO;QACjB,SAAS,CAAC,IAAI;QACd,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACxB,SAAS,CAAC,QAAQ;QAClB,SAAS,CAAC,kBAAkB;;GAEjC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,EAAc,EACd,SAAqB,EACrB,OAAe;IAEf,MAAM,mBAAmB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAEzC,MAAM,GAAG,CAAA;kBACO,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;sBAChB,OAAO;GAC1B,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,EAAc,EACd,SAAiB;IAEjB,MAAM,GAAG,CAAA,eAAe,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAc,EACd,SAAqB;IAErB,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,OAAO,CAAC;AAC9C,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ import type { Kysely } from 'kysely';
|
|
|
6
6
|
* A single migration function that modifies the database schema.
|
|
7
7
|
*/
|
|
8
8
|
export type MigrationFn<DB = unknown> = (db: Kysely<DB>) => Promise<void>;
|
|
9
|
+
export type MigrationChecksumMode = 'deterministic' | 'disabled';
|
|
10
|
+
export type MigrationChecksumAlgorithm = 'sql_trace_v1' | 'disabled';
|
|
11
|
+
export type MigrationChecksums = Record<string, string>;
|
|
9
12
|
/**
|
|
10
13
|
* A reversible migration definition.
|
|
11
14
|
*/
|
|
@@ -13,13 +16,12 @@ export interface ReversibleMigrationDefinition<DB = unknown> {
|
|
|
13
16
|
/** Apply schema/data changes for this version. */
|
|
14
17
|
up: MigrationFn<DB>;
|
|
15
18
|
/** Revert schema/data changes for this version. */
|
|
16
|
-
down
|
|
19
|
+
down: MigrationFn<DB>;
|
|
20
|
+
/** Controls whether this migration participates in checksum validation. */
|
|
21
|
+
checksum?: MigrationChecksumMode;
|
|
17
22
|
}
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
* an object with explicit up/down handlers.
|
|
21
|
-
*/
|
|
22
|
-
export type MigrationDefinition<DB = unknown> = MigrationFn<DB> | ReversibleMigrationDefinition<DB>;
|
|
23
|
+
/** A migration definition must explicitly provide both up/down handlers. */
|
|
24
|
+
export type MigrationDefinition<DB = unknown> = ReversibleMigrationDefinition<DB>;
|
|
23
25
|
/**
|
|
24
26
|
* Record of versioned migrations keyed by version string (e.g., 'v1', 'v2').
|
|
25
27
|
*/
|
|
@@ -32,8 +34,10 @@ export interface ParsedMigration<DB = unknown> {
|
|
|
32
34
|
name: string;
|
|
33
35
|
/** Up migration function. */
|
|
34
36
|
up: MigrationFn<DB>;
|
|
35
|
-
/**
|
|
36
|
-
down
|
|
37
|
+
/** Down migration function. */
|
|
38
|
+
down: MigrationFn<DB>;
|
|
39
|
+
/** Controls whether this migration participates in checksum validation. */
|
|
40
|
+
checksum: MigrationChecksumMode;
|
|
37
41
|
}
|
|
38
42
|
/**
|
|
39
43
|
* Result of defineMigrations() - contains migrations and metadata.
|
|
@@ -54,6 +58,7 @@ export interface MigrationStateRow {
|
|
|
54
58
|
name: string;
|
|
55
59
|
applied_at: string;
|
|
56
60
|
checksum: string;
|
|
61
|
+
checksum_algorithm: MigrationChecksumAlgorithm;
|
|
57
62
|
}
|
|
58
63
|
/**
|
|
59
64
|
* Options for running migrations.
|
|
@@ -63,6 +68,8 @@ export interface RunMigrationsOptions<DB = unknown> {
|
|
|
63
68
|
db: Kysely<DB>;
|
|
64
69
|
/** Defined migrations from defineMigrations() */
|
|
65
70
|
migrations: DefinedMigrations<DB>;
|
|
71
|
+
/** Generated deterministic checksums for this migration set. */
|
|
72
|
+
checksums?: MigrationChecksums;
|
|
66
73
|
/** Name of the tracking table (default: 'sync_migration_state') */
|
|
67
74
|
trackingTable?: string;
|
|
68
75
|
/** What to do when a migration's checksum doesn't match. Default: 'error' */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,EAAE,GAAG,OAAO,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,6BAA6B,CAAC,EAAE,GAAG,OAAO;IACzD,kDAAkD;IAClD,EAAE,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACpB,mDAAmD;IACnD,IAAI,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/migrations",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Database migration utilities for Syncular",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"test": "bun test --pass-with-no-tests",
|
|
42
42
|
"tsgo": "tsgo --noEmit",
|
|
43
43
|
"build": "tsgo",
|
|
44
|
-
"release": "
|
|
44
|
+
"release": "syncular-publish"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"kysely": "^0.28.0"
|
|
@@ -52,6 +52,14 @@
|
|
|
52
52
|
},
|
|
53
53
|
"files": [
|
|
54
54
|
"dist",
|
|
55
|
-
"src"
|
|
56
|
-
|
|
55
|
+
"src",
|
|
56
|
+
"!src/**/*.test.ts",
|
|
57
|
+
"!src/**/*.test.tsx",
|
|
58
|
+
"!src/**/__tests__/**",
|
|
59
|
+
"!dist/**/*.test.*",
|
|
60
|
+
"!dist/**/__tests__/**",
|
|
61
|
+
"!test/**",
|
|
62
|
+
"!tests/**"
|
|
63
|
+
],
|
|
64
|
+
"dependencies": {}
|
|
57
65
|
}
|
package/src/checksum.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MigrationChecksumAlgorithm,
|
|
3
|
+
MigrationChecksums,
|
|
4
|
+
ParsedMigration,
|
|
5
|
+
} from './types';
|
|
6
|
+
|
|
7
|
+
export const DISABLED_MIGRATION_CHECKSUM = '__syncular_checksum_disabled__';
|
|
8
|
+
export const SQL_TRACE_MIGRATION_CHECKSUM_ALGORITHM = 'sql_trace_v1';
|
|
9
|
+
export const DISABLED_MIGRATION_CHECKSUM_ALGORITHM = 'disabled';
|
|
10
|
+
|
|
11
|
+
export function getStoredDeterministicChecksum<DB>(
|
|
12
|
+
migration: ParsedMigration<DB>,
|
|
13
|
+
checksums: MigrationChecksums | undefined
|
|
14
|
+
): string {
|
|
15
|
+
if (migration.checksum === 'disabled') {
|
|
16
|
+
return DISABLED_MIGRATION_CHECKSUM;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!checksums) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Migration v${migration.version} (${migration.name}) requires generated checksums. ` +
|
|
22
|
+
'Generate a checksum manifest with @syncular/typegen and pass it to runMigrations({ checksums }).'
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const checksum = checksums[String(migration.version)];
|
|
27
|
+
|
|
28
|
+
if (!checksum) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Missing generated checksum for migration v${migration.version} (${migration.name}). ` +
|
|
31
|
+
'Regenerate the checksum manifest before running migrations.'
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return checksum;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function getMigrationChecksumAlgorithm<DB>(
|
|
39
|
+
migration: ParsedMigration<DB>,
|
|
40
|
+
checksums: MigrationChecksums | undefined
|
|
41
|
+
): MigrationChecksumAlgorithm {
|
|
42
|
+
if (migration.checksum === 'disabled') {
|
|
43
|
+
return DISABLED_MIGRATION_CHECKSUM_ALGORITHM;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!checksums) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Migration v${migration.version} (${migration.name}) requires generated checksums. ` +
|
|
49
|
+
'Generate a checksum manifest with @syncular/typegen and pass it to runMigrations({ checksums }).'
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return SQL_TRACE_MIGRATION_CHECKSUM_ALGORITHM;
|
|
54
|
+
}
|
package/src/define.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import type {
|
|
6
6
|
DefinedMigrations,
|
|
7
|
+
MigrationChecksumMode,
|
|
7
8
|
MigrationDefinition,
|
|
8
|
-
MigrationFn,
|
|
9
9
|
MigrationRecord,
|
|
10
10
|
ParsedMigration,
|
|
11
11
|
} from './types';
|
|
@@ -21,149 +21,26 @@ function parseVersionKey(key: string): number | null {
|
|
|
21
21
|
return Number.isNaN(version) ? null : version;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
*/
|
|
29
|
-
function stripCommentsPreservingStrings(source: string): string {
|
|
30
|
-
let out = '';
|
|
31
|
-
let i = 0;
|
|
32
|
-
let mode:
|
|
33
|
-
| 'code'
|
|
34
|
-
| 'singleQuote'
|
|
35
|
-
| 'doubleQuote'
|
|
36
|
-
| 'template'
|
|
37
|
-
| 'lineComment'
|
|
38
|
-
| 'blockComment' = 'code';
|
|
39
|
-
|
|
40
|
-
while (i < source.length) {
|
|
41
|
-
const char = source[i]!;
|
|
42
|
-
const next = source[i + 1];
|
|
43
|
-
|
|
44
|
-
if (mode === 'lineComment') {
|
|
45
|
-
if (char === '\n') {
|
|
46
|
-
out += '\n';
|
|
47
|
-
mode = 'code';
|
|
48
|
-
}
|
|
49
|
-
i += 1;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (mode === 'blockComment') {
|
|
54
|
-
if (char === '*' && next === '/') {
|
|
55
|
-
i += 2;
|
|
56
|
-
mode = 'code';
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (char === '\n') {
|
|
60
|
-
out += '\n';
|
|
61
|
-
}
|
|
62
|
-
i += 1;
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (mode === 'singleQuote') {
|
|
67
|
-
out += char;
|
|
68
|
-
if (char === '\\' && next !== undefined) {
|
|
69
|
-
out += next;
|
|
70
|
-
i += 2;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (char === "'") {
|
|
74
|
-
mode = 'code';
|
|
75
|
-
}
|
|
76
|
-
i += 1;
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (mode === 'doubleQuote') {
|
|
81
|
-
out += char;
|
|
82
|
-
if (char === '\\' && next !== undefined) {
|
|
83
|
-
out += next;
|
|
84
|
-
i += 2;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
if (char === '"') {
|
|
88
|
-
mode = 'code';
|
|
89
|
-
}
|
|
90
|
-
i += 1;
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (mode === 'template') {
|
|
95
|
-
out += char;
|
|
96
|
-
if (char === '\\' && next !== undefined) {
|
|
97
|
-
out += next;
|
|
98
|
-
i += 2;
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
if (char === '`') {
|
|
102
|
-
mode = 'code';
|
|
103
|
-
}
|
|
104
|
-
i += 1;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (char === '/' && next === '/') {
|
|
109
|
-
mode = 'lineComment';
|
|
110
|
-
i += 2;
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
if (char === '/' && next === '*') {
|
|
114
|
-
mode = 'blockComment';
|
|
115
|
-
i += 2;
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
if (char === "'") {
|
|
119
|
-
mode = 'singleQuote';
|
|
120
|
-
out += char;
|
|
121
|
-
i += 1;
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
if (char === '"') {
|
|
125
|
-
mode = 'doubleQuote';
|
|
126
|
-
out += char;
|
|
127
|
-
i += 1;
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
if (char === '`') {
|
|
131
|
-
mode = 'template';
|
|
132
|
-
out += char;
|
|
133
|
-
i += 1;
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
out += char;
|
|
138
|
-
i += 1;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return out;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function normalizeSource(source: string): string {
|
|
145
|
-
return stripCommentsPreservingStrings(source)
|
|
146
|
-
.replace(/\s+/g, ' ') // collapse whitespace
|
|
147
|
-
.trim();
|
|
24
|
+
function isMigrationDefinitionObject<DB>(
|
|
25
|
+
value: MigrationDefinition<DB>
|
|
26
|
+
): value is MigrationDefinition<DB> {
|
|
27
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
148
28
|
}
|
|
149
29
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
30
|
+
function normalizeChecksumMode(
|
|
31
|
+
key: string,
|
|
32
|
+
checksum: MigrationChecksumMode | undefined
|
|
33
|
+
): MigrationChecksumMode {
|
|
34
|
+
if (checksum === undefined) {
|
|
35
|
+
return 'deterministic';
|
|
36
|
+
}
|
|
37
|
+
if (checksum === 'deterministic' || checksum === 'disabled') {
|
|
38
|
+
return checksum;
|
|
159
39
|
}
|
|
160
|
-
return hash.toString(16).padStart(8, '0');
|
|
161
|
-
}
|
|
162
40
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
)
|
|
166
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Invalid migration "${key}": "checksum" must be "deterministic" or "disabled" when provided.`
|
|
43
|
+
);
|
|
167
44
|
}
|
|
168
45
|
|
|
169
46
|
/**
|
|
@@ -172,16 +49,28 @@ function isMigrationDefinitionObject<DB>(
|
|
|
172
49
|
* @example
|
|
173
50
|
* ```typescript
|
|
174
51
|
* export const migrations = defineMigrations({
|
|
175
|
-
* v1:
|
|
176
|
-
*
|
|
177
|
-
* .
|
|
178
|
-
*
|
|
179
|
-
*
|
|
52
|
+
* v1: {
|
|
53
|
+
* up: async (db) => {
|
|
54
|
+
* await db.schema.createTable('tasks')
|
|
55
|
+
* .addColumn('id', 'text', col => col.primaryKey())
|
|
56
|
+
* .addColumn('title', 'text', col => col.notNull())
|
|
57
|
+
* .execute();
|
|
58
|
+
* },
|
|
59
|
+
* down: async (db) => {
|
|
60
|
+
* await db.schema.dropTable('tasks').ifExists().execute();
|
|
61
|
+
* },
|
|
180
62
|
* },
|
|
181
|
-
* v2:
|
|
182
|
-
*
|
|
183
|
-
* .
|
|
184
|
-
*
|
|
63
|
+
* v2: {
|
|
64
|
+
* up: async (db) => {
|
|
65
|
+
* await db.schema.alterTable('tasks')
|
|
66
|
+
* .addColumn('priority', 'integer', col => col.defaultTo(0))
|
|
67
|
+
* .execute();
|
|
68
|
+
* },
|
|
69
|
+
* down: async (db) => {
|
|
70
|
+
* await db.schema.alterTable('tasks')
|
|
71
|
+
* .dropColumn('priority')
|
|
72
|
+
* .execute();
|
|
73
|
+
* },
|
|
185
74
|
* },
|
|
186
75
|
* });
|
|
187
76
|
* ```
|
|
@@ -205,28 +94,27 @@ export function defineMigrations<
|
|
|
205
94
|
);
|
|
206
95
|
}
|
|
207
96
|
|
|
208
|
-
|
|
209
|
-
? definition.up
|
|
210
|
-
: definition;
|
|
211
|
-
const down = isMigrationDefinitionObject(definition)
|
|
212
|
-
? definition.down
|
|
213
|
-
: undefined;
|
|
214
|
-
if (typeof up !== 'function') {
|
|
97
|
+
if (!isMigrationDefinitionObject(definition)) {
|
|
215
98
|
throw new Error(
|
|
216
|
-
`Invalid migration "${key}": expected
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
if (down !== undefined && typeof down !== 'function') {
|
|
220
|
-
throw new Error(
|
|
221
|
-
`Invalid migration "${key}": "down" must be a function when provided.`
|
|
99
|
+
`Invalid migration "${key}": expected a { up, down } object. Shorthand migration functions are not supported.`
|
|
222
100
|
);
|
|
223
101
|
}
|
|
224
102
|
|
|
103
|
+
const { up, down } = definition;
|
|
104
|
+
const checksum = normalizeChecksumMode(key, definition.checksum);
|
|
105
|
+
|
|
106
|
+
if (typeof up !== 'function') {
|
|
107
|
+
throw new Error(`Invalid migration "${key}": "up" must be a function.`);
|
|
108
|
+
}
|
|
109
|
+
if (typeof down !== 'function') {
|
|
110
|
+
throw new Error(`Invalid migration "${key}": "down" must be a function.`);
|
|
111
|
+
}
|
|
225
112
|
migrations.push({
|
|
226
113
|
version,
|
|
227
114
|
name: key,
|
|
228
115
|
up,
|
|
229
116
|
down,
|
|
117
|
+
checksum,
|
|
230
118
|
});
|
|
231
119
|
}
|
|
232
120
|
|
|
@@ -251,12 +139,3 @@ export function defineMigrations<
|
|
|
251
139
|
},
|
|
252
140
|
};
|
|
253
141
|
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Get the checksum for a migration.
|
|
257
|
-
*/
|
|
258
|
-
export function getMigrationChecksum<DB>(
|
|
259
|
-
migration: ParsedMigration<DB>
|
|
260
|
-
): string {
|
|
261
|
-
return computeChecksum(migration.up);
|
|
262
|
-
}
|