alchemy 0.42.1 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +17 -0
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/d1-migrations.d.ts +5 -2
- package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
- package/lib/cloudflare/d1-migrations.js +166 -14
- package/lib/cloudflare/d1-migrations.js.map +1 -1
- package/package.json +1 -1
- package/src/cloudflare/d1-database.ts +17 -0
- package/src/cloudflare/d1-migrations.ts +224 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-database.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1-database.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAgB,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAQ,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,UAAU,CAAC;AAIlB;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,oBAAoB;IAC3D;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,mBAAmB,CAAC,EAChB,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,GACN,MAAM,CAAC;IAEX;;;OAGG;IACH,eAAe,CAAC,EAAE;QAChB;;;;WAIG;QACH,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;KAC3B,CAAC;IAEF;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,UAAU,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAEvD;;;;OAIG;IACH,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAErD;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,GAAG,CAAC,EAAE;QACJ;;;WAGG;QACH,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,GACjB,QAAQ,IAAI,kBAAkB,CAEhC;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,wBAAwB,CAAC,GACjE,eAAe,GAAG;IAChB,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,eAAe,CAAC,EAAE;QAChB;;WAEG;QACH,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;KAC3B,CAAC;CACH,CAAC;AAEJ,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;AAExE,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,KAAK,GAAE,IAAI,CAAC,eAAe,EAAE,iBAAiB,CAAM,GACnD,OAAO,CAAC,UAAU,CAAC,CAqBrB;
|
|
1
|
+
{"version":3,"file":"d1-database.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1-database.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,6 +66,23 @@ export async function D1Database(id, props = {}) {
|
|
|
66
66
|
* });
|
|
67
67
|
*
|
|
68
68
|
* @example
|
|
69
|
+
* // Create a database with migrations using a custom migration table (compatible with Drizzle)
|
|
70
|
+
* const dbWithCustomMigrations = await D1Database("mydb", {
|
|
71
|
+
* name: "mydb",
|
|
72
|
+
* migrationsDir: "./migrations",
|
|
73
|
+
* migrationsTable: "drizzle_migrations",
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* // Create a database with custom migration table and ID column for maximum compatibility
|
|
78
|
+
* const dbWithCustomMigrations = await D1Database("mydb", {
|
|
79
|
+
* name: "mydb",
|
|
80
|
+
* migrationsDir: "./migrations",
|
|
81
|
+
* migrationsTable: "custom_migrations",
|
|
82
|
+
* migrationsIdColumn: "migration_name", // explicit column name override
|
|
83
|
+
* });
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
69
86
|
* // Clone an existing database by ID
|
|
70
87
|
* const clonedDb = await D1Database("cloned-db", {
|
|
71
88
|
* name: "cloned-db",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-database.js","sourceRoot":"","sources":["../../src/cloudflare/d1-database.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAc,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,mBAAmB,GAGpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAgG1E,MAAM,UAAU,YAAY,CAC1B,QAAkB;IAElB,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,wBAAwB,CAAC;AAC7D,CAAC;AA8CD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,EAAU,EACV,QAAkD,EAAE;IAEpD,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa;QACzC,CAAC,CAAC,MAAM,mBAAmB,CAAC,KAAK,CAAC,aAAa,CAAC;QAChD,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE;QACtC,GAAG,KAAK;QACR,eAAe;KAChB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/B,OAAO;QACL,GAAG,EAAE;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC;;WAEG;QACH,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC;AACJ,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"d1-database.js","sourceRoot":"","sources":["../../src/cloudflare/d1-database.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,11 +18,13 @@ export declare function listMigrationsFiles(migrationsDir: string): Promise<Arra
|
|
|
18
18
|
sql: string;
|
|
19
19
|
}>>;
|
|
20
20
|
/**
|
|
21
|
-
* Ensures the migrations table exists in the D1 database.
|
|
21
|
+
* Ensures the migrations table exists in the D1 database with wrangler-compatible schema.
|
|
22
|
+
* Handles migration from legacy 2-column schema to 3-column schema if needed.
|
|
22
23
|
*/
|
|
23
24
|
export declare function ensureMigrationsTable(options: D1MigrationOptions): Promise<void>;
|
|
24
25
|
/**
|
|
25
|
-
* Gets the list of applied migration
|
|
26
|
+
* Gets the list of applied migration names from the migrations table.
|
|
27
|
+
* Uses the 'name' column which contains the migration filename.
|
|
26
28
|
*/
|
|
27
29
|
export declare function getAppliedMigrations(options: D1MigrationOptions): Promise<Set<string>>;
|
|
28
30
|
/**
|
|
@@ -42,6 +44,7 @@ export declare function executeD1SQL(options: D1MigrationOptions, sql: string):
|
|
|
42
44
|
}>;
|
|
43
45
|
/**
|
|
44
46
|
* Applies all pending migrations from the provided files to the D1 database.
|
|
47
|
+
* Uses wrangler-compatible 3-column schema (id, name, applied_at).
|
|
45
48
|
*/
|
|
46
49
|
export declare function applyMigrations(options: D1MigrationOptions): Promise<void>;
|
|
47
50
|
//# sourceMappingURL=d1-migrations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-migrations.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1-migrations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,aAAa,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"d1-migrations.d.ts","sourceRoot":"","sources":["../../src/cloudflare/d1-migrations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,aAAa,CAAC;CACpB;AAyID;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAuB7C;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAStB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,kBAAkB,EAC3B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IACT,MAAM,EAAE;QACN;YACE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACxB,OAAO,EAAE,OAAO,CAAC;YACjB,IAAI,EAAE,GAAG,CAAC;SACX;KACF,CAAC;IACF,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAgBD;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiEf"}
|
|
@@ -10,6 +10,103 @@ const getPrefix = (name) => {
|
|
|
10
10
|
async function readMigrationFile(filePath) {
|
|
11
11
|
return fs.readFile(filePath, "utf-8");
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Detects the current schema of the migration table.
|
|
15
|
+
* Returns info about the table structure to determine if migration is needed.
|
|
16
|
+
*/
|
|
17
|
+
async function detectMigrationTableSchema(options) {
|
|
18
|
+
try {
|
|
19
|
+
// Check if the table exists and get its schema
|
|
20
|
+
const pragmaSQL = `PRAGMA table_info(${options.migrationsTable});`;
|
|
21
|
+
const result = await executeD1SQL(options, pragmaSQL);
|
|
22
|
+
const columns = result?.result[0]?.results || [];
|
|
23
|
+
if (columns.length === 0) {
|
|
24
|
+
return {
|
|
25
|
+
exists: false,
|
|
26
|
+
hasIdColumn: false,
|
|
27
|
+
hasNameColumn: false,
|
|
28
|
+
isLegacySchema: false,
|
|
29
|
+
columns: [],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const columnNames = columns.map((col) => col.name);
|
|
33
|
+
const hasIdColumn = columnNames.includes("id");
|
|
34
|
+
const hasNameColumn = columnNames.includes("name");
|
|
35
|
+
// Legacy schema has only 2 columns and is missing the proper 3-column structure
|
|
36
|
+
// Wrangler needs (id, name, applied_at) - if we don't have both id and name columns, it's legacy
|
|
37
|
+
const isLegacySchema = columns.length === 2 && !(hasIdColumn && hasNameColumn);
|
|
38
|
+
return {
|
|
39
|
+
exists: true,
|
|
40
|
+
hasIdColumn,
|
|
41
|
+
hasNameColumn,
|
|
42
|
+
isLegacySchema,
|
|
43
|
+
columns: columns.map((col) => ({
|
|
44
|
+
name: col.name,
|
|
45
|
+
type: col.type,
|
|
46
|
+
pk: col.pk,
|
|
47
|
+
})),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (_error) {
|
|
51
|
+
return {
|
|
52
|
+
exists: false,
|
|
53
|
+
hasIdColumn: false,
|
|
54
|
+
hasNameColumn: false,
|
|
55
|
+
isLegacySchema: false,
|
|
56
|
+
columns: [],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Migrates a legacy 2-column migration table to the wrangler-compatible 3-column format.
|
|
62
|
+
* Legacy: (id, applied_at) or (name, applied_at)
|
|
63
|
+
* New: (id, name, applied_at) where id is primary key and name is migration filename
|
|
64
|
+
*/
|
|
65
|
+
async function migrateLegacySchema(options, schema) {
|
|
66
|
+
logger.log(`Migrating legacy migration table ${options.migrationsTable} to wrangler-compatible schema...`);
|
|
67
|
+
// Determine the current primary column name (could be 'id' or something else)
|
|
68
|
+
const primaryColumn = schema.columns.find((col) => col.pk === 1)?.name || schema.columns[0]?.name;
|
|
69
|
+
if (!primaryColumn) {
|
|
70
|
+
throw new Error("Cannot migrate legacy migration table: no columns found");
|
|
71
|
+
}
|
|
72
|
+
const tempTableName = `${options.migrationsTable}_temp_migration`;
|
|
73
|
+
try {
|
|
74
|
+
// 1. Create new table with correct schema
|
|
75
|
+
const createNewTableSQL = `CREATE TABLE ${tempTableName} (
|
|
76
|
+
id TEXT PRIMARY KEY,
|
|
77
|
+
name TEXT NOT NULL,
|
|
78
|
+
applied_at TEXT NOT NULL
|
|
79
|
+
);`;
|
|
80
|
+
await executeD1SQL(options, createNewTableSQL);
|
|
81
|
+
// 2. Copy data from old table to new table
|
|
82
|
+
// Use row_number() to generate sequential IDs, and use the old primary column value as the name
|
|
83
|
+
const copyDataSQL = `
|
|
84
|
+
INSERT INTO ${tempTableName} (id, name, applied_at)
|
|
85
|
+
SELECT
|
|
86
|
+
printf('%05d', row_number() OVER (ORDER BY applied_at)) as id,
|
|
87
|
+
${primaryColumn} as name,
|
|
88
|
+
applied_at
|
|
89
|
+
FROM ${options.migrationsTable}
|
|
90
|
+
ORDER BY applied_at;
|
|
91
|
+
`;
|
|
92
|
+
await executeD1SQL(options, copyDataSQL);
|
|
93
|
+
// 3. Drop old table
|
|
94
|
+
const dropOldTableSQL = `DROP TABLE ${options.migrationsTable};`;
|
|
95
|
+
await executeD1SQL(options, dropOldTableSQL);
|
|
96
|
+
// 4. Rename new table
|
|
97
|
+
const renameTableSQL = `ALTER TABLE ${tempTableName} RENAME TO ${options.migrationsTable};`;
|
|
98
|
+
await executeD1SQL(options, renameTableSQL);
|
|
99
|
+
logger.log("Successfully migrated migration table to wrangler-compatible schema");
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
// If migration fails, try to clean up temp table
|
|
103
|
+
try {
|
|
104
|
+
await executeD1SQL(options, `DROP TABLE IF EXISTS ${tempTableName};`);
|
|
105
|
+
}
|
|
106
|
+
catch { }
|
|
107
|
+
throw new Error(`Failed to migrate legacy migration table: ${error}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
13
110
|
/**
|
|
14
111
|
* Reads migration SQL files from the migrationsDir, sorted by filename.
|
|
15
112
|
* @param migrationsDir Directory containing .sql migration files
|
|
@@ -37,20 +134,45 @@ export async function listMigrationsFiles(migrationsDir) {
|
|
|
37
134
|
return files;
|
|
38
135
|
}
|
|
39
136
|
/**
|
|
40
|
-
* Ensures the migrations table exists in the D1 database.
|
|
137
|
+
* Ensures the migrations table exists in the D1 database with wrangler-compatible schema.
|
|
138
|
+
* Handles migration from legacy 2-column schema to 3-column schema if needed.
|
|
41
139
|
*/
|
|
42
140
|
export async function ensureMigrationsTable(options) {
|
|
43
|
-
const
|
|
44
|
-
|
|
141
|
+
const schema = await detectMigrationTableSchema(options);
|
|
142
|
+
// If table doesn't exist, create it with the correct 3-column schema
|
|
143
|
+
if (!schema.exists) {
|
|
144
|
+
const createTableSQL = `CREATE TABLE ${options.migrationsTable} (
|
|
145
|
+
id TEXT PRIMARY KEY,
|
|
146
|
+
name TEXT NOT NULL,
|
|
147
|
+
applied_at TEXT NOT NULL
|
|
148
|
+
);`;
|
|
149
|
+
await executeD1SQL(options, createTableSQL);
|
|
150
|
+
logger.log(`Created migration table ${options.migrationsTable} with wrangler-compatible schema`);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
// If table has legacy schema, migrate it
|
|
154
|
+
if (schema.isLegacySchema) {
|
|
155
|
+
await migrateLegacySchema(options, schema);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// If table exists but doesn't have the correct 3-column structure, we need to handle it
|
|
159
|
+
if (!schema.hasIdColumn || !schema.hasNameColumn) {
|
|
160
|
+
logger.log(`Migration table ${options.migrationsTable} has incomplete schema - attempting migration...`);
|
|
161
|
+
await migrateLegacySchema(options, schema);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Table already has correct schema
|
|
165
|
+
logger.log(`Migration table ${options.migrationsTable} already has correct schema`);
|
|
45
166
|
}
|
|
46
167
|
/**
|
|
47
|
-
* Gets the list of applied migration
|
|
168
|
+
* Gets the list of applied migration names from the migrations table.
|
|
169
|
+
* Uses the 'name' column which contains the migration filename.
|
|
48
170
|
*/
|
|
49
171
|
export async function getAppliedMigrations(options) {
|
|
50
|
-
const sql = `SELECT
|
|
172
|
+
const sql = `SELECT name FROM ${options.migrationsTable};`;
|
|
51
173
|
const result = await executeD1SQL(options, sql);
|
|
52
|
-
const
|
|
53
|
-
return new Set(
|
|
174
|
+
const migrationNames = (result?.result[0]?.results || []).map((row) => row.name);
|
|
175
|
+
return new Set(migrationNames);
|
|
54
176
|
}
|
|
55
177
|
/**
|
|
56
178
|
* Executes a SQL statement against the D1 database using the HTTP API.
|
|
@@ -64,20 +186,50 @@ export async function executeD1SQL(options, sql) {
|
|
|
64
186
|
}
|
|
65
187
|
/**
|
|
66
188
|
* Applies all pending migrations from the provided files to the D1 database.
|
|
189
|
+
* Uses wrangler-compatible 3-column schema (id, name, applied_at).
|
|
67
190
|
*/
|
|
68
191
|
export async function applyMigrations(options) {
|
|
69
192
|
await ensureMigrationsTable(options);
|
|
70
193
|
const applied = await getAppliedMigrations(options);
|
|
194
|
+
// Determine the starting point for sequential IDs by querying existing IDs from the database
|
|
195
|
+
const existingIdsResult = await executeD1SQL(options, `SELECT id FROM ${options.migrationsTable} ORDER BY id;`);
|
|
196
|
+
const existingIds = (existingIdsResult?.result[0]?.results || []).map((row) => row.id);
|
|
197
|
+
let maxNumeric = 0;
|
|
198
|
+
for (const id of existingIds) {
|
|
199
|
+
if (/^\d+$/.test(id)) {
|
|
200
|
+
const num = Number.parseInt(id, 10);
|
|
201
|
+
maxNumeric = Math.max(maxNumeric, num);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
let nextSeq = maxNumeric + 1;
|
|
71
205
|
for (const migration of options.migrationsFiles) {
|
|
72
|
-
const
|
|
73
|
-
if (applied.has(
|
|
206
|
+
const migrationName = migration.id;
|
|
207
|
+
if (applied.has(migrationName))
|
|
74
208
|
continue;
|
|
75
|
-
// Run the migration
|
|
209
|
+
// Run the migration SQL
|
|
76
210
|
await executeD1SQL(options, migration.sql);
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
211
|
+
// Generate a migration id: prefer sequential zero-padded numeric ids (e.g. 00014)
|
|
212
|
+
// to keep consistency with legacy/imported data. If we cannot produce a numeric id
|
|
213
|
+
// (e.g. existing IDs are not numeric), fall back to a unique timestamp-based ID.
|
|
214
|
+
let migrationId;
|
|
215
|
+
if (nextSeq > 0) {
|
|
216
|
+
migrationId = nextSeq.toString().padStart(5, "0");
|
|
217
|
+
nextSeq += 1;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
migrationId =
|
|
221
|
+
Date.now().toString() + Math.random().toString(36).substr(2, 9);
|
|
222
|
+
}
|
|
223
|
+
const insertSQL = `INSERT INTO ${options.migrationsTable} (id, name, applied_at) VALUES (?, ?, datetime('now'));`;
|
|
224
|
+
// Use parameterised query to record the migration
|
|
225
|
+
const response = await options.api.post(`/accounts/${options.accountId}/d1/database/${options.databaseId}/query`, {
|
|
226
|
+
sql: insertSQL,
|
|
227
|
+
params: [migrationId, migrationName],
|
|
228
|
+
});
|
|
229
|
+
if (!response.ok) {
|
|
230
|
+
await handleApiError(response, "inserting migration record", "D1 database", options.databaseId);
|
|
231
|
+
}
|
|
232
|
+
logger.log(`Applied migration: ${migrationName}`);
|
|
81
233
|
}
|
|
82
234
|
}
|
|
83
235
|
//# sourceMappingURL=d1-migrations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-migrations.js","sourceRoot":"","sources":["../../src/cloudflare/d1-migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAWhD,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;AACxC,CAAC,CAAC;AAEF,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IAC/C,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,aAAqB;IAErB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAG,OAAO;SACrB,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACzC,IAAI,CAAC,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAE1B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,GAAG,IAAI,CAAC;QACvD,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC;QAE5B,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEL,MAAM,KAAK,GAAuC,EAAE,CAAC;IACrD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;QACpE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"d1-migrations.js","sourceRoot":"","sources":["../../src/cloudflare/d1-migrations.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -218,6 +218,23 @@ export async function D1Database(
|
|
|
218
218
|
* });
|
|
219
219
|
*
|
|
220
220
|
* @example
|
|
221
|
+
* // Create a database with migrations using a custom migration table (compatible with Drizzle)
|
|
222
|
+
* const dbWithCustomMigrations = await D1Database("mydb", {
|
|
223
|
+
* name: "mydb",
|
|
224
|
+
* migrationsDir: "./migrations",
|
|
225
|
+
* migrationsTable: "drizzle_migrations",
|
|
226
|
+
* });
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* // Create a database with custom migration table and ID column for maximum compatibility
|
|
230
|
+
* const dbWithCustomMigrations = await D1Database("mydb", {
|
|
231
|
+
* name: "mydb",
|
|
232
|
+
* migrationsDir: "./migrations",
|
|
233
|
+
* migrationsTable: "custom_migrations",
|
|
234
|
+
* migrationsIdColumn: "migration_name", // explicit column name override
|
|
235
|
+
* });
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
221
238
|
* // Clone an existing database by ID
|
|
222
239
|
* const clonedDb = await D1Database("cloned-db", {
|
|
223
240
|
* name: "cloned-db",
|
|
@@ -22,6 +22,131 @@ async function readMigrationFile(filePath: string): Promise<string> {
|
|
|
22
22
|
return fs.readFile(filePath, "utf-8");
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Detects the current schema of the migration table.
|
|
27
|
+
* Returns info about the table structure to determine if migration is needed.
|
|
28
|
+
*/
|
|
29
|
+
async function detectMigrationTableSchema(
|
|
30
|
+
options: D1MigrationOptions,
|
|
31
|
+
): Promise<{
|
|
32
|
+
exists: boolean;
|
|
33
|
+
hasIdColumn: boolean;
|
|
34
|
+
hasNameColumn: boolean;
|
|
35
|
+
isLegacySchema: boolean;
|
|
36
|
+
columns: Array<{ name: string; type: string; pk: number }>;
|
|
37
|
+
}> {
|
|
38
|
+
try {
|
|
39
|
+
// Check if the table exists and get its schema
|
|
40
|
+
const pragmaSQL = `PRAGMA table_info(${options.migrationsTable});`;
|
|
41
|
+
const result = await executeD1SQL(options, pragmaSQL);
|
|
42
|
+
const columns = result?.result[0]?.results || [];
|
|
43
|
+
|
|
44
|
+
if (columns.length === 0) {
|
|
45
|
+
return {
|
|
46
|
+
exists: false,
|
|
47
|
+
hasIdColumn: false,
|
|
48
|
+
hasNameColumn: false,
|
|
49
|
+
isLegacySchema: false,
|
|
50
|
+
columns: [],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const columnNames = columns.map((col: any) => col.name);
|
|
55
|
+
const hasIdColumn = columnNames.includes("id");
|
|
56
|
+
const hasNameColumn = columnNames.includes("name");
|
|
57
|
+
|
|
58
|
+
// Legacy schema has only 2 columns and is missing the proper 3-column structure
|
|
59
|
+
// Wrangler needs (id, name, applied_at) - if we don't have both id and name columns, it's legacy
|
|
60
|
+
const isLegacySchema =
|
|
61
|
+
columns.length === 2 && !(hasIdColumn && hasNameColumn);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
exists: true,
|
|
65
|
+
hasIdColumn,
|
|
66
|
+
hasNameColumn,
|
|
67
|
+
isLegacySchema,
|
|
68
|
+
columns: columns.map((col: any) => ({
|
|
69
|
+
name: col.name,
|
|
70
|
+
type: col.type,
|
|
71
|
+
pk: col.pk,
|
|
72
|
+
})),
|
|
73
|
+
};
|
|
74
|
+
} catch (_error) {
|
|
75
|
+
return {
|
|
76
|
+
exists: false,
|
|
77
|
+
hasIdColumn: false,
|
|
78
|
+
hasNameColumn: false,
|
|
79
|
+
isLegacySchema: false,
|
|
80
|
+
columns: [],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Migrates a legacy 2-column migration table to the wrangler-compatible 3-column format.
|
|
87
|
+
* Legacy: (id, applied_at) or (name, applied_at)
|
|
88
|
+
* New: (id, name, applied_at) where id is primary key and name is migration filename
|
|
89
|
+
*/
|
|
90
|
+
async function migrateLegacySchema(
|
|
91
|
+
options: D1MigrationOptions,
|
|
92
|
+
schema: { columns: Array<{ name: string; type: string; pk: number }> },
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
logger.log(
|
|
95
|
+
`Migrating legacy migration table ${options.migrationsTable} to wrangler-compatible schema...`,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// Determine the current primary column name (could be 'id' or something else)
|
|
99
|
+
const primaryColumn =
|
|
100
|
+
schema.columns.find((col) => col.pk === 1)?.name || schema.columns[0]?.name;
|
|
101
|
+
|
|
102
|
+
if (!primaryColumn) {
|
|
103
|
+
throw new Error("Cannot migrate legacy migration table: no columns found");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const tempTableName = `${options.migrationsTable}_temp_migration`;
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
// 1. Create new table with correct schema
|
|
110
|
+
const createNewTableSQL = `CREATE TABLE ${tempTableName} (
|
|
111
|
+
id TEXT PRIMARY KEY,
|
|
112
|
+
name TEXT NOT NULL,
|
|
113
|
+
applied_at TEXT NOT NULL
|
|
114
|
+
);`;
|
|
115
|
+
await executeD1SQL(options, createNewTableSQL);
|
|
116
|
+
|
|
117
|
+
// 2. Copy data from old table to new table
|
|
118
|
+
// Use row_number() to generate sequential IDs, and use the old primary column value as the name
|
|
119
|
+
const copyDataSQL = `
|
|
120
|
+
INSERT INTO ${tempTableName} (id, name, applied_at)
|
|
121
|
+
SELECT
|
|
122
|
+
printf('%05d', row_number() OVER (ORDER BY applied_at)) as id,
|
|
123
|
+
${primaryColumn} as name,
|
|
124
|
+
applied_at
|
|
125
|
+
FROM ${options.migrationsTable}
|
|
126
|
+
ORDER BY applied_at;
|
|
127
|
+
`;
|
|
128
|
+
await executeD1SQL(options, copyDataSQL);
|
|
129
|
+
|
|
130
|
+
// 3. Drop old table
|
|
131
|
+
const dropOldTableSQL = `DROP TABLE ${options.migrationsTable};`;
|
|
132
|
+
await executeD1SQL(options, dropOldTableSQL);
|
|
133
|
+
|
|
134
|
+
// 4. Rename new table
|
|
135
|
+
const renameTableSQL = `ALTER TABLE ${tempTableName} RENAME TO ${options.migrationsTable};`;
|
|
136
|
+
await executeD1SQL(options, renameTableSQL);
|
|
137
|
+
|
|
138
|
+
logger.log(
|
|
139
|
+
"Successfully migrated migration table to wrangler-compatible schema",
|
|
140
|
+
);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
// If migration fails, try to clean up temp table
|
|
143
|
+
try {
|
|
144
|
+
await executeD1SQL(options, `DROP TABLE IF EXISTS ${tempTableName};`);
|
|
145
|
+
} catch {}
|
|
146
|
+
throw new Error(`Failed to migrate legacy migration table: ${error}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
25
150
|
/**
|
|
26
151
|
* Reads migration SQL files from the migrationsDir, sorted by filename.
|
|
27
152
|
* @param migrationsDir Directory containing .sql migration files
|
|
@@ -54,28 +179,64 @@ export async function listMigrationsFiles(
|
|
|
54
179
|
}
|
|
55
180
|
|
|
56
181
|
/**
|
|
57
|
-
* Ensures the migrations table exists in the D1 database.
|
|
182
|
+
* Ensures the migrations table exists in the D1 database with wrangler-compatible schema.
|
|
183
|
+
* Handles migration from legacy 2-column schema to 3-column schema if needed.
|
|
58
184
|
*/
|
|
59
185
|
export async function ensureMigrationsTable(
|
|
60
186
|
options: D1MigrationOptions,
|
|
61
187
|
): Promise<void> {
|
|
62
|
-
const
|
|
188
|
+
const schema = await detectMigrationTableSchema(options);
|
|
189
|
+
|
|
190
|
+
// If table doesn't exist, create it with the correct 3-column schema
|
|
191
|
+
if (!schema.exists) {
|
|
192
|
+
const createTableSQL = `CREATE TABLE ${options.migrationsTable} (
|
|
193
|
+
id TEXT PRIMARY KEY,
|
|
194
|
+
name TEXT NOT NULL,
|
|
195
|
+
applied_at TEXT NOT NULL
|
|
196
|
+
);`;
|
|
197
|
+
await executeD1SQL(options, createTableSQL);
|
|
198
|
+
logger.log(
|
|
199
|
+
`Created migration table ${options.migrationsTable} with wrangler-compatible schema`,
|
|
200
|
+
);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
63
203
|
|
|
64
|
-
|
|
204
|
+
// If table has legacy schema, migrate it
|
|
205
|
+
if (schema.isLegacySchema) {
|
|
206
|
+
await migrateLegacySchema(options, schema);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// If table exists but doesn't have the correct 3-column structure, we need to handle it
|
|
211
|
+
if (!schema.hasIdColumn || !schema.hasNameColumn) {
|
|
212
|
+
logger.log(
|
|
213
|
+
`Migration table ${options.migrationsTable} has incomplete schema - attempting migration...`,
|
|
214
|
+
);
|
|
215
|
+
await migrateLegacySchema(options, schema);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Table already has correct schema
|
|
220
|
+
logger.log(
|
|
221
|
+
`Migration table ${options.migrationsTable} already has correct schema`,
|
|
222
|
+
);
|
|
65
223
|
}
|
|
66
224
|
|
|
67
225
|
/**
|
|
68
|
-
* Gets the list of applied migration
|
|
226
|
+
* Gets the list of applied migration names from the migrations table.
|
|
227
|
+
* Uses the 'name' column which contains the migration filename.
|
|
69
228
|
*/
|
|
70
229
|
export async function getAppliedMigrations(
|
|
71
230
|
options: D1MigrationOptions,
|
|
72
231
|
): Promise<Set<string>> {
|
|
73
|
-
const sql = `SELECT
|
|
232
|
+
const sql = `SELECT name FROM ${options.migrationsTable};`;
|
|
74
233
|
|
|
75
234
|
const result = await executeD1SQL(options, sql);
|
|
76
235
|
|
|
77
|
-
const
|
|
78
|
-
|
|
236
|
+
const migrationNames = (result?.result[0]?.results || []).map(
|
|
237
|
+
(row: any) => row.name,
|
|
238
|
+
);
|
|
239
|
+
return new Set(migrationNames);
|
|
79
240
|
}
|
|
80
241
|
|
|
81
242
|
/**
|
|
@@ -115,6 +276,7 @@ export async function executeD1SQL(
|
|
|
115
276
|
|
|
116
277
|
/**
|
|
117
278
|
* Applies all pending migrations from the provided files to the D1 database.
|
|
279
|
+
* Uses wrangler-compatible 3-column schema (id, name, applied_at).
|
|
118
280
|
*/
|
|
119
281
|
export async function applyMigrations(
|
|
120
282
|
options: D1MigrationOptions,
|
|
@@ -122,17 +284,65 @@ export async function applyMigrations(
|
|
|
122
284
|
await ensureMigrationsTable(options);
|
|
123
285
|
const applied = await getAppliedMigrations(options);
|
|
124
286
|
|
|
287
|
+
// Determine the starting point for sequential IDs by querying existing IDs from the database
|
|
288
|
+
const existingIdsResult = await executeD1SQL(
|
|
289
|
+
options,
|
|
290
|
+
`SELECT id FROM ${options.migrationsTable} ORDER BY id;`,
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
const existingIds = (existingIdsResult?.result[0]?.results || []).map(
|
|
294
|
+
(row: any) => row.id,
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
let maxNumeric = 0;
|
|
298
|
+
for (const id of existingIds) {
|
|
299
|
+
if (/^\d+$/.test(id)) {
|
|
300
|
+
const num = Number.parseInt(id, 10);
|
|
301
|
+
maxNumeric = Math.max(maxNumeric, num);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
let nextSeq = maxNumeric + 1;
|
|
305
|
+
|
|
125
306
|
for (const migration of options.migrationsFiles) {
|
|
126
|
-
const
|
|
307
|
+
const migrationName = migration.id;
|
|
127
308
|
|
|
128
|
-
if (applied.has(
|
|
309
|
+
if (applied.has(migrationName)) continue;
|
|
129
310
|
|
|
130
|
-
// Run the migration
|
|
311
|
+
// Run the migration SQL
|
|
131
312
|
await executeD1SQL(options, migration.sql);
|
|
132
|
-
// Record as applied
|
|
133
|
-
const insertSQL = `INSERT INTO ${options.migrationsTable} (id, applied_at) VALUES ('${migrationId.replace("'", "''")}', datetime('now'));`;
|
|
134
|
-
await executeD1SQL(options, insertSQL);
|
|
135
313
|
|
|
136
|
-
|
|
314
|
+
// Generate a migration id: prefer sequential zero-padded numeric ids (e.g. 00014)
|
|
315
|
+
// to keep consistency with legacy/imported data. If we cannot produce a numeric id
|
|
316
|
+
// (e.g. existing IDs are not numeric), fall back to a unique timestamp-based ID.
|
|
317
|
+
let migrationId: string;
|
|
318
|
+
if (nextSeq > 0) {
|
|
319
|
+
migrationId = nextSeq.toString().padStart(5, "0");
|
|
320
|
+
nextSeq += 1;
|
|
321
|
+
} else {
|
|
322
|
+
migrationId =
|
|
323
|
+
Date.now().toString() + Math.random().toString(36).substr(2, 9);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const insertSQL = `INSERT INTO ${options.migrationsTable} (id, name, applied_at) VALUES (?, ?, datetime('now'));`;
|
|
327
|
+
|
|
328
|
+
// Use parameterised query to record the migration
|
|
329
|
+
const response = await options.api.post(
|
|
330
|
+
`/accounts/${options.accountId}/d1/database/${options.databaseId}/query`,
|
|
331
|
+
{
|
|
332
|
+
sql: insertSQL,
|
|
333
|
+
params: [migrationId, migrationName],
|
|
334
|
+
},
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
if (!response.ok) {
|
|
338
|
+
await handleApiError(
|
|
339
|
+
response,
|
|
340
|
+
"inserting migration record",
|
|
341
|
+
"D1 database",
|
|
342
|
+
options.databaseId,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
logger.log(`Applied migration: ${migrationName}`);
|
|
137
347
|
}
|
|
138
348
|
}
|