Skip to content

Commit

Permalink
Merge 216d086 into 4906ff2
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan-knight committed May 6, 2021
2 parents 4906ff2 + 216d086 commit caa41f6
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 12 deletions.
11 changes: 10 additions & 1 deletion lib/env/config.js
@@ -1,6 +1,8 @@
const fs = require("fs-extra");
const path = require("path");
const url = require("url");
const { get } = require("lodash");
const moduleLoader = require('../utils/module-loader');

const DEFAULT_CONFIG_FILE_NAME = "migrate-mongo-config.js";

Expand Down Expand Up @@ -60,6 +62,13 @@ module.exports = {
return customConfigContent;
}
const configPath = getConfigPath();
return Promise.resolve(require(configPath)); // eslint-disable-line
try {
return Promise.resolve(moduleLoader.require(configPath));
} catch (e) {
if (e.code === 'ERR_REQUIRE_ESM') {
return (await moduleLoader.import(url.pathToFileURL(configPath))).default;
}
throw e;
}
}
};
14 changes: 12 additions & 2 deletions lib/env/migrationsDir.js
@@ -1,7 +1,9 @@
const fs = require("fs-extra");
const path = require("path");
const url = require("url");
const crypto = require("crypto");
const config = require("./config");
const moduleLoader = require('../utils/module-loader');

const DEFAULT_MIGRATIONS_DIR_NAME = "migrations";
const DEFAULT_MIGRATION_EXT = ".js";
Expand Down Expand Up @@ -94,11 +96,19 @@ module.exports = {

async loadMigration(fileName) {
const migrationsDir = await resolveMigrationsDirPath();
return require(path.join(migrationsDir, fileName)); // eslint-disable-line
const migrationPath = path.join(migrationsDir, fileName);
try {
return moduleLoader.require(migrationPath);
} catch (e) {
if (e.code === 'ERR_REQUIRE_ESM') {
return moduleLoader.import(url.pathToFileURL(migrationPath));
}
throw e;
}
},

async loadFileHash(fileName) {
const migrationsDir = await resolveMigrationsDirPath();
const migrationsDir = await resolveMigrationsDirPath();
const filePath = path.join(migrationsDir, fileName)
const hash = crypto.createHash('sha256');
const input = await fs.readFile(filePath);
Expand Down
10 changes: 10 additions & 0 deletions lib/utils/module-loader.js
@@ -0,0 +1,10 @@
module.exports = {
require(requirePath) {
return require(requirePath); // eslint-disable-line
},

/* istanbul ignore next */
import(importPath) {
return import(importPath); // eslint-disable-line
},
};
32 changes: 25 additions & 7 deletions test/env/config.test.js
Expand Up @@ -7,16 +7,27 @@ const path = require("path");
describe("config", () => {
let config; // module under test
let fs; // mocked dependencies
let moduleLoader;

function mockFs() {
return {
stat: sinon.stub()
};
}

function mockModuleLoader() {
return {
import: sinon.stub(),
};
}

beforeEach(() => {
fs = mockFs();
config = proxyquire("../../lib/env/config", { "fs-extra": fs });
moduleLoader = mockModuleLoader();
config = proxyquire("../../lib/env/config", {
"fs-extra": fs,
"../utils/module-loader": moduleLoader
});
});

describe("shouldExist()", () => {
Expand Down Expand Up @@ -98,19 +109,17 @@ describe("config", () => {
await config.read();
expect.fail("Error was not thrown");
} catch (err) {
expect(err.message).to.match(new RegExp(`Cannot find module '${configPath}'`));
expect(err.message).to.have.string(`Cannot find module '${configPath}'`);
}
});

it("should be possible to read a custom, absolute config file path", async () => {
global.options = { file: "/some/absoluete/path/to/a-config-file.js" };
global.options = { file: "/some/absolute/path/to/a-config-file.js" };
try {
await config.read();
expect.fail("Error was not thrown");
} catch (err) {
expect(err.message).to.match(
new RegExp(`Cannot find module '${global.options.file}'`)
);
expect(err.message).to.have.string(`Cannot find module '${global.options.file}'`);
}
});

Expand All @@ -121,8 +130,17 @@ describe("config", () => {
await config.read();
expect.fail("Error was not thrown");
} catch (err) {
expect(err.message).to.match(new RegExp(`Cannot find module '${configPath}'`));
expect(err.message).to.have.string(`Cannot find module '${configPath}'`);
}
});

it("should fall back to using 'import' if Node requires the use of ESM", async () => {
const error = new Error('ESM required');
error.code = 'ERR_REQUIRE_ESM';
moduleLoader.require = sinon.stub().throws(error);
moduleLoader.import.returns({});
await config.read();
expect(moduleLoader.import.called).to.equal(true);
});
});
});
21 changes: 19 additions & 2 deletions test/env/migrationsDir.test.js
Expand Up @@ -8,6 +8,7 @@ describe("migrationsDir", () => {
let migrationsDir;
let fs;
let config;
let moduleLoader;

function mockFs() {
return {
Expand All @@ -26,12 +27,20 @@ describe("migrationsDir", () => {
};
}

function mockModuleLoader() {
return {
import: sinon.stub(),
};
}

beforeEach(() => {
fs = mockFs();
config = mockConfig();
moduleLoader = mockModuleLoader();
migrationsDir = proxyquire("../../lib/env/migrationsDir", {
"fs-extra": fs,
"./config": config
"./config": config,
"../utils/module-loader": moduleLoader
});
});

Expand Down Expand Up @@ -165,9 +174,17 @@ describe("migrationsDir", () => {
await migrationsDir.loadMigration("someFile.js");
expect.fail("Error was not thrown");
} catch (err) {
expect(err.message).to.match(new RegExp(`Cannot find module '${pathToMigration}'`));
expect(err.message).to.have.string(`Cannot find module '${pathToMigration}'`);
}
});

it("should fall back to using 'import' if Node requires the use of ESM", async () => {
const error = new Error('ESM required');
error.code = 'ERR_REQUIRE_ESM';
moduleLoader.require = sinon.stub().throws(error);
await migrationsDir.loadMigration("someFile.js");
expect(moduleLoader.import.called).to.equal(true);
});
});

describe("resolveMigrationFileExtension()", () => {
Expand Down

0 comments on commit caa41f6

Please sign in to comment.