@noego/proper 0.2.2 → 0.3.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/bin/cli.js +70 -45
- package/bin/cli.js.map +1 -1
- package/bin/cli.mjs +79 -47
- package/bin/cli.mjs.map +1 -1
- package/bin/index.d.mts +5 -0
- package/bin/index.d.ts +5 -0
- package/bin/index.js +70 -45
- package/bin/index.js.map +1 -1
- package/bin/index.mjs +70 -45
- package/bin/index.mjs.map +1 -1
- package/package.json +1 -1
- package/readme.md +8 -1
package/bin/index.d.mts
CHANGED
|
@@ -6,6 +6,11 @@ interface MigrationConfig {
|
|
|
6
6
|
migration_table: string;
|
|
7
7
|
migration_folder: string;
|
|
8
8
|
database: string;
|
|
9
|
+
/**
|
|
10
|
+
* Exact canonical migration keys whose historical rounded stamps are
|
|
11
|
+
* explicitly allowed. Proper remains strict for every other migration.
|
|
12
|
+
*/
|
|
13
|
+
legacy_migration_keys?: readonly string[];
|
|
9
14
|
/**
|
|
10
15
|
* Folder containing one-shot ledger patch files. Defaults to a `patches`
|
|
11
16
|
* sibling of `migration_folder` (e.g. `migrations` -> `patches`,
|
package/bin/index.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ interface MigrationConfig {
|
|
|
6
6
|
migration_table: string;
|
|
7
7
|
migration_folder: string;
|
|
8
8
|
database: string;
|
|
9
|
+
/**
|
|
10
|
+
* Exact canonical migration keys whose historical rounded stamps are
|
|
11
|
+
* explicitly allowed. Proper remains strict for every other migration.
|
|
12
|
+
*/
|
|
13
|
+
legacy_migration_keys?: readonly string[];
|
|
9
14
|
/**
|
|
10
15
|
* Folder containing one-shot ledger patch files. Defaults to a `patches`
|
|
11
16
|
* sibling of `migration_folder` (e.g. `migrations` -> `patches`,
|
package/bin/index.js
CHANGED
|
@@ -90,9 +90,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
90
90
|
// framework/MigrationRunner.ts
|
|
91
91
|
var import_fs6 = __toESM(require("fs"));
|
|
92
92
|
|
|
93
|
-
// framework/MigrationDirectoryReader.ts
|
|
94
|
-
var import_fs2 = __toESM(require("fs"));
|
|
95
|
-
|
|
96
93
|
// framework/errors.ts
|
|
97
94
|
var MigrationError = class _MigrationError extends Error {
|
|
98
95
|
constructor(message) {
|
|
@@ -295,6 +292,71 @@ var CLIError = class _CLIError extends MigrationError {
|
|
|
295
292
|
}
|
|
296
293
|
};
|
|
297
294
|
|
|
295
|
+
// framework/MigrationManifest.ts
|
|
296
|
+
var import_fs = __toESM(require("fs"));
|
|
297
|
+
var import_path = __toESM(require("path"));
|
|
298
|
+
var MIGRATION_FILE_REGEX = /(?:\.(mysql|sqlite|pg))?\.(up|down)\.(sql|js)$/i;
|
|
299
|
+
function isMigrationFile(fileName) {
|
|
300
|
+
return MIGRATION_FILE_REGEX.test(fileName);
|
|
301
|
+
}
|
|
302
|
+
function canonicalMigrationKey(value) {
|
|
303
|
+
return value.replace(MIGRATION_FILE_REGEX, "").toLowerCase();
|
|
304
|
+
}
|
|
305
|
+
function mintMigrationStamp(now = Date.now()) {
|
|
306
|
+
return now % 10 === 0 ? now + 1 : now;
|
|
307
|
+
}
|
|
308
|
+
function isHandStampedKey(key) {
|
|
309
|
+
const stamp = key.split("_")[0];
|
|
310
|
+
return /^\d+$/.test(stamp) && /000$/.test(stamp);
|
|
311
|
+
}
|
|
312
|
+
function resolveMigrationFile(directory, baseName, direction, dialect) {
|
|
313
|
+
const dialectExt = dialect === "sql" ? "mysql" : dialect;
|
|
314
|
+
const dialectFile = import_path.default.join(directory, `${baseName}.${dialectExt}.${direction}.sql`);
|
|
315
|
+
if (import_fs.default.existsSync(dialectFile)) return dialectFile;
|
|
316
|
+
const genericFile = import_path.default.join(directory, `${baseName}.${direction}.sql`);
|
|
317
|
+
if (import_fs.default.existsSync(genericFile)) return genericFile;
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
function loadMigrationManifest(directory, dialect) {
|
|
321
|
+
const manifest = /* @__PURE__ */ new Map();
|
|
322
|
+
if (!import_fs.default.existsSync(directory)) return manifest;
|
|
323
|
+
const files = import_fs.default.readdirSync(directory, { withFileTypes: true }).filter((f) => f.isFile()).map((f) => f.name).filter(isMigrationFile);
|
|
324
|
+
const uniqueKeys = /* @__PURE__ */ new Set();
|
|
325
|
+
files.forEach((file) => uniqueKeys.add(canonicalMigrationKey(file)));
|
|
326
|
+
uniqueKeys.forEach((key) => {
|
|
327
|
+
manifest.set(key, {
|
|
328
|
+
key,
|
|
329
|
+
upFile: resolveMigrationFile(directory, key, "up", dialect),
|
|
330
|
+
downFile: resolveMigrationFile(directory, key, "down", dialect)
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
return manifest;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// framework/MigrationConfig.ts
|
|
337
|
+
function validateLegacyMigrationKeys(value) {
|
|
338
|
+
if (value === void 0) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (!Array.isArray(value) || value.some((key) => !isExactCanonicalMigrationKey(key))) {
|
|
342
|
+
throw new ConfigurationError(
|
|
343
|
+
"legacy_migration_keys must be an array of nonempty exact canonical migration keys; filenames, paths, wildcards, and nonstrings are not allowed"
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function isExactCanonicalMigrationKey(value) {
|
|
348
|
+
if (typeof value !== "string" || value.length === 0 || value !== value.trim()) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
if (value.includes("/") || value.includes("\\") || ["*", "?", "[", "]", "{", "}"].some((token) => value.includes(token))) {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
return !isMigrationFile(value) && canonicalMigrationKey(value) === value;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// framework/MigrationDirectoryReader.ts
|
|
358
|
+
var import_fs2 = __toESM(require("fs"));
|
|
359
|
+
|
|
298
360
|
// framework/MigrationNode.ts
|
|
299
361
|
var MigrationNode = class {
|
|
300
362
|
constructor(name) {
|
|
@@ -426,47 +488,6 @@ var SqlMigrationBuilder = class {
|
|
|
426
488
|
}
|
|
427
489
|
};
|
|
428
490
|
|
|
429
|
-
// framework/MigrationManifest.ts
|
|
430
|
-
var import_fs = __toESM(require("fs"));
|
|
431
|
-
var import_path = __toESM(require("path"));
|
|
432
|
-
var MIGRATION_FILE_REGEX = /(?:\.(mysql|sqlite|pg))?\.(up|down)\.(sql|js)$/i;
|
|
433
|
-
function isMigrationFile(fileName) {
|
|
434
|
-
return MIGRATION_FILE_REGEX.test(fileName);
|
|
435
|
-
}
|
|
436
|
-
function canonicalMigrationKey(value) {
|
|
437
|
-
return value.replace(MIGRATION_FILE_REGEX, "").toLowerCase();
|
|
438
|
-
}
|
|
439
|
-
function mintMigrationStamp(now = Date.now()) {
|
|
440
|
-
return now % 10 === 0 ? now + 1 : now;
|
|
441
|
-
}
|
|
442
|
-
function isHandStampedKey(key) {
|
|
443
|
-
const stamp = key.split("_")[0];
|
|
444
|
-
return /^\d+$/.test(stamp) && /000$/.test(stamp);
|
|
445
|
-
}
|
|
446
|
-
function resolveMigrationFile(directory, baseName, direction, dialect) {
|
|
447
|
-
const dialectExt = dialect === "sql" ? "mysql" : dialect;
|
|
448
|
-
const dialectFile = import_path.default.join(directory, `${baseName}.${dialectExt}.${direction}.sql`);
|
|
449
|
-
if (import_fs.default.existsSync(dialectFile)) return dialectFile;
|
|
450
|
-
const genericFile = import_path.default.join(directory, `${baseName}.${direction}.sql`);
|
|
451
|
-
if (import_fs.default.existsSync(genericFile)) return genericFile;
|
|
452
|
-
return null;
|
|
453
|
-
}
|
|
454
|
-
function loadMigrationManifest(directory, dialect) {
|
|
455
|
-
const manifest = /* @__PURE__ */ new Map();
|
|
456
|
-
if (!import_fs.default.existsSync(directory)) return manifest;
|
|
457
|
-
const files = import_fs.default.readdirSync(directory, { withFileTypes: true }).filter((f) => f.isFile()).map((f) => f.name).filter(isMigrationFile);
|
|
458
|
-
const uniqueKeys = /* @__PURE__ */ new Set();
|
|
459
|
-
files.forEach((file) => uniqueKeys.add(canonicalMigrationKey(file)));
|
|
460
|
-
uniqueKeys.forEach((key) => {
|
|
461
|
-
manifest.set(key, {
|
|
462
|
-
key,
|
|
463
|
-
upFile: resolveMigrationFile(directory, key, "up", dialect),
|
|
464
|
-
downFile: resolveMigrationFile(directory, key, "down", dialect)
|
|
465
|
-
});
|
|
466
|
-
});
|
|
467
|
-
return manifest;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
491
|
// framework/MigrationDirectoryReader.ts
|
|
471
492
|
var MigrationDirectoryReader = class {
|
|
472
493
|
constructor(directory, read_strategy, sqlrunner, dialect = "sql") {
|
|
@@ -1851,6 +1872,7 @@ var MySQLMigrationRunner = class {
|
|
|
1851
1872
|
*/
|
|
1852
1873
|
this.preflightPromise = null;
|
|
1853
1874
|
this.lastPatchResults = [];
|
|
1875
|
+
validateLegacyMigrationKeys(config.legacy_migration_keys);
|
|
1854
1876
|
}
|
|
1855
1877
|
setup() {
|
|
1856
1878
|
return __async(this, null, function* () {
|
|
@@ -1956,11 +1978,13 @@ var MySQLMigrationRunner = class {
|
|
|
1956
1978
|
}
|
|
1957
1979
|
migrate(migrationNodes, forward) {
|
|
1958
1980
|
return __async(this, null, function* () {
|
|
1981
|
+
var _a;
|
|
1959
1982
|
yield this.setup();
|
|
1960
1983
|
if (forward) {
|
|
1984
|
+
const legacyMigrationKeys = new Set((_a = this.config.legacy_migration_keys) != null ? _a : []);
|
|
1961
1985
|
for (const node of migrationNodes) {
|
|
1962
1986
|
const key = node.get_key();
|
|
1963
|
-
if (isHandStampedKey(key) && !(yield node.status()).completed) {
|
|
1987
|
+
if (isHandStampedKey(key) && !legacyMigrationKeys.has(key) && !(yield node.status()).completed) {
|
|
1964
1988
|
throw new MigrationStampError(key);
|
|
1965
1989
|
}
|
|
1966
1990
|
}
|
|
@@ -2060,6 +2084,7 @@ var FileMigrationConfigReader = class {
|
|
|
2060
2084
|
try {
|
|
2061
2085
|
const fileContent = import_fs6.default.readFileSync(this.configFile);
|
|
2062
2086
|
const config = JSON.parse(fileContent.toString());
|
|
2087
|
+
validateLegacyMigrationKeys(config.legacy_migration_keys);
|
|
2063
2088
|
if (!config.migration_folder) {
|
|
2064
2089
|
throw ConfigurationError.missingRequiredProperty("migration_folder");
|
|
2065
2090
|
}
|