@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/index.mjs CHANGED
@@ -41,9 +41,6 @@ var __async = (__this, __arguments, generator) => {
41
41
  // framework/MigrationRunner.ts
42
42
  import fs6 from "fs";
43
43
 
44
- // framework/MigrationDirectoryReader.ts
45
- import fs2 from "fs";
46
-
47
44
  // framework/errors.ts
48
45
  var MigrationError = class _MigrationError extends Error {
49
46
  constructor(message) {
@@ -246,6 +243,71 @@ var CLIError = class _CLIError extends MigrationError {
246
243
  }
247
244
  };
248
245
 
246
+ // framework/MigrationManifest.ts
247
+ import fs from "fs";
248
+ import path from "path";
249
+ var MIGRATION_FILE_REGEX = /(?:\.(mysql|sqlite|pg))?\.(up|down)\.(sql|js)$/i;
250
+ function isMigrationFile(fileName) {
251
+ return MIGRATION_FILE_REGEX.test(fileName);
252
+ }
253
+ function canonicalMigrationKey(value) {
254
+ return value.replace(MIGRATION_FILE_REGEX, "").toLowerCase();
255
+ }
256
+ function mintMigrationStamp(now = Date.now()) {
257
+ return now % 10 === 0 ? now + 1 : now;
258
+ }
259
+ function isHandStampedKey(key) {
260
+ const stamp = key.split("_")[0];
261
+ return /^\d+$/.test(stamp) && /000$/.test(stamp);
262
+ }
263
+ function resolveMigrationFile(directory, baseName, direction, dialect) {
264
+ const dialectExt = dialect === "sql" ? "mysql" : dialect;
265
+ const dialectFile = path.join(directory, `${baseName}.${dialectExt}.${direction}.sql`);
266
+ if (fs.existsSync(dialectFile)) return dialectFile;
267
+ const genericFile = path.join(directory, `${baseName}.${direction}.sql`);
268
+ if (fs.existsSync(genericFile)) return genericFile;
269
+ return null;
270
+ }
271
+ function loadMigrationManifest(directory, dialect) {
272
+ const manifest = /* @__PURE__ */ new Map();
273
+ if (!fs.existsSync(directory)) return manifest;
274
+ const files = fs.readdirSync(directory, { withFileTypes: true }).filter((f) => f.isFile()).map((f) => f.name).filter(isMigrationFile);
275
+ const uniqueKeys = /* @__PURE__ */ new Set();
276
+ files.forEach((file) => uniqueKeys.add(canonicalMigrationKey(file)));
277
+ uniqueKeys.forEach((key) => {
278
+ manifest.set(key, {
279
+ key,
280
+ upFile: resolveMigrationFile(directory, key, "up", dialect),
281
+ downFile: resolveMigrationFile(directory, key, "down", dialect)
282
+ });
283
+ });
284
+ return manifest;
285
+ }
286
+
287
+ // framework/MigrationConfig.ts
288
+ function validateLegacyMigrationKeys(value) {
289
+ if (value === void 0) {
290
+ return;
291
+ }
292
+ if (!Array.isArray(value) || value.some((key) => !isExactCanonicalMigrationKey(key))) {
293
+ throw new ConfigurationError(
294
+ "legacy_migration_keys must be an array of nonempty exact canonical migration keys; filenames, paths, wildcards, and nonstrings are not allowed"
295
+ );
296
+ }
297
+ }
298
+ function isExactCanonicalMigrationKey(value) {
299
+ if (typeof value !== "string" || value.length === 0 || value !== value.trim()) {
300
+ return false;
301
+ }
302
+ if (value.includes("/") || value.includes("\\") || ["*", "?", "[", "]", "{", "}"].some((token) => value.includes(token))) {
303
+ return false;
304
+ }
305
+ return !isMigrationFile(value) && canonicalMigrationKey(value) === value;
306
+ }
307
+
308
+ // framework/MigrationDirectoryReader.ts
309
+ import fs2 from "fs";
310
+
249
311
  // framework/MigrationNode.ts
250
312
  var MigrationNode = class {
251
313
  constructor(name) {
@@ -377,47 +439,6 @@ var SqlMigrationBuilder = class {
377
439
  }
378
440
  };
379
441
 
380
- // framework/MigrationManifest.ts
381
- import fs from "fs";
382
- import path from "path";
383
- var MIGRATION_FILE_REGEX = /(?:\.(mysql|sqlite|pg))?\.(up|down)\.(sql|js)$/i;
384
- function isMigrationFile(fileName) {
385
- return MIGRATION_FILE_REGEX.test(fileName);
386
- }
387
- function canonicalMigrationKey(value) {
388
- return value.replace(MIGRATION_FILE_REGEX, "").toLowerCase();
389
- }
390
- function mintMigrationStamp(now = Date.now()) {
391
- return now % 10 === 0 ? now + 1 : now;
392
- }
393
- function isHandStampedKey(key) {
394
- const stamp = key.split("_")[0];
395
- return /^\d+$/.test(stamp) && /000$/.test(stamp);
396
- }
397
- function resolveMigrationFile(directory, baseName, direction, dialect) {
398
- const dialectExt = dialect === "sql" ? "mysql" : dialect;
399
- const dialectFile = path.join(directory, `${baseName}.${dialectExt}.${direction}.sql`);
400
- if (fs.existsSync(dialectFile)) return dialectFile;
401
- const genericFile = path.join(directory, `${baseName}.${direction}.sql`);
402
- if (fs.existsSync(genericFile)) return genericFile;
403
- return null;
404
- }
405
- function loadMigrationManifest(directory, dialect) {
406
- const manifest = /* @__PURE__ */ new Map();
407
- if (!fs.existsSync(directory)) return manifest;
408
- const files = fs.readdirSync(directory, { withFileTypes: true }).filter((f) => f.isFile()).map((f) => f.name).filter(isMigrationFile);
409
- const uniqueKeys = /* @__PURE__ */ new Set();
410
- files.forEach((file) => uniqueKeys.add(canonicalMigrationKey(file)));
411
- uniqueKeys.forEach((key) => {
412
- manifest.set(key, {
413
- key,
414
- upFile: resolveMigrationFile(directory, key, "up", dialect),
415
- downFile: resolveMigrationFile(directory, key, "down", dialect)
416
- });
417
- });
418
- return manifest;
419
- }
420
-
421
442
  // framework/MigrationDirectoryReader.ts
422
443
  var MigrationDirectoryReader = class {
423
444
  constructor(directory, read_strategy, sqlrunner, dialect = "sql") {
@@ -1802,6 +1823,7 @@ var MySQLMigrationRunner = class {
1802
1823
  */
1803
1824
  this.preflightPromise = null;
1804
1825
  this.lastPatchResults = [];
1826
+ validateLegacyMigrationKeys(config.legacy_migration_keys);
1805
1827
  }
1806
1828
  setup() {
1807
1829
  return __async(this, null, function* () {
@@ -1907,11 +1929,13 @@ var MySQLMigrationRunner = class {
1907
1929
  }
1908
1930
  migrate(migrationNodes, forward) {
1909
1931
  return __async(this, null, function* () {
1932
+ var _a;
1910
1933
  yield this.setup();
1911
1934
  if (forward) {
1935
+ const legacyMigrationKeys = new Set((_a = this.config.legacy_migration_keys) != null ? _a : []);
1912
1936
  for (const node of migrationNodes) {
1913
1937
  const key = node.get_key();
1914
- if (isHandStampedKey(key) && !(yield node.status()).completed) {
1938
+ if (isHandStampedKey(key) && !legacyMigrationKeys.has(key) && !(yield node.status()).completed) {
1915
1939
  throw new MigrationStampError(key);
1916
1940
  }
1917
1941
  }
@@ -2011,6 +2035,7 @@ var FileMigrationConfigReader = class {
2011
2035
  try {
2012
2036
  const fileContent = fs6.readFileSync(this.configFile);
2013
2037
  const config = JSON.parse(fileContent.toString());
2038
+ validateLegacyMigrationKeys(config.legacy_migration_keys);
2014
2039
  if (!config.migration_folder) {
2015
2040
  throw ConfigurationError.missingRequiredProperty("migration_folder");
2016
2041
  }