@noego/proper 0.0.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/bin/cli.js +1140 -0
- package/bin/cli.js.map +1 -0
- package/bin/cli.mjs +1192 -0
- package/bin/cli.mjs.map +1 -0
- package/bin/index.js +971 -0
- package/bin/index.js.map +1 -0
- package/bin/index.mjs +935 -0
- package/bin/index.mjs.map +1 -0
- package/package.json +55 -0
- package/readme.md +236 -0
package/bin/index.js
ADDED
|
@@ -0,0 +1,971 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var __async = (__this, __arguments, generator) => {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
var fulfilled = (value) => {
|
|
31
|
+
try {
|
|
32
|
+
step(generator.next(value));
|
|
33
|
+
} catch (e) {
|
|
34
|
+
reject(e);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var rejected = (value) => {
|
|
38
|
+
try {
|
|
39
|
+
step(generator.throw(value));
|
|
40
|
+
} catch (e) {
|
|
41
|
+
reject(e);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
45
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// index.ts
|
|
50
|
+
var index_exports = {};
|
|
51
|
+
__export(index_exports, {
|
|
52
|
+
MigrationRunner: () => MySQLMigrationRunner,
|
|
53
|
+
MigrationRunnerFactory: () => MigrationRunnerFactory
|
|
54
|
+
});
|
|
55
|
+
module.exports = __toCommonJS(index_exports);
|
|
56
|
+
|
|
57
|
+
// framework/MigrationRunner.ts
|
|
58
|
+
var import_fs3 = __toESM(require("fs"));
|
|
59
|
+
var import_promise = __toESM(require("mysql2/promise"));
|
|
60
|
+
var sqlite = __toESM(require("sqlite"));
|
|
61
|
+
var sqlite3 = __toESM(require("sqlite3"));
|
|
62
|
+
|
|
63
|
+
// framework/MigrationDirectoryReader.ts
|
|
64
|
+
var import_fs = __toESM(require("fs"));
|
|
65
|
+
var import_path = __toESM(require("path"));
|
|
66
|
+
|
|
67
|
+
// framework/errors.ts
|
|
68
|
+
var MigrationError = class _MigrationError extends Error {
|
|
69
|
+
constructor(message) {
|
|
70
|
+
super(message);
|
|
71
|
+
this.name = "MigrationError";
|
|
72
|
+
Object.setPrototypeOf(this, _MigrationError.prototype);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
var ConfigurationError = class _ConfigurationError extends MigrationError {
|
|
76
|
+
constructor(message) {
|
|
77
|
+
super(`Configuration Error: ${message}`);
|
|
78
|
+
this.name = "ConfigurationError";
|
|
79
|
+
Object.setPrototypeOf(this, _ConfigurationError.prototype);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Helper method for missing database configuration
|
|
83
|
+
* @param dbType The database type (e.g., 'sql', 'sqlite')
|
|
84
|
+
* @returns A ConfigurationError with appropriate message
|
|
85
|
+
*/
|
|
86
|
+
static missingDatabaseConfiguration(dbType) {
|
|
87
|
+
return new _ConfigurationError(`Missing ${dbType} configuration`);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Helper method for unknown database type
|
|
91
|
+
* @param dbType The unknown database type
|
|
92
|
+
* @returns A ConfigurationError with appropriate message
|
|
93
|
+
*/
|
|
94
|
+
static unknownDatabaseType(dbType) {
|
|
95
|
+
return new _ConfigurationError(`Unknown database type: ${dbType}`);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Helper method for missing required configuration properties
|
|
99
|
+
* @param property The name of the missing property
|
|
100
|
+
* @returns A ConfigurationError with appropriate message
|
|
101
|
+
*/
|
|
102
|
+
static missingRequiredProperty(property) {
|
|
103
|
+
return new _ConfigurationError(`Missing required property: ${property}`);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var DatabaseConnectionError = class _DatabaseConnectionError extends MigrationError {
|
|
107
|
+
constructor(message) {
|
|
108
|
+
super(`Database Connection Error: ${message}`);
|
|
109
|
+
this.name = "DatabaseConnectionError";
|
|
110
|
+
Object.setPrototypeOf(this, _DatabaseConnectionError.prototype);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Helper method for connection errors
|
|
114
|
+
* @param dbType The database type (e.g., 'sql', 'sqlite')
|
|
115
|
+
* @param details Additional error details
|
|
116
|
+
* @returns A DatabaseConnectionError with appropriate message
|
|
117
|
+
*/
|
|
118
|
+
static connectionFailed(dbType, details) {
|
|
119
|
+
const message = details ? `Failed to connect to ${dbType} database: ${details}` : `Failed to connect to ${dbType} database`;
|
|
120
|
+
return new _DatabaseConnectionError(message);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Helper method for authentication errors
|
|
124
|
+
* @param dbType The database type (e.g., 'sql', 'sqlite')
|
|
125
|
+
* @returns A DatabaseConnectionError with appropriate message
|
|
126
|
+
*/
|
|
127
|
+
static authenticationFailed(dbType) {
|
|
128
|
+
return new _DatabaseConnectionError(`Authentication failed for ${dbType} database`);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var MigrationExecutionError = class _MigrationExecutionError extends MigrationError {
|
|
132
|
+
constructor(message, migrationName, sql, originalError) {
|
|
133
|
+
let fullMessage = `Migration Execution Error${migrationName ? ` in '${migrationName}'` : ""}: ${message}`;
|
|
134
|
+
if (originalError) {
|
|
135
|
+
fullMessage += `
|
|
136
|
+
Original Error:
|
|
137
|
+
${originalError.message}`;
|
|
138
|
+
}
|
|
139
|
+
super(fullMessage);
|
|
140
|
+
this.migrationName = migrationName;
|
|
141
|
+
this.sql = sql;
|
|
142
|
+
this.originalError = originalError;
|
|
143
|
+
this.name = "MigrationExecutionError";
|
|
144
|
+
Object.setPrototypeOf(this, _MigrationExecutionError.prototype);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Helper method for SQL execution errors
|
|
148
|
+
* @param migrationName The name of the migration
|
|
149
|
+
* @param sql The SQL that caused the error
|
|
150
|
+
* @param originalError The original error thrown by the database driver
|
|
151
|
+
* @returns A MigrationExecutionError with appropriate message
|
|
152
|
+
*/
|
|
153
|
+
static sqlExecutionFailed(migrationName, sql, originalError) {
|
|
154
|
+
return new _MigrationExecutionError(
|
|
155
|
+
originalError.message,
|
|
156
|
+
migrationName,
|
|
157
|
+
sql,
|
|
158
|
+
originalError
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Helper method for missing migration file errors
|
|
163
|
+
* @param filename The missing file
|
|
164
|
+
* @returns A MigrationExecutionError with appropriate message
|
|
165
|
+
*/
|
|
166
|
+
static missingMigrationFile(filename) {
|
|
167
|
+
return new _MigrationExecutionError(`Migration file not found: ${filename}`);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Helper method for invalid migration file format errors
|
|
171
|
+
* @param filename The invalid file
|
|
172
|
+
* @param details Additional error details
|
|
173
|
+
* @returns A MigrationExecutionError with appropriate message
|
|
174
|
+
*/
|
|
175
|
+
static invalidMigrationFile(filename, details) {
|
|
176
|
+
const message = details ? `Invalid migration file format in ${filename}: ${details}` : `Invalid migration file format in ${filename}`;
|
|
177
|
+
return new _MigrationExecutionError(message);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
var CLIError = class _CLIError extends MigrationError {
|
|
181
|
+
constructor(message) {
|
|
182
|
+
super(`CLI Error: ${message}`);
|
|
183
|
+
this.name = "CLIError";
|
|
184
|
+
Object.setPrototypeOf(this, _CLIError.prototype);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Helper method for missing command errors
|
|
188
|
+
* @returns A CLIError with appropriate message
|
|
189
|
+
*/
|
|
190
|
+
static missingCommand() {
|
|
191
|
+
return new _CLIError("No command specified. Run with --help for usage information.");
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Helper method for unknown command errors
|
|
195
|
+
* @param command The unknown command
|
|
196
|
+
* @returns A CLIError with appropriate message
|
|
197
|
+
*/
|
|
198
|
+
static unknownCommand(command) {
|
|
199
|
+
return new _CLIError(`Unknown command: ${command}. Run with --help for usage information.`);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Helper method for missing required argument errors
|
|
203
|
+
* @param argument The missing argument
|
|
204
|
+
* @returns A CLIError with appropriate message
|
|
205
|
+
*/
|
|
206
|
+
static missingRequiredArgument(argument) {
|
|
207
|
+
return new _CLIError(`Missing required argument: ${argument}`);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// framework/MigrationNode.ts
|
|
212
|
+
var MigrationNode = class {
|
|
213
|
+
constructor(name) {
|
|
214
|
+
this.name = name || "";
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
var SqlMigrationNode = class extends MigrationNode {
|
|
218
|
+
constructor(conn, table, key, up_file, sql_up, down_file, sql_down) {
|
|
219
|
+
super(key);
|
|
220
|
+
this.conn = conn;
|
|
221
|
+
this.table = table;
|
|
222
|
+
this.key = key;
|
|
223
|
+
this.up_file = up_file;
|
|
224
|
+
this.sql_up = sql_up;
|
|
225
|
+
this.down_file = down_file;
|
|
226
|
+
this.sql_down = sql_down;
|
|
227
|
+
}
|
|
228
|
+
up_sql() {
|
|
229
|
+
return this.sql_up;
|
|
230
|
+
}
|
|
231
|
+
down_sql() {
|
|
232
|
+
return this.sql_down;
|
|
233
|
+
}
|
|
234
|
+
get_key() {
|
|
235
|
+
return this.key;
|
|
236
|
+
}
|
|
237
|
+
status() {
|
|
238
|
+
return __async(this, null, function* () {
|
|
239
|
+
try {
|
|
240
|
+
const result = yield this.conn.query(`
|
|
241
|
+
select *
|
|
242
|
+
from ${this.table}
|
|
243
|
+
where migration_key = ?;
|
|
244
|
+
`, [this.key]);
|
|
245
|
+
if (result.length > 0 && result[0].length > 0) {
|
|
246
|
+
return {
|
|
247
|
+
completed: true
|
|
248
|
+
};
|
|
249
|
+
} else {
|
|
250
|
+
return {
|
|
251
|
+
completed: false
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
} catch (error) {
|
|
255
|
+
throw new MigrationExecutionError(
|
|
256
|
+
`Error checking status for migration`,
|
|
257
|
+
this.key,
|
|
258
|
+
void 0,
|
|
259
|
+
error instanceof Error ? error : new Error(String(error))
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
up() {
|
|
265
|
+
return __async(this, null, function* () {
|
|
266
|
+
try {
|
|
267
|
+
yield this.conn.execute(this.sql_up);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
throw new MigrationExecutionError(
|
|
270
|
+
`Error executing UP migration`,
|
|
271
|
+
this.key,
|
|
272
|
+
this.sql_up,
|
|
273
|
+
error instanceof Error ? error : new Error(String(error))
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
yield this.conn.execute(`
|
|
278
|
+
insert into ${this.table} (migration_key,up,down)
|
|
279
|
+
values (?,?,?)
|
|
280
|
+
`, [this.key, this.up_file, this.down_file]);
|
|
281
|
+
} catch (error) {
|
|
282
|
+
throw new MigrationExecutionError(
|
|
283
|
+
`Error recording migration completion`,
|
|
284
|
+
this.key,
|
|
285
|
+
void 0,
|
|
286
|
+
error instanceof Error ? error : new Error(String(error))
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
down() {
|
|
292
|
+
return __async(this, null, function* () {
|
|
293
|
+
try {
|
|
294
|
+
yield this.conn.execute(this.sql_down);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
throw new MigrationExecutionError(
|
|
297
|
+
`Error executing DOWN migration`,
|
|
298
|
+
this.key,
|
|
299
|
+
this.sql_down,
|
|
300
|
+
error instanceof Error ? error : new Error(String(error))
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
yield this.conn.execute(`
|
|
305
|
+
delete from ${this.table}
|
|
306
|
+
where migration_key = ?
|
|
307
|
+
`, [this.key]);
|
|
308
|
+
} catch (error) {
|
|
309
|
+
throw new MigrationExecutionError(
|
|
310
|
+
`Error removing migration record`,
|
|
311
|
+
this.key,
|
|
312
|
+
void 0,
|
|
313
|
+
error instanceof Error ? error : new Error(String(error))
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// framework/SqlMigrationBuilder.ts
|
|
321
|
+
var SqlMigrationBuilder = class {
|
|
322
|
+
constructor(key) {
|
|
323
|
+
this.key = key;
|
|
324
|
+
this.up = "";
|
|
325
|
+
this.up_file = "";
|
|
326
|
+
this.down = "";
|
|
327
|
+
this.down_file = "";
|
|
328
|
+
}
|
|
329
|
+
set_up(file, up) {
|
|
330
|
+
this.up_file = file;
|
|
331
|
+
this.up = up;
|
|
332
|
+
}
|
|
333
|
+
set_down(file, down) {
|
|
334
|
+
this.down_file = file;
|
|
335
|
+
this.down = down;
|
|
336
|
+
}
|
|
337
|
+
build(table, conn) {
|
|
338
|
+
return new SqlMigrationNode(conn, table, this.key, this.up_file, this.up, this.down_file, this.down);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// framework/MigrationDirectoryReader.ts
|
|
343
|
+
var MigrationDirectoryReader = class {
|
|
344
|
+
constructor(directory, read_strategy, sqlrunner) {
|
|
345
|
+
this.directory = directory;
|
|
346
|
+
this.read_strategy = read_strategy;
|
|
347
|
+
this.sqlrunner = sqlrunner;
|
|
348
|
+
}
|
|
349
|
+
loadMigrations(table, connection) {
|
|
350
|
+
import_fs.default.existsSync(this.directory) || import_fs.default.mkdirSync(this.directory);
|
|
351
|
+
const dir_content = import_fs.default.readdirSync(this.directory, { withFileTypes: true }).filter((file) => file.isFile()).map((file) => file.name);
|
|
352
|
+
let migration_files = dir_content.map((file) => {
|
|
353
|
+
return {
|
|
354
|
+
migration_key: file.replace(/\.(up|down)\.(sql|js)/i, "").toLowerCase(),
|
|
355
|
+
directory: this.directory,
|
|
356
|
+
relative_path: import_path.default.join(this.directory, file),
|
|
357
|
+
file
|
|
358
|
+
};
|
|
359
|
+
}).sort();
|
|
360
|
+
const migration_sorter = {};
|
|
361
|
+
migration_files.forEach((migration) => {
|
|
362
|
+
const builder = migration_sorter[migration.migration_key] = migration_sorter[migration.migration_key] || new SqlMigrationBuilder(migration.migration_key);
|
|
363
|
+
this.loadMigration(builder, migration.relative_path);
|
|
364
|
+
});
|
|
365
|
+
const keys = Object.keys(migration_sorter);
|
|
366
|
+
keys.sort();
|
|
367
|
+
const built = keys.map((key) => {
|
|
368
|
+
return migration_sorter[key].build(table, this.sqlrunner);
|
|
369
|
+
});
|
|
370
|
+
return built;
|
|
371
|
+
}
|
|
372
|
+
loadMigration(builder, file) {
|
|
373
|
+
const is_sql = /sql$/i.test(file);
|
|
374
|
+
const is_js = /js$/i.test(file);
|
|
375
|
+
const is_up = /up\.(js|sql)/i.test(file);
|
|
376
|
+
const is_down = /down\.(js|sql)/i.test(file);
|
|
377
|
+
if (is_sql && is_up) {
|
|
378
|
+
const content = this.sql_up(file);
|
|
379
|
+
builder.set_up(file, content);
|
|
380
|
+
} else if (is_sql && is_down) {
|
|
381
|
+
const content = this.sql_down(file);
|
|
382
|
+
builder.set_down(file, content);
|
|
383
|
+
} else {
|
|
384
|
+
throw new Error(`Invalid migration file: ${file}`);
|
|
385
|
+
}
|
|
386
|
+
return builder;
|
|
387
|
+
}
|
|
388
|
+
sql_up(file) {
|
|
389
|
+
let content = import_fs.default.readFileSync(file).toString();
|
|
390
|
+
content = this.read_strategy(content);
|
|
391
|
+
return content.trim();
|
|
392
|
+
}
|
|
393
|
+
sql_down(file) {
|
|
394
|
+
let content = import_fs.default.readFileSync(file).toString();
|
|
395
|
+
content = this.read_strategy(content);
|
|
396
|
+
return content.trim();
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
// framework/MigrationSetup.ts
|
|
401
|
+
var import_fs2 = __toESM(require("fs"));
|
|
402
|
+
var MigrationSetup = class {
|
|
403
|
+
constructor(sqlrunner, config) {
|
|
404
|
+
this.sqlrunner = sqlrunner;
|
|
405
|
+
this.config = config;
|
|
406
|
+
}
|
|
407
|
+
setup() {
|
|
408
|
+
return __async(this, null, function* () {
|
|
409
|
+
import_fs2.default.existsSync(this.config.migration_folder) || import_fs2.default.mkdirSync(this.config.migration_folder);
|
|
410
|
+
const tableName = this.config.migration_table;
|
|
411
|
+
const createTableSql = this.config.database === "sqlite" ? `CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
412
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
413
|
+
migration_key TEXT,
|
|
414
|
+
up TEXT,
|
|
415
|
+
down TEXT,
|
|
416
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
417
|
+
)` : `CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
418
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
419
|
+
migration_key VARCHAR(255),
|
|
420
|
+
up VARCHAR(255),
|
|
421
|
+
down VARCHAR(255),
|
|
422
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
423
|
+
)`;
|
|
424
|
+
yield this.sqlrunner.query(createTableSql);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
teardown() {
|
|
428
|
+
return __async(this, null, function* () {
|
|
429
|
+
yield this.sqlrunner.execute(`DROP TABLE ${this.config.migration_table}`);
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
// framework/MigrationFilter.ts
|
|
435
|
+
function migration_filter(_0) {
|
|
436
|
+
return __async(this, arguments, function* (migrations, completed = true, keep = []) {
|
|
437
|
+
if (migrations.length === 0) {
|
|
438
|
+
return keep;
|
|
439
|
+
}
|
|
440
|
+
const [first, ...rest] = migrations;
|
|
441
|
+
const status = yield first.status();
|
|
442
|
+
if (status.completed == completed) {
|
|
443
|
+
keep.push(first);
|
|
444
|
+
}
|
|
445
|
+
return migration_filter(rest, completed, keep);
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// framework/MigrationDialectParser.ts
|
|
450
|
+
function MySqlDialectParser(sql) {
|
|
451
|
+
const lines = sql.split("\n");
|
|
452
|
+
let result = "";
|
|
453
|
+
let isInMySQLBlock = true;
|
|
454
|
+
const startSQLRegex = /^\s*--\s*\[\s*(sql|mysql)\s*\]\s*$/i;
|
|
455
|
+
const anyDialectRegex = /^\s*--\s*\[\s*\w+\s*\]\s*$/i;
|
|
456
|
+
for (const line of lines) {
|
|
457
|
+
const trimmed = line.trim();
|
|
458
|
+
if (startSQLRegex.test(trimmed)) {
|
|
459
|
+
isInMySQLBlock = true;
|
|
460
|
+
result += line + "\n";
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
if (anyDialectRegex.test(trimmed) && !startSQLRegex.test(trimmed)) {
|
|
464
|
+
isInMySQLBlock = false;
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
if (!isInMySQLBlock && line.toLowerCase().includes("create index")) {
|
|
468
|
+
isInMySQLBlock = true;
|
|
469
|
+
}
|
|
470
|
+
if (isInMySQLBlock) {
|
|
471
|
+
result += line + "\n";
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return result;
|
|
475
|
+
}
|
|
476
|
+
function SqliteDialectParser(sql) {
|
|
477
|
+
const lines = sql.split("\n");
|
|
478
|
+
let result = "";
|
|
479
|
+
let isInSqliteBlock = true;
|
|
480
|
+
const startSqliteRegex = /^\s*--\s*\[\s*sqlite\s*\]\s*$/i;
|
|
481
|
+
const anyDialectRegex = /^\s*--\s*\[\s*\w+\s*\]\s*$/i;
|
|
482
|
+
for (const line of lines) {
|
|
483
|
+
const trimmed = line.trim();
|
|
484
|
+
if (startSqliteRegex.test(trimmed)) {
|
|
485
|
+
isInSqliteBlock = true;
|
|
486
|
+
result += line + "\n";
|
|
487
|
+
continue;
|
|
488
|
+
} else if (anyDialectRegex.test(trimmed) && !startSqliteRegex.test(trimmed)) {
|
|
489
|
+
isInSqliteBlock = false;
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
if (!isInSqliteBlock && line.toLowerCase().includes("create index")) {
|
|
493
|
+
isInSqliteBlock = true;
|
|
494
|
+
}
|
|
495
|
+
if (isInSqliteBlock) {
|
|
496
|
+
result += line + "\n";
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return result;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// framework/SQLRunner.ts
|
|
503
|
+
var BaseSQLRunner = class {
|
|
504
|
+
/**
|
|
505
|
+
* Ensures that both MySQL and SQLite return the same tuple shape that callers
|
|
506
|
+
* expect: `[rowsOrResult, extra]`. For SQLite there is no `extra` metadata
|
|
507
|
+
* comparable to MySQL's `FieldPacket[]`, so we just use `undefined`.
|
|
508
|
+
*/
|
|
509
|
+
query(_0) {
|
|
510
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
511
|
+
const result = yield this._query(sql, params);
|
|
512
|
+
return Array.isArray(result) && result.length === 2 ? result : [result, void 0];
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
execute(_0) {
|
|
516
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
517
|
+
const result = yield this._execute(sql, params);
|
|
518
|
+
return Array.isArray(result) && result.length === 2 ? result : [result, void 0];
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
end() {
|
|
522
|
+
return __async(this, null, function* () {
|
|
523
|
+
yield this._end();
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
var SQLRunner = class extends BaseSQLRunner {
|
|
528
|
+
constructor(connection) {
|
|
529
|
+
super();
|
|
530
|
+
this.connection = connection;
|
|
531
|
+
}
|
|
532
|
+
// The MySQL driver already returns the correct tuple shapes.
|
|
533
|
+
_query(_0) {
|
|
534
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
535
|
+
return yield this.connection.query(sql, params);
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
_execute(_0) {
|
|
539
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
540
|
+
return yield this.connection.execute(sql, params);
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
_end() {
|
|
544
|
+
return __async(this, null, function* () {
|
|
545
|
+
if (this.connection) {
|
|
546
|
+
yield this.connection.end();
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
var SQLiteRunner = class extends BaseSQLRunner {
|
|
552
|
+
constructor(connection) {
|
|
553
|
+
super();
|
|
554
|
+
this.connection = connection;
|
|
555
|
+
}
|
|
556
|
+
_query(_0) {
|
|
557
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
558
|
+
const stmt = yield this.connection.prepare(sql);
|
|
559
|
+
try {
|
|
560
|
+
const rows = yield stmt.all(...params);
|
|
561
|
+
return rows;
|
|
562
|
+
} finally {
|
|
563
|
+
yield stmt.finalize();
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
_execute(_0) {
|
|
568
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
569
|
+
if (this.isMultiStatement(sql)) {
|
|
570
|
+
return yield this.executeMultiStatement(sql, params).catch((err) => {
|
|
571
|
+
console.error(`Error executing multi-statement SQL:
|
|
572
|
+
${sql}
|
|
573
|
+
`, err);
|
|
574
|
+
throw err;
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
const stmt = yield this.connection.prepare(sql);
|
|
578
|
+
try {
|
|
579
|
+
const info = yield stmt.run(...params);
|
|
580
|
+
return info;
|
|
581
|
+
} finally {
|
|
582
|
+
yield stmt.finalize();
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
isMultiStatement(sql) {
|
|
587
|
+
return sql.split(";").length > 1;
|
|
588
|
+
}
|
|
589
|
+
executeMultiStatement(_0) {
|
|
590
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
591
|
+
const statements = sql.split(";").map(
|
|
592
|
+
(s) => s.split("\n").map(
|
|
593
|
+
(s2) => this.removeComments(s2)
|
|
594
|
+
).filter((s2) => s2.trim() != "").join("\n")
|
|
595
|
+
).filter((s) => s.trim() !== "");
|
|
596
|
+
const infos = yield statements.reduce((prev, statement) => __async(this, null, function* () {
|
|
597
|
+
const infos2 = yield prev;
|
|
598
|
+
const stmt = yield this.connection.prepare(`${statement};`);
|
|
599
|
+
try {
|
|
600
|
+
const info = yield stmt.run(...params);
|
|
601
|
+
infos2.push(info);
|
|
602
|
+
return infos2;
|
|
603
|
+
} finally {
|
|
604
|
+
yield stmt.finalize();
|
|
605
|
+
}
|
|
606
|
+
}), Promise.resolve([null])).then((infos2) => {
|
|
607
|
+
return infos2.filter((info) => info !== null);
|
|
608
|
+
});
|
|
609
|
+
return infos.reduce((acc, latest) => {
|
|
610
|
+
if (latest) {
|
|
611
|
+
acc.stmt = latest.stmt;
|
|
612
|
+
acc.lastID = latest.lastID;
|
|
613
|
+
acc.changes += latest.changes;
|
|
614
|
+
}
|
|
615
|
+
return acc;
|
|
616
|
+
});
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
removeComments(sql) {
|
|
620
|
+
sql = sql.replace(/--.*$/gm, "");
|
|
621
|
+
return sql;
|
|
622
|
+
}
|
|
623
|
+
_end() {
|
|
624
|
+
return __async(this, null, function* () {
|
|
625
|
+
if (this.connection) {
|
|
626
|
+
yield this.connection.close();
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// framework/MigrationRunner.ts
|
|
633
|
+
function toError(error) {
|
|
634
|
+
if (error instanceof Error) return error;
|
|
635
|
+
return new Error(String(error));
|
|
636
|
+
}
|
|
637
|
+
var MigrationRunnerFactory = class _MigrationRunnerFactory {
|
|
638
|
+
static create(configFile, conn) {
|
|
639
|
+
return __async(this, null, function* () {
|
|
640
|
+
const configReader = new FileMigrationConfigReader(configFile);
|
|
641
|
+
const config = configReader.loadFile();
|
|
642
|
+
if (!conn) {
|
|
643
|
+
conn = yield this.createConnection(config);
|
|
644
|
+
}
|
|
645
|
+
return new _MigrationRunnerFactory().create(config, conn);
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
static createConnection(config) {
|
|
649
|
+
return __async(this, null, function* () {
|
|
650
|
+
let conn = null;
|
|
651
|
+
switch (config.database) {
|
|
652
|
+
case "sql":
|
|
653
|
+
if (!config.sql) {
|
|
654
|
+
throw ConfigurationError.missingDatabaseConfiguration("sql");
|
|
655
|
+
}
|
|
656
|
+
const settings = Object.assign({
|
|
657
|
+
password: process.env.SQL_PASSWORD
|
|
658
|
+
}, config.sql);
|
|
659
|
+
try {
|
|
660
|
+
conn = yield import_promise.default.createConnection(settings);
|
|
661
|
+
return conn;
|
|
662
|
+
} catch (error) {
|
|
663
|
+
throw DatabaseConnectionError.connectionFailed("sql", toError(error).message);
|
|
664
|
+
}
|
|
665
|
+
case "sqlite":
|
|
666
|
+
if (!config.sqlite) {
|
|
667
|
+
throw ConfigurationError.missingDatabaseConfiguration("sqlite");
|
|
668
|
+
}
|
|
669
|
+
try {
|
|
670
|
+
conn = yield sqlite.open({
|
|
671
|
+
filename: config.sqlite.database,
|
|
672
|
+
driver: sqlite3.Database
|
|
673
|
+
});
|
|
674
|
+
return conn;
|
|
675
|
+
} catch (error) {
|
|
676
|
+
throw DatabaseConnectionError.connectionFailed("sqlite", toError(error).message);
|
|
677
|
+
}
|
|
678
|
+
default:
|
|
679
|
+
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
static createEmpty(configFile) {
|
|
684
|
+
return __async(this, null, function* () {
|
|
685
|
+
const configReader = new FileMigrationConfigReader(configFile);
|
|
686
|
+
const config = configReader.loadFile();
|
|
687
|
+
return new _MigrationRunnerFactory().createEmpty(config);
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
create(config, conn) {
|
|
691
|
+
return __async(this, null, function* () {
|
|
692
|
+
let sqlrunner;
|
|
693
|
+
switch (config.database) {
|
|
694
|
+
case "sql":
|
|
695
|
+
sqlrunner = new SQLRunner(conn);
|
|
696
|
+
break;
|
|
697
|
+
case "sqlite":
|
|
698
|
+
sqlrunner = new SQLiteRunner(conn);
|
|
699
|
+
break;
|
|
700
|
+
default:
|
|
701
|
+
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
702
|
+
}
|
|
703
|
+
const setup = new MigrationSetup(sqlrunner, config);
|
|
704
|
+
const read_strategy = this.getReadStategy(config);
|
|
705
|
+
const migration_files = new MigrationDirectoryReader(config.migration_folder, read_strategy, sqlrunner);
|
|
706
|
+
yield setup.setup();
|
|
707
|
+
return new MySQLMigrationRunner(config, migration_files, setup, sqlrunner, conn);
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
createEmpty(config) {
|
|
711
|
+
return __async(this, null, function* () {
|
|
712
|
+
const conn = null;
|
|
713
|
+
let sqlrunner;
|
|
714
|
+
switch (config.database) {
|
|
715
|
+
case "sql":
|
|
716
|
+
sqlrunner = new SQLRunner(conn);
|
|
717
|
+
break;
|
|
718
|
+
case "sqlite":
|
|
719
|
+
sqlrunner = new SQLiteRunner(conn);
|
|
720
|
+
break;
|
|
721
|
+
default:
|
|
722
|
+
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
723
|
+
}
|
|
724
|
+
const setup = new MigrationSetup(sqlrunner, config);
|
|
725
|
+
const read_strategy = this.getReadStategy(config);
|
|
726
|
+
const migration_files = new MigrationDirectoryReader(config.migration_folder, read_strategy, sqlrunner);
|
|
727
|
+
return new MySQLMigrationRunner(config, migration_files, setup, sqlrunner, conn);
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
getReadStategy(config) {
|
|
731
|
+
switch (config.database) {
|
|
732
|
+
case "sql":
|
|
733
|
+
return MySqlDialectParser;
|
|
734
|
+
case "sqlite":
|
|
735
|
+
return SqliteDialectParser;
|
|
736
|
+
default:
|
|
737
|
+
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
var MySQLMigrationRunner = class {
|
|
742
|
+
constructor(config, directory, setupRunner, sqlrunner, connection) {
|
|
743
|
+
this.config = config;
|
|
744
|
+
this.directory = directory;
|
|
745
|
+
this.setupRunner = setupRunner;
|
|
746
|
+
this.sqlrunner = sqlrunner;
|
|
747
|
+
this.connection = connection;
|
|
748
|
+
}
|
|
749
|
+
setup() {
|
|
750
|
+
return __async(this, null, function* () {
|
|
751
|
+
try {
|
|
752
|
+
yield this.setupRunner.setup();
|
|
753
|
+
} catch (error) {
|
|
754
|
+
throw new MigrationExecutionError("Failed to set up migration database", void 0, void 0, toError(error));
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
terminate() {
|
|
759
|
+
return __async(this, null, function* () {
|
|
760
|
+
try {
|
|
761
|
+
yield this.setupRunner.teardown();
|
|
762
|
+
} catch (error) {
|
|
763
|
+
throw new MigrationExecutionError("Failed to tear down migration database", void 0, void 0, toError(error));
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
getMigrationsHistory() {
|
|
768
|
+
return __async(this, null, function* () {
|
|
769
|
+
try {
|
|
770
|
+
const results = yield this.sqlrunner.query(`
|
|
771
|
+
select *
|
|
772
|
+
from ${this.config.migration_table}
|
|
773
|
+
`);
|
|
774
|
+
return results[0];
|
|
775
|
+
} catch (error) {
|
|
776
|
+
throw new MigrationExecutionError("Failed to get migration history", void 0, void 0, toError(error));
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
getMigrations() {
|
|
781
|
+
return __async(this, null, function* () {
|
|
782
|
+
try {
|
|
783
|
+
return this.directory.loadMigrations(this.config.migration_table, this.connection);
|
|
784
|
+
} catch (error) {
|
|
785
|
+
throw new MigrationExecutionError("Failed to load migrations", void 0, void 0, toError(error));
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
getPendingMigrations() {
|
|
790
|
+
return __async(this, null, function* () {
|
|
791
|
+
try {
|
|
792
|
+
const migrations = yield this.getMigrations();
|
|
793
|
+
return migration_filter(migrations, false);
|
|
794
|
+
} catch (error) {
|
|
795
|
+
if (error instanceof MigrationExecutionError) {
|
|
796
|
+
throw error;
|
|
797
|
+
}
|
|
798
|
+
throw new MigrationExecutionError("Failed to get pending migrations", void 0, void 0, toError(error));
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
getCompletedMigrations() {
|
|
803
|
+
return __async(this, null, function* () {
|
|
804
|
+
try {
|
|
805
|
+
const migrations = yield this.getMigrations();
|
|
806
|
+
return migration_filter(migrations, true);
|
|
807
|
+
} catch (error) {
|
|
808
|
+
if (error instanceof MigrationExecutionError) {
|
|
809
|
+
throw error;
|
|
810
|
+
}
|
|
811
|
+
throw new MigrationExecutionError("Failed to get completed migrations", void 0, void 0, toError(error));
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
migrate(migrationNodes, forward) {
|
|
816
|
+
return __async(this, null, function* () {
|
|
817
|
+
for (let node of migrationNodes) {
|
|
818
|
+
try {
|
|
819
|
+
if (forward) {
|
|
820
|
+
yield node.up();
|
|
821
|
+
} else {
|
|
822
|
+
yield node.down();
|
|
823
|
+
}
|
|
824
|
+
} catch (error) {
|
|
825
|
+
throw new MigrationExecutionError(
|
|
826
|
+
`Failed to ${forward ? "apply" : "rollback"} migration`,
|
|
827
|
+
node.name || String(node),
|
|
828
|
+
forward ? node.up_sql() : node.down_sql(),
|
|
829
|
+
toError(error)
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
reset() {
|
|
836
|
+
return __async(this, null, function* () {
|
|
837
|
+
try {
|
|
838
|
+
let migrations = yield this.getMigrations();
|
|
839
|
+
const rollback = yield migration_filter(migrations, true);
|
|
840
|
+
yield this.migrate(rollback.reverse(), false);
|
|
841
|
+
migrations = yield this.getMigrations();
|
|
842
|
+
const rollforward = yield migration_filter(migrations, false);
|
|
843
|
+
yield this.migrate(rollforward, true);
|
|
844
|
+
} catch (error) {
|
|
845
|
+
if (error instanceof MigrationExecutionError) {
|
|
846
|
+
throw error;
|
|
847
|
+
}
|
|
848
|
+
throw new MigrationExecutionError("Failed to reset migrations", void 0, void 0, toError(error));
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
createMigration(name) {
|
|
853
|
+
try {
|
|
854
|
+
const creator = new MigrationCreator(this.config);
|
|
855
|
+
creator.create(name);
|
|
856
|
+
} catch (error) {
|
|
857
|
+
throw new MigrationExecutionError(`Failed to create migration: ${name}`, void 0, void 0, toError(error));
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
close() {
|
|
861
|
+
return __async(this, null, function* () {
|
|
862
|
+
if (this.sqlrunner) {
|
|
863
|
+
try {
|
|
864
|
+
yield this.sqlrunner.end();
|
|
865
|
+
} catch (error) {
|
|
866
|
+
throw new DatabaseConnectionError(`Failed to close database connection: ${toError(error).message}`);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
init(config_file) {
|
|
872
|
+
return __async(this, null, function* () {
|
|
873
|
+
try {
|
|
874
|
+
console.log(`Checking for ${config_file}`);
|
|
875
|
+
const config_exist = import_fs3.default.existsSync(config_file);
|
|
876
|
+
if (!config_exist) {
|
|
877
|
+
console.log(`Creating ${config_file}`);
|
|
878
|
+
const default_config = {
|
|
879
|
+
"migration_folder": "migrations",
|
|
880
|
+
"migration_table": "proper_migrations",
|
|
881
|
+
"database": "sql",
|
|
882
|
+
"sql": {
|
|
883
|
+
"host": "localhost",
|
|
884
|
+
"user": "root",
|
|
885
|
+
"database": "proper",
|
|
886
|
+
"password": ""
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
import_fs3.default.writeFileSync(config_file, JSON.stringify(default_config, null, 2));
|
|
890
|
+
console.log(`Created ${config_file}`);
|
|
891
|
+
}
|
|
892
|
+
} catch (error) {
|
|
893
|
+
throw new ConfigurationError(`Failed to initialize config file: ${toError(error).message}`);
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
};
|
|
898
|
+
var FileMigrationConfigReader = class {
|
|
899
|
+
constructor(configFile) {
|
|
900
|
+
this.configFile = configFile;
|
|
901
|
+
}
|
|
902
|
+
loadFile() {
|
|
903
|
+
try {
|
|
904
|
+
const fileContent = import_fs3.default.readFileSync(this.configFile);
|
|
905
|
+
const config = JSON.parse(fileContent.toString());
|
|
906
|
+
if (!config.migration_folder) {
|
|
907
|
+
throw ConfigurationError.missingRequiredProperty("migration_folder");
|
|
908
|
+
}
|
|
909
|
+
if (!config.migration_table) {
|
|
910
|
+
throw ConfigurationError.missingRequiredProperty("migration_table");
|
|
911
|
+
}
|
|
912
|
+
if (!config.database) {
|
|
913
|
+
if (config.sql) {
|
|
914
|
+
config.database = "sql";
|
|
915
|
+
} else if (config.sqlite) {
|
|
916
|
+
config.database = "sqlite";
|
|
917
|
+
} else {
|
|
918
|
+
throw ConfigurationError.missingRequiredProperty("database");
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return config;
|
|
922
|
+
} catch (error) {
|
|
923
|
+
if (error instanceof ConfigurationError) {
|
|
924
|
+
throw error;
|
|
925
|
+
}
|
|
926
|
+
const err = toError(error);
|
|
927
|
+
if (err.message.includes("ENOENT")) {
|
|
928
|
+
throw new ConfigurationError(`Config file not found: ${this.configFile}`);
|
|
929
|
+
}
|
|
930
|
+
throw new ConfigurationError(`Failed to load config file: ${err.message}`);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
var MigrationCreator = class {
|
|
935
|
+
constructor(config) {
|
|
936
|
+
this.config = config;
|
|
937
|
+
}
|
|
938
|
+
create(name) {
|
|
939
|
+
if (!name) {
|
|
940
|
+
throw new CLIError("Migration name is required");
|
|
941
|
+
}
|
|
942
|
+
try {
|
|
943
|
+
if (!import_fs3.default.existsSync(this.config.migration_folder)) {
|
|
944
|
+
import_fs3.default.mkdirSync(this.config.migration_folder, { recursive: true });
|
|
945
|
+
}
|
|
946
|
+
const now_timestamp = Date.now();
|
|
947
|
+
const filename_up = `${now_timestamp}_${name}.up.sql`;
|
|
948
|
+
const filename_down = `${now_timestamp}_${name}.down.sql`;
|
|
949
|
+
import_fs3.default.writeFileSync(`${this.config.migration_folder}/${filename_up}`, `
|
|
950
|
+
-- Write your up migration here
|
|
951
|
+
`.trim());
|
|
952
|
+
import_fs3.default.writeFileSync(`${this.config.migration_folder}/${filename_down}`, `
|
|
953
|
+
-- Write your down migration here
|
|
954
|
+
`.trim());
|
|
955
|
+
console.log(`Created migration files:`);
|
|
956
|
+
console.log(` ${filename_up}`);
|
|
957
|
+
console.log(` ${filename_down}`);
|
|
958
|
+
} catch (error) {
|
|
959
|
+
if (error instanceof CLIError) {
|
|
960
|
+
throw error;
|
|
961
|
+
}
|
|
962
|
+
throw new MigrationExecutionError(`Failed to create migration files: ${toError(error).message}`);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
};
|
|
966
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
967
|
+
0 && (module.exports = {
|
|
968
|
+
MigrationRunner,
|
|
969
|
+
MigrationRunnerFactory
|
|
970
|
+
});
|
|
971
|
+
//# sourceMappingURL=index.js.map
|