diff --git a/.eslintrc.js b/.eslintrc.js index ccc0b3249bdf..32eb83986453 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -11,8 +11,10 @@ module.exports = { }, parser: "@typescript-eslint/parser", parserOptions: { - ecmaVersion: 10, + ecmaVersion: "latest", project: "./tsconfig.json", + // Support ESM modules + sourceType: "module", }, plugins: ["@typescript-eslint", "eslint-plugin-import", "eslint-plugin-node", "no-only-tests", "prettier"], extends: [ @@ -124,6 +126,9 @@ module.exports = { // Prevents accidentally pushing a commit with .only in Mocha tests "no-only-tests/no-only-tests": "error", + + // TEMP Disabled while eslint-plugin-import support ESM (Typescript does support it) https://github.com/import-js/eslint-plugin-import/issues/2170 + "import/no-unresolved": "off", }, overrides: [ { diff --git a/packages/utils/package.json b/packages/utils/package.json index ddbdd6135e22..26eaf0940a44 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -12,6 +12,8 @@ "url": "https://github.com/ChainSafe/lodestar/issues" }, "version": "0.29.3", + "type": "module", + "exports": "./lib/index.js", "main": "lib/index.js", "files": [ "lib/**/*.d.ts", @@ -20,6 +22,9 @@ "*.d.ts", "*.js" ], + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, "scripts": { "clean": "rm -rf lib && rm -f *.tsbuildinfo", "build": "tsc -p tsconfig.build.json", diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 4fbe38e12dad..295566f54474 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,15 +1,15 @@ -export * from "./logger"; -export * from "./yaml"; -export * from "./assert"; -export * from "./bytes"; -export * from "./errors"; -export * from "./format"; -export * from "./math"; -export * from "./objects"; -export * from "./notNullish"; -export * from "./sleep"; -export * from "./sort"; -export * from "./timeout"; -export * from "./types"; -export * from "./verifyMerkleBranch"; -export * from "./json"; +export * from "./logger/index.js"; +export * from "./yaml/index.js"; +export * from "./assert.js"; +export * from "./bytes.js"; +export * from "./errors.js"; +export * from "./format.js"; +export * from "./math.js"; +export * from "./objects.js"; +export * from "./notNullish.js"; +export * from "./sleep.js"; +export * from "./sort.js"; +export * from "./timeout.js"; +export * from "./types.js"; +export * from "./verifyMerkleBranch.js"; +export * from "./json.js"; diff --git a/packages/utils/src/json.ts b/packages/utils/src/json.ts index 1aefa1a5f97d..ed906b16132c 100644 --- a/packages/utils/src/json.ts +++ b/packages/utils/src/json.ts @@ -1,6 +1,6 @@ import {Json, toHexString} from "@chainsafe/ssz"; -import {LodestarError} from "./errors"; -import {mapValues} from "./objects"; +import {LodestarError} from "./errors.js"; +import {mapValues} from "./objects.js"; export const CIRCULAR_REFERENCE_TAG = "CIRCULAR_REFERENCE"; diff --git a/packages/utils/src/logger/format.ts b/packages/utils/src/logger/format.ts index 3a44f8b48ae1..6f5d7ab1f6fe 100644 --- a/packages/utils/src/logger/format.ts +++ b/packages/utils/src/logger/format.ts @@ -1,6 +1,6 @@ import {Json} from "@chainsafe/ssz"; import {format} from "winston"; -import {toJson, toString} from "../json"; +import {toJson, toString} from "../json.js"; import {Context, ILoggerOptions, TimestampFormatCode} from "./interface"; import {formatEpochSlotTime} from "./util"; diff --git a/packages/utils/src/logger/index.ts b/packages/utils/src/logger/index.ts index 33c9eefc9db8..5cb88279c696 100644 --- a/packages/utils/src/logger/index.ts +++ b/packages/utils/src/logger/index.ts @@ -3,6 +3,6 @@ */ export * from "./interface"; -export * from "./format"; -export * from "./transport"; -export * from "./winston"; +export * from "./format.js"; +export * from "./transport.js"; +export * from "./winston.js"; diff --git a/packages/utils/src/logger/winston.ts b/packages/utils/src/logger/winston.ts index 3623caee9107..e095d6132a63 100644 --- a/packages/utils/src/logger/winston.ts +++ b/packages/utils/src/logger/winston.ts @@ -5,9 +5,9 @@ import {createLogger, Logger} from "winston"; import {Context, defaultLogLevel, ILogger, ILoggerOptions, LogLevel, logLevelNum} from "./interface"; import chalk from "chalk"; -import {getFormat} from "./format"; +import {getFormat} from "./format.js"; import {Writable} from "stream"; -import {TransportOpts, TransportType, fromTransportOpts} from "./transport"; +import {TransportOpts, TransportType, fromTransportOpts} from "./transport.js"; const defaultTransportOpts: TransportOpts = {type: TransportType.console}; diff --git a/packages/utils/src/sleep.ts b/packages/utils/src/sleep.ts index 0134bf23810d..16d482eec159 100644 --- a/packages/utils/src/sleep.ts +++ b/packages/utils/src/sleep.ts @@ -1,5 +1,5 @@ import {AbortSignal} from "@chainsafe/abort-controller"; -import {ErrorAborted} from "./errors"; +import {ErrorAborted} from "./errors.js"; /** * Abortable sleep function. Cleans everything on all cases preventing leaks diff --git a/packages/utils/src/timeout.ts b/packages/utils/src/timeout.ts index 8545152bfbf5..c3d5f4d485c7 100644 --- a/packages/utils/src/timeout.ts +++ b/packages/utils/src/timeout.ts @@ -1,7 +1,7 @@ import {AbortSignal, AbortController} from "@chainsafe/abort-controller"; import {anySignal} from "any-signal"; -import {TimeoutError} from "./errors"; -import {sleep} from "./sleep"; +import {TimeoutError} from "./errors.js"; +import {sleep} from "./sleep.js"; export async function withTimeout( asyncFn: (timeoutAndParentSignal?: AbortSignal) => Promise, diff --git a/packages/utils/src/verifyMerkleBranch.ts b/packages/utils/src/verifyMerkleBranch.ts index 59db928575bf..7cbce3d6d10d 100644 --- a/packages/utils/src/verifyMerkleBranch.ts +++ b/packages/utils/src/verifyMerkleBranch.ts @@ -1,4 +1,3 @@ -import {intDiv} from "./math"; import {hash} from "@chainsafe/ssz"; /** @@ -14,7 +13,7 @@ export function verifyMerkleBranch( ): boolean { let value = leaf; for (let i = 0; i < depth; i++) { - if (intDiv(index, 2 ** i) % 2) { + if (Math.floor(index / 2 ** i) % 2) { value = hash(Buffer.concat([proof[i], value])); } else { value = hash(Buffer.concat([value, proof[i]])); diff --git a/packages/utils/src/yaml/index.ts b/packages/utils/src/yaml/index.ts index ac0cb1394edc..e5908d5a89fb 100644 --- a/packages/utils/src/yaml/index.ts +++ b/packages/utils/src/yaml/index.ts @@ -1,6 +1,6 @@ import {load, dump} from "js-yaml"; -import {schema} from "./schema"; -import {objectToExpectedCase} from "../objects"; +import {schema} from "./schema.js"; +import {objectToExpectedCase} from "../objects.js"; export function loadYaml(yaml: string): Record { return objectToExpectedCase>(load(yaml, {schema})); diff --git a/packages/utils/src/yaml/schema.ts b/packages/utils/src/yaml/schema.ts index efe59c4f4405..03ef475ab5f0 100644 --- a/packages/utils/src/yaml/schema.ts +++ b/packages/utils/src/yaml/schema.ts @@ -11,7 +11,7 @@ import boolType from "js-yaml/lib/js-yaml/type/bool"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore import floatType from "js-yaml/lib/js-yaml/type/float"; -import {intType} from "./int"; +import {intType} from "./int.js"; export const schema = new Schema({ include: [failsafe], diff --git a/packages/utils/tsconfig.build.json b/packages/utils/tsconfig.build.json index bac394399f4e..5395232e2eea 100644 --- a/packages/utils/tsconfig.build.json +++ b/packages/utils/tsconfig.build.json @@ -2,6 +2,10 @@ "extends": "../../tsconfig.build.json", "include": ["src"], "compilerOptions": { - "outDir": "./lib" + "outDir": "./lib", + "target": "es2020", + "module": "esnext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true } } diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index b29a7b46c4b1..c5fd0b35329f 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -1,4 +1,9 @@ { "extends": "../../tsconfig.json", - "compilerOptions": {} + "compilerOptions": { + "target": "es2020", + "module": "ES2020", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + } }