From 836f6ab7541b49776e23f143209257d9d0b18004 Mon Sep 17 00:00:00 2001 From: Pagan Gazzard Date: Mon, 21 Nov 2022 20:07:46 +0000 Subject: [PATCH] Enable node16 module resolution in tsconfig to ease the ESM transition This means that dynamic import statements will emit actual `import` statements rather than being translated to `require`, the benefit being that we can now import ES modules via dynamic imports Change-type: patch --- src/types/basic.ts | 2 +- test/integration/config.spec.ts | 41 +++++++++++++++++-------------- test/integration/db.spec.ts | 11 ++++++--- test/legacy/10-api-binder.spec.ts | 5 ++-- test/legacy/11-logger.spec.ts | 2 +- tsconfig.json | 1 + 6 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/types/basic.ts b/src/types/basic.ts index 147a4339..29890a7f 100644 --- a/src/types/basic.ts +++ b/src/types/basic.ts @@ -1,6 +1,6 @@ import * as t from 'io-ts'; import { chain, fold, isRight, left, right, Either } from 'fp-ts/lib/Either'; -import { pipe, flow } from 'fp-ts/function'; +import { pipe, flow } from 'fp-ts/lib/function'; /** * A short string is a non null string between diff --git a/test/integration/config.spec.ts b/test/integration/config.spec.ts index 9ea7bbd5..ecdc3dc0 100644 --- a/test/integration/config.spec.ts +++ b/test/integration/config.spec.ts @@ -9,6 +9,9 @@ import * as hostUtils from '~/lib/host-utils'; import constants = require('~/lib/constants'); import { fnSchema } from '~/src/config/functions'; +// Utility method to use along with `require` +type Config = typeof import('~/src/config'); + describe('config', () => { const configJsonPath = path.join( constants.rootMountPoint, @@ -42,7 +45,7 @@ describe('config', () => { }); it('reads and exposes values from config.json', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const configJson = await readConfigJson(); const id = await config.get('applicationId'); @@ -50,7 +53,7 @@ describe('config', () => { }); it('allows reading several values in one getMany call', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const configJson = await readConfigJson(); return expect( @@ -62,7 +65,7 @@ describe('config', () => { }); it('generates a uuid and stores it in config.json', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const configJson = await readConfigJson(); const uuid = await config.get('uuid'); @@ -72,14 +75,14 @@ describe('config', () => { }); it('does not allow setting an immutable field', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); return expect(config.set({ deviceType: 'a different device type' })).to.be .rejected; }); it('allows setting both config.json and database fields transparently', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); await config.set({ appUpdatePollInterval: 30000, @@ -93,7 +96,7 @@ describe('config', () => { }); it('allows deleting a config.json key and returns a default value if none is set', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); await config.remove('appUpdatePollInterval'); const poll = await config.get('appUpdatePollInterval'); @@ -101,7 +104,7 @@ describe('config', () => { }); it('allows deleting a config.json key if it is null', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); await config.set({ apiKey: null }); const key = await config.get('apiKey'); @@ -114,7 +117,7 @@ describe('config', () => { }); it('does not allow modifying or removing a function value', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); // We have to cast to any below, as the type system will // not allow removing a function value @@ -123,13 +126,13 @@ describe('config', () => { }); it('throws when asked for an unknown key', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); await expect(config.get('unknownInvalidValue' as any)).to.be.rejected; }); it('emits a change event when values change', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const listener = stub(); config.on('change', listener); @@ -156,7 +159,7 @@ describe('config', () => { ), }).enable(); - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); await config.set({ developmentMode: false }); @@ -167,7 +170,7 @@ describe('config', () => { }); it('reads and exposes MAC addresses', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const macAddress = await config.get('macAddress'); expect(macAddress).to.have.length.greaterThan(0); @@ -175,13 +178,13 @@ describe('config', () => { describe('Function config providers', () => { it('should throw if a non-mutable function provider is set', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); await expect(config.set({ version: 'some-version' })).to.be.rejected; }); it('should throw if a non-mutable function provider is removed', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); await expect(config.remove('version' as any)).to.be.rejected; }); @@ -196,7 +199,7 @@ describe('config', () => { it('should obtain deviceArch from device-type.json', async () => { const dtJson = await readDeviceTypeJson(); - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const deviceArch = await config.get('deviceArch'); @@ -205,7 +208,7 @@ describe('config', () => { it('should obtain deviceType from device-type.json', async () => { const dtJson = await readDeviceTypeJson(); - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const deviceArch = await config.get('deviceType'); @@ -213,7 +216,7 @@ describe('config', () => { }); it('should memoize values from device-type.json', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const dtJson = await readDeviceTypeJson(); spy(hostUtils, 'readFromBoot'); @@ -240,7 +243,7 @@ describe('config', () => { }); it('should not memoize errors when reading deviceArch', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const tfs = await testfs({}, { keep: [deviceTypeJsonPath] }).enable(); @@ -260,7 +263,7 @@ describe('config', () => { }); it('should not memoize errors when reading deviceType', async () => { - const config = await import('~/src/config'); + const config = require('~/src/config') as Config; await config.initialized(); const tfs = await testfs({}, { keep: [deviceTypeJsonPath] }).enable(); diff --git a/test/integration/db.spec.ts b/test/integration/db.spec.ts index d8790201..1374835c 100644 --- a/test/integration/db.spec.ts +++ b/test/integration/db.spec.ts @@ -48,13 +48,16 @@ async function restoreDb() { delete require.cache[require.resolve('~/src/db')]; } +// Utility method to use along with `require` +type Db = typeof import('~/src/db'); + describe('db', () => { afterEach(async () => { await restoreDb(); }); it('creates a database at the path passed on creation', async () => { - const testDb = await import('~/src/db'); + const testDb = require('~/src/db') as Db; await testDb.initialized(); await expect(fs.access(constants.databasePath)).to.not.be.rejected; }); @@ -62,7 +65,7 @@ describe('db', () => { it('migrations add new fields and removes old ones in an old database', async () => { // Create a database with an older schema const knexForDB = await createOldDatabase(constants.databasePath); - const testDb = await import('~/src/db'); + const testDb = require('~/src/db') as Db; await testDb.initialized(); await Bluebird.all([ expect(knexForDB.schema.hasColumn('app', 'appId')).to.eventually.be.true, @@ -88,7 +91,7 @@ describe('db', () => { }); it('creates a deviceConfig table with a single default value', async () => { - const testDb = await import('~/src/db'); + const testDb = require('~/src/db') as Db; await testDb.initialized(); const deviceConfig = await testDb.models('deviceConfig').select(); expect(deviceConfig).to.have.lengthOf(1); @@ -96,7 +99,7 @@ describe('db', () => { }); it('allows performing transactions', async () => { - const testDb = await import('~/src/db'); + const testDb = require('~/src/db') as Db; await testDb.initialized(); return testDb.transaction((trx) => expect(trx.commit()).to.be.fulfilled); }); diff --git a/test/legacy/10-api-binder.spec.ts b/test/legacy/10-api-binder.spec.ts index 679d3660..758d0ef4 100644 --- a/test/legacy/10-api-binder.spec.ts +++ b/test/legacy/10-api-binder.spec.ts @@ -41,7 +41,7 @@ const initModels = async (obj: Dictionary, filename: string) => { }, } as any; - ApiBinder = await import('~/src/api-binder'); + ApiBinder = require('~/src/api-binder'); await ApiBinder.initialized(); obj.apiBinder = ApiBinder; @@ -414,7 +414,8 @@ describe('ApiBinder', () => { }); it('fails when stateReportHealthy is false', async () => { - const currentState = await import('~/src/api-binder/report'); + const currentState = + require('~/src/api-binder/report') as typeof import('~/src/api-binder/report'); configStub.resolves({ unmanaged: false, diff --git a/test/legacy/11-logger.spec.ts b/test/legacy/11-logger.spec.ts index a9e32eea..bb8869bc 100644 --- a/test/legacy/11-logger.spec.ts +++ b/test/legacy/11-logger.spec.ts @@ -37,7 +37,7 @@ describe('Logger', function () { ); // delete the require cache for the logger module so we can force a refresh delete require.cache[require.resolve('~/src/logger')]; - logger = await import('~/src/logger'); + logger = require('~/src/logger'); await logger.initialized(); }); diff --git a/tsconfig.json b/tsconfig.json index a287730a..28e5bc66 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "baseUrl": "./", "target": "ES2021", "module": "commonjs", + "moduleResolution": "Node16", "strict": true, "strictFunctionTypes": false, "strictPropertyInitialization": false,