@syncular/migrations 0.0.6-244 → 0.0.6-246
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 +42 -11
- package/dist/checksum.d.ts +9 -0
- package/dist/checksum.d.ts.map +1 -0
- package/dist/checksum.js +142 -0
- package/dist/checksum.js.map +1 -0
- package/dist/define.d.ts +22 -18
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +39 -166
- package/dist/define.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/runner.d.ts +8 -2
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +50 -15
- package/dist/runner.js.map +1 -1
- package/dist/tracking.d.ts.map +1 -1
- package/dist/tracking.js +32 -3
- package/dist/tracking.js.map +1 -1
- package/dist/types.d.ts +15 -15
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/checksum.ts +190 -0
- package/src/define.ts +49 -201
- package/src/index.ts +1 -0
- package/src/runner.ts +94 -20
- package/src/tracking.ts +36 -3
- package/src/types.ts +21 -16
package/dist/runner.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @syncular/migrations - Migration runner
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import { DISABLED_MIGRATION_CHECKSUM, DISABLED_MIGRATION_CHECKSUM_ALGORITHM, getLegacyMigrationChecksum, getMigrationChecksumAlgorithm, getStoredDeterministicChecksum, LEGACY_SOURCE_MIGRATION_CHECKSUM_ALGORITHM, } from './checksum.js';
|
|
5
5
|
import { DEFAULT_MIGRATION_TRACKING_TABLE } from './naming.js';
|
|
6
6
|
import { clearAppliedMigrations, ensureTrackingTable, getAppliedMigrations, recordAppliedMigration, removeAppliedMigration, } from './tracking.js';
|
|
7
7
|
const migrationRunQueues = new Map();
|
|
@@ -13,6 +13,27 @@ 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 === LEGACY_SOURCE_MIGRATION_CHECKSUM_ALGORITHM) {
|
|
30
|
+
return getLegacyMigrationChecksum(migration);
|
|
31
|
+
}
|
|
32
|
+
if (algorithm === 'sql_trace_v1') {
|
|
33
|
+
return await getStoredChecksumForMigration(options, migration);
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`Unsupported migration checksum algorithm: ${algorithm}`);
|
|
36
|
+
}
|
|
16
37
|
async function runWithMigrationQueue(queueKey, task) {
|
|
17
38
|
const previous = migrationRunQueues.get(queueKey) ?? Promise.resolve();
|
|
18
39
|
let release;
|
|
@@ -40,8 +61,14 @@ async function runWithMigrationQueue(queueKey, task) {
|
|
|
40
61
|
* import { defineMigrations, runMigrations } from '@syncular/migrations';
|
|
41
62
|
*
|
|
42
63
|
* const migrations = defineMigrations({
|
|
43
|
-
* v1:
|
|
44
|
-
*
|
|
64
|
+
* v1: {
|
|
65
|
+
* up: async (db) => { ... },
|
|
66
|
+
* down: async (db) => { ... },
|
|
67
|
+
* },
|
|
68
|
+
* v2: {
|
|
69
|
+
* up: async (db) => { ... },
|
|
70
|
+
* down: async (db) => { ... },
|
|
71
|
+
* },
|
|
45
72
|
* });
|
|
46
73
|
*
|
|
47
74
|
* const result = await runMigrations({
|
|
@@ -91,14 +118,21 @@ export async function runMigrationsToVersion(options) {
|
|
|
91
118
|
const revertedVersions = [];
|
|
92
119
|
let wasReset = false;
|
|
93
120
|
let recoveredFromSchemaConflict = false;
|
|
121
|
+
const deterministicMigrations = getDeterministicMigrations(migrations);
|
|
94
122
|
// Check for checksum mismatches up-front when reset mode is enabled
|
|
95
123
|
if (onChecksumMismatch === 'reset' && applied.length > 0) {
|
|
96
|
-
|
|
124
|
+
let hasMismatch = false;
|
|
125
|
+
for (const migration of deterministicMigrations) {
|
|
97
126
|
const existing = appliedByVersion.get(migration.version);
|
|
98
|
-
if (!existing)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
127
|
+
if (!existing) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const currentChecksum = await getChecksumForAlgorithm(options, migration, existing.checksum_algorithm);
|
|
131
|
+
if (existing.checksum !== currentChecksum) {
|
|
132
|
+
hasMismatch = true;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
102
136
|
if (hasMismatch) {
|
|
103
137
|
// Let caller drop application tables first
|
|
104
138
|
await options.beforeReset?.(db);
|
|
@@ -115,9 +149,11 @@ export async function runMigrationsToVersion(options) {
|
|
|
115
149
|
if (!existing) {
|
|
116
150
|
continue;
|
|
117
151
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
152
|
+
if (migration.checksum === 'disabled') {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const currentChecksum = await getChecksumForAlgorithm(options, migration, existing.checksum_algorithm);
|
|
156
|
+
if (existing.checksum !== currentChecksum) {
|
|
121
157
|
throw new Error(`Migration v${migration.version} (${migration.name}) has changed since it was applied. ` +
|
|
122
158
|
`Stored checksum ${existing.checksum} is not compatible with current checksum ${currentChecksum}. ` +
|
|
123
159
|
'Migrations must not be modified after being applied.');
|
|
@@ -156,10 +192,12 @@ export async function runMigrationsToVersion(options) {
|
|
|
156
192
|
index = -1;
|
|
157
193
|
continue;
|
|
158
194
|
}
|
|
195
|
+
const checksum = await getStoredChecksumForMigration(options, migration);
|
|
159
196
|
await recordAppliedMigration(db, trackingTable, {
|
|
160
197
|
version: migration.version,
|
|
161
198
|
name: migration.name,
|
|
162
|
-
checksum
|
|
199
|
+
checksum,
|
|
200
|
+
checksum_algorithm: getMigrationChecksumAlgorithm(migration, options.checksums),
|
|
163
201
|
});
|
|
164
202
|
appliedVersions.push(migration.version);
|
|
165
203
|
}
|
|
@@ -170,9 +208,6 @@ export async function runMigrationsToVersion(options) {
|
|
|
170
208
|
if (!migration) {
|
|
171
209
|
throw new Error(`Cannot revert migration v${version}: migration is not defined in current migration set.`);
|
|
172
210
|
}
|
|
173
|
-
if (typeof migration.down !== 'function') {
|
|
174
|
-
throw new Error(`Cannot revert migration v${version} (${migration.name}): down migration is not defined.`);
|
|
175
|
-
}
|
|
176
211
|
await migration.down(db);
|
|
177
212
|
await removeAppliedMigration(db, trackingTable, version);
|
|
178
213
|
revertedVersions.push(version);
|
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,EACL
|
|
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;
|
|
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;AAE1C,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,CAqBf;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
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
* @syncular/migrations - Migration tracking table helpers
|
|
3
3
|
*/
|
|
4
4
|
import { sql } from 'kysely';
|
|
5
|
+
import { LEGACY_SOURCE_MIGRATION_CHECKSUM_ALGORITHM } from './checksum.js';
|
|
6
|
+
function isDuplicateColumnError(error) {
|
|
7
|
+
if (!(error instanceof Error)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const message = error.message.toLowerCase();
|
|
11
|
+
return (message.includes('duplicate column') ||
|
|
12
|
+
message.includes('already exists') ||
|
|
13
|
+
(message.includes('column') && message.includes('exists')));
|
|
14
|
+
}
|
|
5
15
|
/**
|
|
6
16
|
* Ensure the migration tracking table exists.
|
|
7
17
|
*/
|
|
@@ -13,7 +23,19 @@ export async function ensureTrackingTable(db, tableName) {
|
|
|
13
23
|
.addColumn('name', 'text', (col) => col.notNull())
|
|
14
24
|
.addColumn('applied_at', 'text', (col) => col.notNull())
|
|
15
25
|
.addColumn('checksum', 'text', (col) => col.notNull())
|
|
26
|
+
.addColumn('checksum_algorithm', 'text', (col) => col.notNull())
|
|
16
27
|
.execute();
|
|
28
|
+
try {
|
|
29
|
+
await sql `
|
|
30
|
+
alter table ${sql.table(tableName)}
|
|
31
|
+
add column checksum_algorithm text not null default ${sql.raw(`'${LEGACY_SOURCE_MIGRATION_CHECKSUM_ALGORITHM}'`)}
|
|
32
|
+
`.execute(db);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (!isDuplicateColumnError(error)) {
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
17
39
|
}
|
|
18
40
|
/**
|
|
19
41
|
* Get all applied migrations from the tracking table.
|
|
@@ -21,7 +43,7 @@ export async function ensureTrackingTable(db, tableName) {
|
|
|
21
43
|
export async function getAppliedMigrations(db, tableName) {
|
|
22
44
|
await ensureTrackingTable(db, tableName);
|
|
23
45
|
const result = await sql `
|
|
24
|
-
select version, name, applied_at, checksum
|
|
46
|
+
select version, name, applied_at, checksum, checksum_algorithm
|
|
25
47
|
from ${sql.table(tableName)}
|
|
26
48
|
order by version asc
|
|
27
49
|
`.execute(db);
|
|
@@ -33,12 +55,19 @@ export async function getAppliedMigrations(db, tableName) {
|
|
|
33
55
|
export async function recordAppliedMigration(db, tableName, migration) {
|
|
34
56
|
await ensureTrackingTable(db, tableName);
|
|
35
57
|
await sql `
|
|
36
|
-
insert into ${sql.table(tableName)} (
|
|
58
|
+
insert into ${sql.table(tableName)} (
|
|
59
|
+
version,
|
|
60
|
+
name,
|
|
61
|
+
applied_at,
|
|
62
|
+
checksum,
|
|
63
|
+
checksum_algorithm
|
|
64
|
+
)
|
|
37
65
|
values (
|
|
38
66
|
${migration.version},
|
|
39
67
|
${migration.name},
|
|
40
68
|
${new Date().toISOString()},
|
|
41
|
-
${migration.checksum}
|
|
69
|
+
${migration.checksum},
|
|
70
|
+
${migration.checksum_algorithm}
|
|
42
71
|
)
|
|
43
72
|
`.execute(db);
|
|
44
73
|
}
|
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;
|
|
1
|
+
{"version":3,"file":"tracking.js","sourceRoot":"","sources":["../src/tracking.ts"],"names":[],"mappings":"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"}
|
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 = 'legacy_source_v1' | 'sql_trace_v1' | 'disabled';
|
|
11
|
+
export type MigrationChecksums = Record<string, string>;
|
|
9
12
|
/**
|
|
10
13
|
* A reversible migration definition.
|
|
11
14
|
*/
|
|
@@ -13,18 +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
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
* copies of this migration.
|
|
20
|
-
*/
|
|
21
|
-
compatibleChecksums?: string[];
|
|
19
|
+
down: MigrationFn<DB>;
|
|
20
|
+
/** Controls whether this migration participates in checksum validation. */
|
|
21
|
+
checksum?: MigrationChecksumMode;
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
* an object with explicit up/down handlers.
|
|
26
|
-
*/
|
|
27
|
-
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>;
|
|
28
25
|
/**
|
|
29
26
|
* Record of versioned migrations keyed by version string (e.g., 'v1', 'v2').
|
|
30
27
|
*/
|
|
@@ -37,10 +34,10 @@ export interface ParsedMigration<DB = unknown> {
|
|
|
37
34
|
name: string;
|
|
38
35
|
/** Up migration function. */
|
|
39
36
|
up: MigrationFn<DB>;
|
|
40
|
-
/**
|
|
41
|
-
down
|
|
42
|
-
/**
|
|
43
|
-
|
|
37
|
+
/** Down migration function. */
|
|
38
|
+
down: MigrationFn<DB>;
|
|
39
|
+
/** Controls whether this migration participates in checksum validation. */
|
|
40
|
+
checksum: MigrationChecksumMode;
|
|
44
41
|
}
|
|
45
42
|
/**
|
|
46
43
|
* Result of defineMigrations() - contains migrations and metadata.
|
|
@@ -61,6 +58,7 @@ export interface MigrationStateRow {
|
|
|
61
58
|
name: string;
|
|
62
59
|
applied_at: string;
|
|
63
60
|
checksum: string;
|
|
61
|
+
checksum_algorithm: MigrationChecksumAlgorithm;
|
|
64
62
|
}
|
|
65
63
|
/**
|
|
66
64
|
* Options for running migrations.
|
|
@@ -70,6 +68,8 @@ export interface RunMigrationsOptions<DB = unknown> {
|
|
|
70
68
|
db: Kysely<DB>;
|
|
71
69
|
/** Defined migrations from defineMigrations() */
|
|
72
70
|
migrations: DefinedMigrations<DB>;
|
|
71
|
+
/** Generated deterministic checksums for this migration set. */
|
|
72
|
+
checksums?: MigrationChecksums;
|
|
73
73
|
/** Name of the tracking table (default: 'sync_migration_state') */
|
|
74
74
|
trackingTable?: string;
|
|
75
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.0.6-
|
|
3
|
+
"version": "0.0.6-246",
|
|
4
4
|
"description": "Database migration utilities for Syncular",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -53,5 +53,6 @@
|
|
|
53
53
|
"files": [
|
|
54
54
|
"dist",
|
|
55
55
|
"src"
|
|
56
|
-
]
|
|
56
|
+
],
|
|
57
|
+
"dependencies": {}
|
|
57
58
|
}
|
package/src/checksum.ts
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
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 LEGACY_SOURCE_MIGRATION_CHECKSUM_ALGORITHM = 'legacy_source_v1';
|
|
9
|
+
export const SQL_TRACE_MIGRATION_CHECKSUM_ALGORITHM = 'sql_trace_v1';
|
|
10
|
+
export const DISABLED_MIGRATION_CHECKSUM_ALGORITHM = 'disabled';
|
|
11
|
+
|
|
12
|
+
function stripCommentsPreservingStrings(source: string): string {
|
|
13
|
+
let out = '';
|
|
14
|
+
let index = 0;
|
|
15
|
+
let mode:
|
|
16
|
+
| 'code'
|
|
17
|
+
| 'singleQuote'
|
|
18
|
+
| 'doubleQuote'
|
|
19
|
+
| 'template'
|
|
20
|
+
| 'lineComment'
|
|
21
|
+
| 'blockComment' = 'code';
|
|
22
|
+
|
|
23
|
+
while (index < source.length) {
|
|
24
|
+
const char = source[index]!;
|
|
25
|
+
const next = source[index + 1];
|
|
26
|
+
|
|
27
|
+
if (mode === 'lineComment') {
|
|
28
|
+
if (char === '\n') {
|
|
29
|
+
out += '\n';
|
|
30
|
+
mode = 'code';
|
|
31
|
+
}
|
|
32
|
+
index += 1;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (mode === 'blockComment') {
|
|
37
|
+
if (char === '*' && next === '/') {
|
|
38
|
+
index += 2;
|
|
39
|
+
mode = 'code';
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (char === '\n') {
|
|
43
|
+
out += '\n';
|
|
44
|
+
}
|
|
45
|
+
index += 1;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (mode === 'singleQuote') {
|
|
50
|
+
out += char;
|
|
51
|
+
if (char === '\\' && next !== undefined) {
|
|
52
|
+
out += next;
|
|
53
|
+
index += 2;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (char === "'") {
|
|
57
|
+
mode = 'code';
|
|
58
|
+
}
|
|
59
|
+
index += 1;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (mode === 'doubleQuote') {
|
|
64
|
+
out += char;
|
|
65
|
+
if (char === '\\' && next !== undefined) {
|
|
66
|
+
out += next;
|
|
67
|
+
index += 2;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (char === '"') {
|
|
71
|
+
mode = 'code';
|
|
72
|
+
}
|
|
73
|
+
index += 1;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (mode === 'template') {
|
|
78
|
+
out += char;
|
|
79
|
+
if (char === '\\' && next !== undefined) {
|
|
80
|
+
out += next;
|
|
81
|
+
index += 2;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (char === '`') {
|
|
85
|
+
mode = 'code';
|
|
86
|
+
}
|
|
87
|
+
index += 1;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (char === '/' && next === '/') {
|
|
92
|
+
mode = 'lineComment';
|
|
93
|
+
index += 2;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (char === '/' && next === '*') {
|
|
97
|
+
mode = 'blockComment';
|
|
98
|
+
index += 2;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (char === "'") {
|
|
102
|
+
mode = 'singleQuote';
|
|
103
|
+
out += char;
|
|
104
|
+
index += 1;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (char === '"') {
|
|
108
|
+
mode = 'doubleQuote';
|
|
109
|
+
out += char;
|
|
110
|
+
index += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (char === '`') {
|
|
114
|
+
mode = 'template';
|
|
115
|
+
out += char;
|
|
116
|
+
index += 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
out += char;
|
|
121
|
+
index += 1;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function hashString(value: string): string {
|
|
128
|
+
let hash = 0;
|
|
129
|
+
|
|
130
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
131
|
+
hash = (hash * 31 + value.charCodeAt(index)) >>> 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return hash.toString(16).padStart(8, '0');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function normalizeLegacySource(source: string): string {
|
|
138
|
+
return stripCommentsPreservingStrings(source).replace(/\s+/g, ' ').trim();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function getLegacyMigrationChecksum<DB>(
|
|
142
|
+
migration: ParsedMigration<DB>
|
|
143
|
+
): string {
|
|
144
|
+
return hashString(normalizeLegacySource(migration.up.toString()));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function getStoredDeterministicChecksum<DB>(
|
|
148
|
+
migration: ParsedMigration<DB>,
|
|
149
|
+
checksums: MigrationChecksums | undefined
|
|
150
|
+
): string {
|
|
151
|
+
if (migration.checksum === 'disabled') {
|
|
152
|
+
return DISABLED_MIGRATION_CHECKSUM;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (!checksums) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Migration v${migration.version} (${migration.name}) requires generated checksums. ` +
|
|
158
|
+
'Generate a checksum manifest with @syncular/typegen and pass it to runMigrations({ checksums }).'
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const checksum = checksums[String(migration.version)];
|
|
163
|
+
|
|
164
|
+
if (!checksum) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`Missing generated checksum for migration v${migration.version} (${migration.name}). ` +
|
|
167
|
+
'Regenerate the checksum manifest before running migrations.'
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return checksum;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function getMigrationChecksumAlgorithm<DB>(
|
|
175
|
+
migration: ParsedMigration<DB>,
|
|
176
|
+
checksums: MigrationChecksums | undefined
|
|
177
|
+
): MigrationChecksumAlgorithm {
|
|
178
|
+
if (migration.checksum === 'disabled') {
|
|
179
|
+
return DISABLED_MIGRATION_CHECKSUM_ALGORITHM;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!checksums) {
|
|
183
|
+
throw new Error(
|
|
184
|
+
`Migration v${migration.version} (${migration.name}) requires generated checksums. ` +
|
|
185
|
+
'Generate a checksum manifest with @syncular/typegen and pass it to runMigrations({ checksums }).'
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return SQL_TRACE_MIGRATION_CHECKSUM_ALGORITHM;
|
|
190
|
+
}
|