@metaobjectsdev/migrate-ts 0.20.11-rc.1 → 0.20.12-rc.1
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/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/write-migration-flyway.d.ts +29 -0
- package/dist/write-migration-flyway.d.ts.map +1 -0
- package/dist/write-migration-flyway.js +74 -0
- package/dist/write-migration-flyway.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +2 -0
- package/src/write-migration-flyway.ts +98 -0
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type { DriftClassification } from "./drift/classify.js";
|
|
|
8
8
|
export { emit } from "./emit/index.js";
|
|
9
9
|
export { writeMigration } from "./write-migration.js";
|
|
10
10
|
export { writeMigrationD1 } from "./write-migration-d1.js";
|
|
11
|
+
export { writeMigrationFlyway } from "./write-migration-flyway.js";
|
|
11
12
|
export { serializeSnapshot, parseSnapshot, SNAPSHOT_FORMAT_VERSION, } from "./snapshot/serialize.js";
|
|
12
13
|
export { snapshotChecksum } from "./snapshot/checksum.js";
|
|
13
14
|
export { snapshotPath, readSnapshot, writeSnapshot } from "./snapshot/store.js";
|
|
@@ -21,6 +22,7 @@ export type { DiffArgs } from "./diff/index.js";
|
|
|
21
22
|
export type { EmitOptions } from "./emit/index.js";
|
|
22
23
|
export type { WriteMigrationOptions, WriteMigrationResult } from "./write-migration.js";
|
|
23
24
|
export type { WriteMigrationD1Options, WriteMigrationD1Result } from "./write-migration-d1.js";
|
|
25
|
+
export type { WriteMigrationFlywayOptions, WriteMigrationFlywayResult } from "./write-migration-flyway.js";
|
|
24
26
|
export { normalizeViewSql, viewSqlEquals } from "./view-sql-compare.js";
|
|
25
27
|
export { renderD1 } from "./emit/d1.js";
|
|
26
28
|
export { applyD1SafetyPass, D1UnsupportedStatementError } from "./emit/d1-safety-pass.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACvE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG7E,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGlG,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG1D,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EACV,cAAc,EAAE,YAAY,EAC5B,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAC/E,cAAc,EAAE,QAAQ,EACxB,MAAM,EAAE,UAAU,EAAE,YAAY,EAChC,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,EACrE,UAAU,EAAE,UAAU,EAAE,OAAO,GAChC,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACxF,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAC/F,YAAY,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAM3G,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAMxE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxH,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,OAAO,EAAE,YAAY,EAAE,KAAK,QAAQ,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG3F,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export { classifyDrift, driftAgainstSnapshot } from "./drift/classify.js";
|
|
|
16
16
|
export { emit } from "./emit/index.js";
|
|
17
17
|
export { writeMigration } from "./write-migration.js";
|
|
18
18
|
export { writeMigrationD1 } from "./write-migration-d1.js";
|
|
19
|
+
export { writeMigrationFlyway } from "./write-migration-flyway.js";
|
|
19
20
|
// Reference-snapshot generation (offline, deterministic).
|
|
20
21
|
export { serializeSnapshot, parseSnapshot, SNAPSHOT_FORMAT_VERSION, } from "./snapshot/serialize.js";
|
|
21
22
|
export { snapshotChecksum } from "./snapshot/checksum.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,gEAAgE;AAChE,yEAAyE;AACzE,sEAAsE;AACtE,2BAA2B;AAC3B,EAAE;AACF,2DAA2D;AAE3D,qBAAqB;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAA4B,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,gEAAgE;AAChE,yEAAyE;AACzE,sEAAsE;AACtE,2BAA2B;AAC3B,EAAE;AACF,2DAA2D;AAE3D,qBAAqB;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAA4B,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,0DAA0D;AAC1D,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAGvE,SAAS;AACT,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAElG,oEAAoE;AACpE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAkB1D,+EAA+E;AAC/E,gFAAgF;AAChF,mFAAmF;AACnF,4EAA4E;AAC5E,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAExE,oCAAoC;AACpC,wEAAwE;AACxE,yEAAyE;AACzE,8CAA8C;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGxH,mBAAmB;AACnB,OAAO,EAAE,YAAY,EAA2C,MAAM,oBAAoB,CAAC;AAE3F,2EAA2E;AAC3E,OAAO,EACL,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,qBAAqB,GAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,UAAU,GAKX,MAAM,kBAAkB,CAAC;AAE1B,0EAA0E;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,0BAA0B;AAC1B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,GAGjB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { EmitResult } from "./types.js";
|
|
2
|
+
export interface WriteMigrationFlywayOptions {
|
|
3
|
+
/** Flyway migrations dir (e.g. "src/main/resources/db/migration"). Created if missing. */
|
|
4
|
+
dir: string;
|
|
5
|
+
/** Human-readable slug; sanitized to lowercase + underscores. */
|
|
6
|
+
slug: string;
|
|
7
|
+
}
|
|
8
|
+
export interface WriteMigrationFlywayResult {
|
|
9
|
+
/** Full path to the versioned (V) migration. */
|
|
10
|
+
upPath: string;
|
|
11
|
+
/** Full path to the undo (U) migration. */
|
|
12
|
+
downPath: string;
|
|
13
|
+
/** Assigned version number (e.g. 1, 2, 11). */
|
|
14
|
+
version: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* #192 — the ADR-0015 Flyway-prefix output adapter.
|
|
18
|
+
*
|
|
19
|
+
* Emits the engine's already-computed up/down SQL in Flyway's envelope:
|
|
20
|
+
* `V<N>__<slug>.sql` plus `U<N>__<slug>.sql`. Undo is a paid Flyway edition
|
|
21
|
+
* feature — Community IGNORES `U__` files rather than failing on them — so the
|
|
22
|
+
* undo file is inert-but-correct there and becomes live on Teams/Enterprise.
|
|
23
|
+
*
|
|
24
|
+
* Applying is deliberately NOT our job here: Flyway owns apply and its
|
|
25
|
+
* `flyway_schema_history`. The CLI refuses --apply / apply-pending / --rollback
|
|
26
|
+
* under this format rather than desyncing that history.
|
|
27
|
+
*/
|
|
28
|
+
export declare function writeMigrationFlyway(result: Pick<EmitResult, "up" | "down">, opts: WriteMigrationFlywayOptions): Promise<WriteMigrationFlywayResult>;
|
|
29
|
+
//# sourceMappingURL=write-migration-flyway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-migration-flyway.d.ts","sourceRoot":"","sources":["../src/write-migration-flyway.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,2BAA2B;IAC1C,0FAA0F;IAC1F,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,0BAA0B;IACzC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAeD;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,CAAC,EACvC,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,0BAA0B,CAAC,CAarC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { mkdir, readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
// Versioned migrations ONLY. Matching [VU] here would let the undo files we
|
|
4
|
+
// ourselves emit bump the counter, skipping a version on every run.
|
|
5
|
+
//
|
|
6
|
+
// A Flyway version may have multiple parts separated by EITHER a dot or an
|
|
7
|
+
// underscore (V1.1__ and V1_0__ are both legal; the latter is version 1.0). We
|
|
8
|
+
// increment the LEADING integer, so an existing V10.5__ yields V11__. Missing the
|
|
9
|
+
// underscore form is not cosmetic: against a dir holding V1_0__init.sql the
|
|
10
|
+
// scanner would see nothing versioned, restart at V1, and Flyway — which pads
|
|
11
|
+
// versions for comparison, so 1 == 1.0 — would reject the result as a duplicate
|
|
12
|
+
// version. That is an un-appliable migration, the failure class this engine
|
|
13
|
+
// hardens against elsewhere (#226/#241/#258).
|
|
14
|
+
const VERSIONED_RE = /^V(\d+)(?:[._]\d+)*__/;
|
|
15
|
+
/**
|
|
16
|
+
* #192 — the ADR-0015 Flyway-prefix output adapter.
|
|
17
|
+
*
|
|
18
|
+
* Emits the engine's already-computed up/down SQL in Flyway's envelope:
|
|
19
|
+
* `V<N>__<slug>.sql` plus `U<N>__<slug>.sql`. Undo is a paid Flyway edition
|
|
20
|
+
* feature — Community IGNORES `U__` files rather than failing on them — so the
|
|
21
|
+
* undo file is inert-but-correct there and becomes live on Teams/Enterprise.
|
|
22
|
+
*
|
|
23
|
+
* Applying is deliberately NOT our job here: Flyway owns apply and its
|
|
24
|
+
* `flyway_schema_history`. The CLI refuses --apply / apply-pending / --rollback
|
|
25
|
+
* under this format rather than desyncing that history.
|
|
26
|
+
*/
|
|
27
|
+
export async function writeMigrationFlyway(result, opts) {
|
|
28
|
+
await mkdir(opts.dir, { recursive: true });
|
|
29
|
+
const version = await nextVersion(opts.dir);
|
|
30
|
+
const slug = sanitizeSlug(opts.slug);
|
|
31
|
+
const upPath = join(opts.dir, `V${version}__${slug}.sql`);
|
|
32
|
+
const downPath = join(opts.dir, `U${version}__${slug}.sql`);
|
|
33
|
+
await writeFile(upPath, ensureTrailingNewline(result.up), "utf8");
|
|
34
|
+
await writeFile(downPath, ensureTrailingNewline(result.down), "utf8");
|
|
35
|
+
return { upPath, downPath, version };
|
|
36
|
+
}
|
|
37
|
+
async function nextVersion(dir) {
|
|
38
|
+
let entries;
|
|
39
|
+
// Best-effort: dir was just mkdir'd, but in race/permission edge cases the
|
|
40
|
+
// listing can still fail; treat as empty (next version = 1) rather than rethrow.
|
|
41
|
+
try {
|
|
42
|
+
entries = await readdir(dir);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
47
|
+
let max = 0;
|
|
48
|
+
for (const entry of entries) {
|
|
49
|
+
if (!entry.endsWith(".sql"))
|
|
50
|
+
continue;
|
|
51
|
+
const m = VERSIONED_RE.exec(entry);
|
|
52
|
+
if (!m)
|
|
53
|
+
continue;
|
|
54
|
+
const n = parseInt(m[1], 10);
|
|
55
|
+
if (n > max)
|
|
56
|
+
max = n;
|
|
57
|
+
}
|
|
58
|
+
return max + 1;
|
|
59
|
+
}
|
|
60
|
+
// Underscores, NOT hyphens: Flyway renders a description's underscores as
|
|
61
|
+
// spaces, so V4__add_program_view.sql is the idiomatic shape. (The D1 adapter
|
|
62
|
+
// sanitizes to hyphens for Wrangler; do not copy that here.)
|
|
63
|
+
function sanitizeSlug(raw) {
|
|
64
|
+
const cleaned = raw
|
|
65
|
+
.toLowerCase()
|
|
66
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
67
|
+
.replace(/^_+|_+$/g, "")
|
|
68
|
+
.substring(0, 60);
|
|
69
|
+
return cleaned.length > 0 ? cleaned : "migration";
|
|
70
|
+
}
|
|
71
|
+
function ensureTrailingNewline(s) {
|
|
72
|
+
return s.endsWith("\n") ? s : s + "\n";
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=write-migration-flyway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-migration-flyway.js","sourceRoot":"","sources":["../src/write-migration-flyway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAmBjC,4EAA4E;AAC5E,oEAAoE;AACpE,EAAE;AACF,2EAA2E;AAC3E,+EAA+E;AAC/E,kFAAkF;AAClF,4EAA4E;AAC5E,8EAA8E;AAC9E,gFAAgF;AAChF,4EAA4E;AAC5E,8CAA8C;AAC9C,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAuC,EACvC,IAAiC;IAEjC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,OAAO,KAAK,IAAI,MAAM,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,OAAO,KAAK,IAAI,MAAM,CAAC,CAAC;IAE5D,MAAM,SAAS,CAAC,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAClE,MAAM,SAAS,CAAC,QAAQ,EAAE,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IAEtE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,IAAI,OAAiB,CAAC;IACtB,2EAA2E;IAC3E,iFAAiF;IACjF,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS;QACtC,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG,GAAG;YAAE,GAAG,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,GAAG,GAAG,CAAC,CAAC;AACjB,CAAC;AAED,0EAA0E;AAC1E,8EAA8E;AAC9E,6DAA6D;AAC7D,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,OAAO,GAAG,GAAG;SAChB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpB,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;AACpD,CAAC;AAED,SAAS,qBAAqB,CAAC,CAAS;IACtC,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AACzC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaobjectsdev/migrate-ts",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.12-rc.1",
|
|
4
4
|
"description": "Schema migration tooling for MetaObjects: diff metadata vs DB and emit SQL for Postgres and SQLite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@iarna/toml": "^2.2.5",
|
|
48
|
-
"@metaobjectsdev/metadata": "0.20.
|
|
48
|
+
"@metaobjectsdev/metadata": "0.20.12-rc.1"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"kysely": ">=0.27.0"
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type { DriftClassification } from "./drift/classify.js";
|
|
|
18
18
|
export { emit } from "./emit/index.js";
|
|
19
19
|
export { writeMigration } from "./write-migration.js";
|
|
20
20
|
export { writeMigrationD1 } from "./write-migration-d1.js";
|
|
21
|
+
export { writeMigrationFlyway } from "./write-migration-flyway.js";
|
|
21
22
|
|
|
22
23
|
// Reference-snapshot generation (offline, deterministic).
|
|
23
24
|
export {
|
|
@@ -50,6 +51,7 @@ export type { DiffArgs } from "./diff/index.js";
|
|
|
50
51
|
export type { EmitOptions } from "./emit/index.js";
|
|
51
52
|
export type { WriteMigrationOptions, WriteMigrationResult } from "./write-migration.js";
|
|
52
53
|
export type { WriteMigrationD1Options, WriteMigrationD1Result } from "./write-migration-d1.js";
|
|
54
|
+
export type { WriteMigrationFlywayOptions, WriteMigrationFlywayResult } from "./write-migration-flyway.js";
|
|
53
55
|
|
|
54
56
|
// View-body comparison — used by the diff to detect body drift (replace-view).
|
|
55
57
|
// View DDL itself is produced by the diff + rendered by each dialect's emitter;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { mkdir, readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import type { EmitResult } from "./types.js";
|
|
4
|
+
|
|
5
|
+
export interface WriteMigrationFlywayOptions {
|
|
6
|
+
/** Flyway migrations dir (e.g. "src/main/resources/db/migration"). Created if missing. */
|
|
7
|
+
dir: string;
|
|
8
|
+
/** Human-readable slug; sanitized to lowercase + underscores. */
|
|
9
|
+
slug: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface WriteMigrationFlywayResult {
|
|
13
|
+
/** Full path to the versioned (V) migration. */
|
|
14
|
+
upPath: string;
|
|
15
|
+
/** Full path to the undo (U) migration. */
|
|
16
|
+
downPath: string;
|
|
17
|
+
/** Assigned version number (e.g. 1, 2, 11). */
|
|
18
|
+
version: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Versioned migrations ONLY. Matching [VU] here would let the undo files we
|
|
22
|
+
// ourselves emit bump the counter, skipping a version on every run.
|
|
23
|
+
//
|
|
24
|
+
// A Flyway version may have multiple parts separated by EITHER a dot or an
|
|
25
|
+
// underscore (V1.1__ and V1_0__ are both legal; the latter is version 1.0). We
|
|
26
|
+
// increment the LEADING integer, so an existing V10.5__ yields V11__. Missing the
|
|
27
|
+
// underscore form is not cosmetic: against a dir holding V1_0__init.sql the
|
|
28
|
+
// scanner would see nothing versioned, restart at V1, and Flyway — which pads
|
|
29
|
+
// versions for comparison, so 1 == 1.0 — would reject the result as a duplicate
|
|
30
|
+
// version. That is an un-appliable migration, the failure class this engine
|
|
31
|
+
// hardens against elsewhere (#226/#241/#258).
|
|
32
|
+
const VERSIONED_RE = /^V(\d+)(?:[._]\d+)*__/;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* #192 — the ADR-0015 Flyway-prefix output adapter.
|
|
36
|
+
*
|
|
37
|
+
* Emits the engine's already-computed up/down SQL in Flyway's envelope:
|
|
38
|
+
* `V<N>__<slug>.sql` plus `U<N>__<slug>.sql`. Undo is a paid Flyway edition
|
|
39
|
+
* feature — Community IGNORES `U__` files rather than failing on them — so the
|
|
40
|
+
* undo file is inert-but-correct there and becomes live on Teams/Enterprise.
|
|
41
|
+
*
|
|
42
|
+
* Applying is deliberately NOT our job here: Flyway owns apply and its
|
|
43
|
+
* `flyway_schema_history`. The CLI refuses --apply / apply-pending / --rollback
|
|
44
|
+
* under this format rather than desyncing that history.
|
|
45
|
+
*/
|
|
46
|
+
export async function writeMigrationFlyway(
|
|
47
|
+
result: Pick<EmitResult, "up" | "down">,
|
|
48
|
+
opts: WriteMigrationFlywayOptions,
|
|
49
|
+
): Promise<WriteMigrationFlywayResult> {
|
|
50
|
+
await mkdir(opts.dir, { recursive: true });
|
|
51
|
+
|
|
52
|
+
const version = await nextVersion(opts.dir);
|
|
53
|
+
const slug = sanitizeSlug(opts.slug);
|
|
54
|
+
|
|
55
|
+
const upPath = join(opts.dir, `V${version}__${slug}.sql`);
|
|
56
|
+
const downPath = join(opts.dir, `U${version}__${slug}.sql`);
|
|
57
|
+
|
|
58
|
+
await writeFile(upPath, ensureTrailingNewline(result.up), "utf8");
|
|
59
|
+
await writeFile(downPath, ensureTrailingNewline(result.down), "utf8");
|
|
60
|
+
|
|
61
|
+
return { upPath, downPath, version };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function nextVersion(dir: string): Promise<number> {
|
|
65
|
+
let entries: string[];
|
|
66
|
+
// Best-effort: dir was just mkdir'd, but in race/permission edge cases the
|
|
67
|
+
// listing can still fail; treat as empty (next version = 1) rather than rethrow.
|
|
68
|
+
try {
|
|
69
|
+
entries = await readdir(dir);
|
|
70
|
+
} catch {
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
let max = 0;
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
if (!entry.endsWith(".sql")) continue;
|
|
76
|
+
const m = VERSIONED_RE.exec(entry);
|
|
77
|
+
if (!m) continue;
|
|
78
|
+
const n = parseInt(m[1]!, 10);
|
|
79
|
+
if (n > max) max = n;
|
|
80
|
+
}
|
|
81
|
+
return max + 1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Underscores, NOT hyphens: Flyway renders a description's underscores as
|
|
85
|
+
// spaces, so V4__add_program_view.sql is the idiomatic shape. (The D1 adapter
|
|
86
|
+
// sanitizes to hyphens for Wrangler; do not copy that here.)
|
|
87
|
+
function sanitizeSlug(raw: string): string {
|
|
88
|
+
const cleaned = raw
|
|
89
|
+
.toLowerCase()
|
|
90
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
91
|
+
.replace(/^_+|_+$/g, "")
|
|
92
|
+
.substring(0, 60);
|
|
93
|
+
return cleaned.length > 0 ? cleaned : "migration";
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function ensureTrailingNewline(s: string): string {
|
|
97
|
+
return s.endsWith("\n") ? s : s + "\n";
|
|
98
|
+
}
|