knex-migrator 6.0.0 → 6.1.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.
Files changed (3) hide show
  1. package/README.md +11 -0
  2. package/lib/utils.js +49 -13
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -42,6 +42,17 @@ The `mysql` client name is accepted for backwards compatibility and is mapped to
42
42
 
43
43
  Add `MigratorConfig.js` to the project root that will run migrations. CLI commands load this file from the current working directory by default, or from the directory passed with `--mgpath`.
44
44
 
45
+ `MigratorConfig.cjs` and `MigratorConfig.mjs` are also supported and are resolved in that order after `MigratorConfig.js`. ESM configs (`.mjs`, or `.js`/`.cjs` in a `"type": "module"` package) are loaded synchronously, so they must export the config as the `default` export and must not use top-level `await`:
46
+
47
+ ```js
48
+ // MigratorConfig.mjs
49
+ export default {
50
+ database: { /* ... */ },
51
+ migrationPath: '/path/to/project/migrations',
52
+ currentVersion: '2.0'
53
+ };
54
+ ```
55
+
45
56
  ```js
46
57
  module.exports = {
47
58
  database: {
package/lib/utils.js CHANGED
@@ -5,11 +5,39 @@ const resolve = require('util').promisify(require('resolve'));
5
5
  const debug = require('debug')('knex-migrator:utils');
6
6
  const errors = require('./errors');
7
7
 
8
+ /**
9
+ * @description The config file basenames we look for, in resolution order.
10
+ *
11
+ * `.mjs` and `.cjs` are supported alongside the historical `.js`. ESM configs
12
+ * are loaded synchronously via `require()` (Node >= 22.13 / >= 24), so they must
13
+ * not use top-level await.
14
+ */
15
+ const CONFIG_FILENAMES = ['MigratorConfig.js', 'MigratorConfig.cjs', 'MigratorConfig.mjs'];
16
+
17
+ /**
18
+ * @description Unwrap the config from a loaded module.
19
+ *
20
+ * `require()`-ing an ESM module (a `.mjs` file, or a `.js`/`.cjs` file in a
21
+ * `"type": "module"` package) returns a Module namespace object whose config
22
+ * lives on the `default` export. CommonJS modules return `module.exports`
23
+ * directly.
24
+ *
25
+ * @param {*} loaded
26
+ * @returns {*}
27
+ */
28
+ function interopConfig(loaded) {
29
+ if (loaded && loaded[Symbol.toStringTag] === 'Module' && 'default' in loaded) {
30
+ return loaded.default;
31
+ }
32
+
33
+ return loaded;
34
+ }
35
+
8
36
  /**
9
37
  * @description This helper function offers two ways of loading the knex-migrator configuration.
10
38
  *
11
39
  * 1. via JS object
12
- * 2. via file location
40
+ * 2. via file location (`MigratorConfig.js`, `MigratorConfig.cjs`, or `MigratorConfig.mjs`)
13
41
  *
14
42
  * The expected format is:
15
43
  *
@@ -27,25 +55,33 @@ module.exports.loadConfig = function loadConfig(options) {
27
55
  return options.knexMigratorConfig;
28
56
  }
29
57
 
30
- const knexMigratorFilePath = options.knexMigratorFilePath || process.cwd();
31
- const configPath = path.join(path.resolve(knexMigratorFilePath), 'MigratorConfig.js');
58
+ const knexMigratorFilePath = path.resolve(options.knexMigratorFilePath || process.cwd());
32
59
  let resolvedConfigPath;
33
60
 
34
- try {
35
- resolvedConfigPath = require.resolve(configPath);
36
- } catch (err) {
37
- if (err.code === 'MODULE_NOT_FOUND') {
38
- throw new errors.KnexMigrateError({
39
- message: 'Please provide a file named MigratorConfig.js in your project root.',
40
- help: 'Read through the README.md to see which values are expected.',
41
- });
61
+ for (const filename of CONFIG_FILENAMES) {
62
+ try {
63
+ resolvedConfigPath = require.resolve(path.join(knexMigratorFilePath, filename));
64
+ break;
65
+ } catch (err) {
66
+ // CASE: this candidate does not exist, try the next one.
67
+ if (err.code === 'MODULE_NOT_FOUND') {
68
+ continue;
69
+ }
70
+
71
+ throw new errors.KnexMigrateError({ err: err });
42
72
  }
73
+ }
43
74
 
44
- throw new errors.KnexMigrateError({ err: err });
75
+ if (!resolvedConfigPath) {
76
+ throw new errors.KnexMigrateError({
77
+ message:
78
+ 'Please provide a file named MigratorConfig.js, MigratorConfig.cjs, or MigratorConfig.mjs in your project root.',
79
+ help: 'Read through the README.md to see which values are expected.',
80
+ });
45
81
  }
46
82
 
47
83
  try {
48
- return require(resolvedConfigPath);
84
+ return interopConfig(require(resolvedConfigPath));
49
85
  } catch (err) {
50
86
  throw new errors.KnexMigrateError({ err: err });
51
87
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knex-migrator",
3
- "version": "6.0.0",
3
+ "version": "6.1.0",
4
4
  "description": "Database migrations with knex.",
5
5
  "keywords": [
6
6
  "ghost",
@@ -41,7 +41,7 @@
41
41
  "@tryghost/database-info": "2.3.1",
42
42
  "@tryghost/errors": "3.3.1",
43
43
  "@tryghost/logging": "5.1.1",
44
- "@tryghost/pro-ship": "1.1.4",
44
+ "@tryghost/pro-ship": "1.1.5",
45
45
  "@tryghost/promise": "2.3.1",
46
46
  "commander": "15.0.0",
47
47
  "compare-ver": "2.0.2",