@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 CHANGED
@@ -125,9 +125,6 @@ function migration_filter(_0) {
125
125
  // framework/MigrationRunner.ts
126
126
  var import_fs6 = __toESM(require("fs"));
127
127
 
128
- // framework/MigrationDirectoryReader.ts
129
- var import_fs2 = __toESM(require("fs"));
130
-
131
128
  // framework/errors.ts
132
129
  var MigrationError = class _MigrationError extends Error {
133
130
  constructor(message) {
@@ -330,6 +327,71 @@ var CLIError = class _CLIError extends MigrationError {
330
327
  }
331
328
  };
332
329
 
330
+ // framework/MigrationManifest.ts
331
+ var import_fs = __toESM(require("fs"));
332
+ var import_path = __toESM(require("path"));
333
+ var MIGRATION_FILE_REGEX = /(?:\.(mysql|sqlite|pg))?\.(up|down)\.(sql|js)$/i;
334
+ function isMigrationFile(fileName) {
335
+ return MIGRATION_FILE_REGEX.test(fileName);
336
+ }
337
+ function canonicalMigrationKey(value) {
338
+ return value.replace(MIGRATION_FILE_REGEX, "").toLowerCase();
339
+ }
340
+ function mintMigrationStamp(now = Date.now()) {
341
+ return now % 10 === 0 ? now + 1 : now;
342
+ }
343
+ function isHandStampedKey(key) {
344
+ const stamp = key.split("_")[0];
345
+ return /^\d+$/.test(stamp) && /000$/.test(stamp);
346
+ }
347
+ function resolveMigrationFile(directory, baseName, direction, dialect) {
348
+ const dialectExt = dialect === "sql" ? "mysql" : dialect;
349
+ const dialectFile = import_path.default.join(directory, `${baseName}.${dialectExt}.${direction}.sql`);
350
+ if (import_fs.default.existsSync(dialectFile)) return dialectFile;
351
+ const genericFile = import_path.default.join(directory, `${baseName}.${direction}.sql`);
352
+ if (import_fs.default.existsSync(genericFile)) return genericFile;
353
+ return null;
354
+ }
355
+ function loadMigrationManifest(directory, dialect) {
356
+ const manifest = /* @__PURE__ */ new Map();
357
+ if (!import_fs.default.existsSync(directory)) return manifest;
358
+ const files = import_fs.default.readdirSync(directory, { withFileTypes: true }).filter((f) => f.isFile()).map((f) => f.name).filter(isMigrationFile);
359
+ const uniqueKeys = /* @__PURE__ */ new Set();
360
+ files.forEach((file) => uniqueKeys.add(canonicalMigrationKey(file)));
361
+ uniqueKeys.forEach((key) => {
362
+ manifest.set(key, {
363
+ key,
364
+ upFile: resolveMigrationFile(directory, key, "up", dialect),
365
+ downFile: resolveMigrationFile(directory, key, "down", dialect)
366
+ });
367
+ });
368
+ return manifest;
369
+ }
370
+
371
+ // framework/MigrationConfig.ts
372
+ function validateLegacyMigrationKeys(value) {
373
+ if (value === void 0) {
374
+ return;
375
+ }
376
+ if (!Array.isArray(value) || value.some((key) => !isExactCanonicalMigrationKey(key))) {
377
+ throw new ConfigurationError(
378
+ "legacy_migration_keys must be an array of nonempty exact canonical migration keys; filenames, paths, wildcards, and nonstrings are not allowed"
379
+ );
380
+ }
381
+ }
382
+ function isExactCanonicalMigrationKey(value) {
383
+ if (typeof value !== "string" || value.length === 0 || value !== value.trim()) {
384
+ return false;
385
+ }
386
+ if (value.includes("/") || value.includes("\\") || ["*", "?", "[", "]", "{", "}"].some((token) => value.includes(token))) {
387
+ return false;
388
+ }
389
+ return !isMigrationFile(value) && canonicalMigrationKey(value) === value;
390
+ }
391
+
392
+ // framework/MigrationDirectoryReader.ts
393
+ var import_fs2 = __toESM(require("fs"));
394
+
333
395
  // framework/MigrationNode.ts
334
396
  var MigrationNode = class {
335
397
  constructor(name) {
@@ -461,47 +523,6 @@ var SqlMigrationBuilder = class {
461
523
  }
462
524
  };
463
525
 
464
- // framework/MigrationManifest.ts
465
- var import_fs = __toESM(require("fs"));
466
- var import_path = __toESM(require("path"));
467
- var MIGRATION_FILE_REGEX = /(?:\.(mysql|sqlite|pg))?\.(up|down)\.(sql|js)$/i;
468
- function isMigrationFile(fileName) {
469
- return MIGRATION_FILE_REGEX.test(fileName);
470
- }
471
- function canonicalMigrationKey(value) {
472
- return value.replace(MIGRATION_FILE_REGEX, "").toLowerCase();
473
- }
474
- function mintMigrationStamp(now = Date.now()) {
475
- return now % 10 === 0 ? now + 1 : now;
476
- }
477
- function isHandStampedKey(key) {
478
- const stamp = key.split("_")[0];
479
- return /^\d+$/.test(stamp) && /000$/.test(stamp);
480
- }
481
- function resolveMigrationFile(directory, baseName, direction, dialect) {
482
- const dialectExt = dialect === "sql" ? "mysql" : dialect;
483
- const dialectFile = import_path.default.join(directory, `${baseName}.${dialectExt}.${direction}.sql`);
484
- if (import_fs.default.existsSync(dialectFile)) return dialectFile;
485
- const genericFile = import_path.default.join(directory, `${baseName}.${direction}.sql`);
486
- if (import_fs.default.existsSync(genericFile)) return genericFile;
487
- return null;
488
- }
489
- function loadMigrationManifest(directory, dialect) {
490
- const manifest = /* @__PURE__ */ new Map();
491
- if (!import_fs.default.existsSync(directory)) return manifest;
492
- const files = import_fs.default.readdirSync(directory, { withFileTypes: true }).filter((f) => f.isFile()).map((f) => f.name).filter(isMigrationFile);
493
- const uniqueKeys = /* @__PURE__ */ new Set();
494
- files.forEach((file) => uniqueKeys.add(canonicalMigrationKey(file)));
495
- uniqueKeys.forEach((key) => {
496
- manifest.set(key, {
497
- key,
498
- upFile: resolveMigrationFile(directory, key, "up", dialect),
499
- downFile: resolveMigrationFile(directory, key, "down", dialect)
500
- });
501
- });
502
- return manifest;
503
- }
504
-
505
526
  // framework/MigrationDirectoryReader.ts
506
527
  var MigrationDirectoryReader = class {
507
528
  constructor(directory, read_strategy, sqlrunner, dialect = "sql") {
@@ -1867,6 +1888,7 @@ var MySQLMigrationRunner = class {
1867
1888
  */
1868
1889
  this.preflightPromise = null;
1869
1890
  this.lastPatchResults = [];
1891
+ validateLegacyMigrationKeys(config.legacy_migration_keys);
1870
1892
  }
1871
1893
  setup() {
1872
1894
  return __async(this, null, function* () {
@@ -1972,11 +1994,13 @@ var MySQLMigrationRunner = class {
1972
1994
  }
1973
1995
  migrate(migrationNodes, forward) {
1974
1996
  return __async(this, null, function* () {
1997
+ var _a;
1975
1998
  yield this.setup();
1976
1999
  if (forward) {
2000
+ const legacyMigrationKeys = new Set((_a = this.config.legacy_migration_keys) != null ? _a : []);
1977
2001
  for (const node of migrationNodes) {
1978
2002
  const key = node.get_key();
1979
- if (isHandStampedKey(key) && !(yield node.status()).completed) {
2003
+ if (isHandStampedKey(key) && !legacyMigrationKeys.has(key) && !(yield node.status()).completed) {
1980
2004
  throw new MigrationStampError(key);
1981
2005
  }
1982
2006
  }
@@ -2076,6 +2100,7 @@ var FileMigrationConfigReader = class {
2076
2100
  try {
2077
2101
  const fileContent = import_fs6.default.readFileSync(this.configFile);
2078
2102
  const config = JSON.parse(fileContent.toString());
2103
+ validateLegacyMigrationKeys(config.legacy_migration_keys);
2079
2104
  if (!config.migration_folder) {
2080
2105
  throw ConfigurationError.missingRequiredProperty("migration_folder");
2081
2106
  }