From e34bfb8e0b2cc847b19ccb753b316b4486094579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emanuel=20Tesa=C5=99?= Date: Wed, 22 Jun 2022 17:56:13 +0200 Subject: [PATCH] Use TS references to link monorepo packages (#1277) * Implement script ensuring validity of TS references * Update TS configuration * Add TS config for dev scripts * Add changeset * Move *.tsbuildinfo files outside of /dist folder * Document edge case when running scripts with ts-node --- .changeset/tasty-masks-grin.md | 15 ++++++ README.md | 5 ++ package.json | 3 +- packages/airnode-abi/.gitignore | 1 + packages/airnode-abi/package.json | 2 +- packages/airnode-abi/src/tsconfig.json | 1 + packages/airnode-abi/test/tsconfig.json | 4 +- packages/airnode-adapter/.gitignore | 1 + packages/airnode-adapter/e2e/tsconfig.json | 4 +- packages/airnode-adapter/package.json | 2 +- packages/airnode-adapter/src/tsconfig.json | 2 + packages/airnode-adapter/test/tsconfig.json | 4 +- packages/airnode-admin/.gitignore | 1 + packages/airnode-admin/package.json | 2 +- packages/airnode-admin/src/tsconfig.json | 7 +++ packages/airnode-admin/test/tsconfig.json | 4 +- packages/airnode-deployer/.gitignore | 1 + packages/airnode-deployer/package.json | 2 +- packages/airnode-deployer/src/tsconfig.json | 7 +++ packages/airnode-deployer/test/tsconfig.json | 4 +- packages/airnode-examples/.gitignore | 1 + .../dev-scripts/tsconfig.json | 4 +- packages/airnode-examples/package.json | 2 +- packages/airnode-examples/src/tsconfig.json | 8 +++ packages/airnode-examples/test/tsconfig.json | 4 +- packages/airnode-node/.gitignore | 1 + packages/airnode-node/package.json | 2 +- packages/airnode-node/src/tsconfig.json | 10 ++++ packages/airnode-node/test/tsconfig.json | 4 +- packages/airnode-ois/.gitignore | 1 + packages/airnode-ois/package.json | 2 +- packages/airnode-ois/src/tsconfig.json | 1 + packages/airnode-ois/test/tsconfig.json | 4 +- packages/airnode-operation/.gitignore | 1 + packages/airnode-operation/package.json | 2 +- packages/airnode-operation/src/tsconfig.json | 6 +++ packages/airnode-protocol/.gitignore | 1 + packages/airnode-protocol/package.json | 2 +- packages/airnode-protocol/src/tsconfig.json | 1 + packages/airnode-protocol/test/tsconfig.json | 3 +- packages/airnode-utilities/.gitignore | 1 + packages/airnode-utilities/package.json | 2 +- packages/airnode-utilities/src/tsconfig.json | 1 + packages/airnode-utilities/test/tsconfig.json | 4 +- packages/airnode-validator/.gitignore | 1 + packages/airnode-validator/package.json | 2 +- .../airnode-validator/src/tsconfig.cjs.json | 3 +- .../airnode-validator/src/tsconfig.es6.json | 3 +- .../airnode-validator/src/tsconfig.esm.json | 3 +- packages/airnode-validator/src/tsconfig.json | 3 +- packages/airnode-validator/test/tsconfig.json | 4 +- scripts/.gitignore | 1 + scripts/tsconfig.json | 9 ++++ scripts/validate-ts-references.ts | 51 +++++++++++++++++++ tsconfig.json | 5 +- yarn.lock | 26 ++++++++++ 56 files changed, 220 insertions(+), 31 deletions(-) create mode 100644 .changeset/tasty-masks-grin.md create mode 100644 scripts/.gitignore create mode 100644 scripts/tsconfig.json create mode 100644 scripts/validate-ts-references.ts diff --git a/.changeset/tasty-masks-grin.md b/.changeset/tasty-masks-grin.md new file mode 100644 index 0000000000..aa04c6e396 --- /dev/null +++ b/.changeset/tasty-masks-grin.md @@ -0,0 +1,15 @@ +--- +'@api3/airnode-abi': minor +'@api3/airnode-adapter': minor +'@api3/airnode-admin': minor +'@api3/airnode-deployer': minor +'@api3/airnode-examples': minor +'@api3/airnode-node': minor +'@api3/airnode-ois': minor +'@api3/airnode-operation': minor +'@api3/airnode-protocol': minor +'@api3/airnode-utilities': minor +'@api3/airnode-validator': minor +--- + +Link monorepo packages using project references diff --git a/README.md b/README.md index a02eb7bd1a..9f286ed25c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,11 @@ examples) will work out of the box. We heavily recommend using UNIX based systems for development. If you are using Windows, consider [WSL](https://docs.microsoft.com/en-us/windows/wsl/install). +We use [TS project references](https://www.typescriptlang.org/docs/handbook/project-references.html) to see +cross-package errors in real time. However, we use `ts-node` to run our development scripts and it +[does not support project references](https://github.com/TypeStrong/ts-node/issues/897) at the moment. This means that +some of the errors are only shown in the IDE or at build time, not when run using `ts-node`. + ## Changelog We use [changesets](https://github.com/atlassian/changesets) to manage the changelog for us. What that means for diff --git a/package.json b/package.json index e97a439072..594e61d363 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "docker:build:client": "docker build --tag api3/airnode-client:latest --file packages/airnode-node/docker/Dockerfile .", "format:check": "yarn prettier:check && yarn terraform:fmt:check", "format:write": "yarn prettier:write && yarn terraform:fmt:write", - "lint": "yarn run lint:eslint && yarn run lint:solhint && yarn format:check && yarn lint:deps-versions", + "lint": "yarn run lint:eslint && yarn run lint:solhint && yarn format:check && yarn lint:deps-versions && yarn ts-node scripts/validate-ts-references.ts", "lint:deps-versions": "syncpack list-mismatches", "lint:eslint": "eslint . --ext .js,.ts", "lint:eslint:fix": "eslint . --ext .js,.ts --fix", @@ -93,6 +93,7 @@ "@types/node": "^17.0.18", "@typescript-eslint/eslint-plugin": "^5.27.1", "@typescript-eslint/parser": "^5.27.1", + "comment-json": "^4.2.2", "eslint": "^8.17.0", "eslint-plugin-functional": "^4.2.1", "eslint-plugin-import": "^2.26.0", diff --git a/packages/airnode-abi/.gitignore b/packages/airnode-abi/.gitignore index 2580f32a3b..f74e6a58cf 100644 --- a/packages/airnode-abi/.gitignore +++ b/packages/airnode-abi/.gitignore @@ -1,5 +1,6 @@ /node_modules /dist +/build # Test files coverage/ diff --git a/packages/airnode-abi/package.json b/packages/airnode-abi/package.json index 6770f52eda..2c725c85e3 100644 --- a/packages/airnode-abi/package.json +++ b/packages/airnode-abi/package.json @@ -10,7 +10,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "compile": "tsc --build tsconfig.json", "pack": "yarn pack", "test": "SILENCE_LOGGER=true jest --coverage", diff --git a/packages/airnode-abi/src/tsconfig.json b/packages/airnode-abi/src/tsconfig.json index 2828a15d91..b5673f51b9 100644 --- a/packages/airnode-abi/src/tsconfig.json +++ b/packages/airnode-abi/src/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "./", "outDir": "../dist" diff --git a/packages/airnode-abi/test/tsconfig.json b/packages/airnode-abi/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-abi/test/tsconfig.json +++ b/packages/airnode-abi/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-adapter/.gitignore b/packages/airnode-adapter/.gitignore index 67b2c0bfc8..46cae764c6 100644 --- a/packages/airnode-adapter/.gitignore +++ b/packages/airnode-adapter/.gitignore @@ -1,5 +1,6 @@ /node_modules /dist +/build /.serverless /.build diff --git a/packages/airnode-adapter/e2e/tsconfig.json b/packages/airnode-adapter/e2e/tsconfig.json index 49cfbffe59..4806daf533 100644 --- a/packages/airnode-adapter/e2e/tsconfig.json +++ b/packages/airnode-adapter/e2e/tsconfig.json @@ -3,7 +3,9 @@ "compilerOptions": { "types": ["@nomiclabs/hardhat-waffle", "@nomiclabs/hardhat-ethers", "chai", "mocha", "hardhat"], "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], // Mocha tests use only the ".ts" (not ".test.ts") extension not to conflict with Jest tests diff --git a/packages/airnode-adapter/package.json b/packages/airnode-adapter/package.json index 1b54ba3401..a05f108b12 100644 --- a/packages/airnode-adapter/package.json +++ b/packages/airnode-adapter/package.json @@ -10,7 +10,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "compile": "hardhat compile && tsc --build tsconfig.json", "pack": "yarn pack", "test": "yarn test:ts && yarn test:hardhat", diff --git a/packages/airnode-adapter/src/tsconfig.json b/packages/airnode-adapter/src/tsconfig.json index 2828a15d91..c5300aea20 100644 --- a/packages/airnode-adapter/src/tsconfig.json +++ b/packages/airnode-adapter/src/tsconfig.json @@ -2,10 +2,12 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "./", "outDir": "../dist" }, + "references": [{ "path": "../../airnode-ois/src" }], "include": ["./**/*.ts"], "exclude": ["./**/*.test.ts"] } diff --git a/packages/airnode-adapter/test/tsconfig.json b/packages/airnode-adapter/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-adapter/test/tsconfig.json +++ b/packages/airnode-adapter/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-admin/.gitignore b/packages/airnode-admin/.gitignore index 8225baa4a7..936992d30c 100644 --- a/packages/airnode-admin/.gitignore +++ b/packages/airnode-admin/.gitignore @@ -1,2 +1,3 @@ /node_modules /dist +/build diff --git a/packages/airnode-admin/package.json b/packages/airnode-admin/package.json index fd18a9cb90..9b3fd03813 100644 --- a/packages/airnode-admin/package.json +++ b/packages/airnode-admin/package.json @@ -12,7 +12,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "cli": "ts-node bin/admin.ts", "compile": "tsc --build tsconfig.json", "pack": "yarn pack", diff --git a/packages/airnode-admin/src/tsconfig.json b/packages/airnode-admin/src/tsconfig.json index 41babe8271..f8c9701bfd 100644 --- a/packages/airnode-admin/src/tsconfig.json +++ b/packages/airnode-admin/src/tsconfig.json @@ -2,11 +2,18 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "..", "rootDirs": ["./src", "./bin"], "outDir": "../dist" }, + "references": [ + { "path": "../../airnode-abi/src" }, + { "path": "../../airnode-protocol/src" }, + { "path": "../../airnode-utilities/src" }, + { "path": "../../airnode-validator/src" } + ], "include": ["./**/*.ts", "../bin/**/*.ts", "../package.json"], "exclude": ["./**/*.test.ts"] } diff --git a/packages/airnode-admin/test/tsconfig.json b/packages/airnode-admin/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-admin/test/tsconfig.json +++ b/packages/airnode-admin/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-deployer/.gitignore b/packages/airnode-deployer/.gitignore index deb33c6bf0..999d242921 100644 --- a/packages/airnode-deployer/.gitignore +++ b/packages/airnode-deployer/.gitignore @@ -1,5 +1,6 @@ /node_modules /dist +/build /.serverless /.build /.webpack diff --git a/packages/airnode-deployer/package.json b/packages/airnode-deployer/package.json index 97aa1dcfc7..bc43034dc6 100644 --- a/packages/airnode-deployer/package.json +++ b/packages/airnode-deployer/package.json @@ -12,7 +12,7 @@ ], "scripts": { "build": "yarn clean && yarn compile && yarn webpack && yarn copy:webpack && yarn copy:terraform", - "clean": "rimraf -rf *.tsbuildinfo ./dist ./.webpack *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./.webpack ./build *.tgz", "cli": "ts-node bin/deployer.ts", "compile": "tsc --build tsconfig.json", "copy:terraform": "copyfiles terraform/**/**/**/*.tf terraform/**/**/**/*.tpl dist/", diff --git a/packages/airnode-deployer/src/tsconfig.json b/packages/airnode-deployer/src/tsconfig.json index 41babe8271..28949e15cf 100644 --- a/packages/airnode-deployer/src/tsconfig.json +++ b/packages/airnode-deployer/src/tsconfig.json @@ -2,11 +2,18 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "..", "rootDirs": ["./src", "./bin"], "outDir": "../dist" }, + "references": [ + { "path": "../../airnode-node/src" }, + { "path": "../../airnode-protocol/src" }, + { "path": "../../airnode-utilities/src" }, + { "path": "../../airnode-validator/src" } + ], "include": ["./**/*.ts", "../bin/**/*.ts", "../package.json"], "exclude": ["./**/*.test.ts"] } diff --git a/packages/airnode-deployer/test/tsconfig.json b/packages/airnode-deployer/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-deployer/test/tsconfig.json +++ b/packages/airnode-deployer/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-examples/.gitignore b/packages/airnode-examples/.gitignore index 83499a4ae1..d7e97d1a1e 100644 --- a/packages/airnode-examples/.gitignore +++ b/packages/airnode-examples/.gitignore @@ -1,6 +1,7 @@ node_modules log.json /dist +/build # Hardhat files /cache diff --git a/packages/airnode-examples/dev-scripts/tsconfig.json b/packages/airnode-examples/dev-scripts/tsconfig.json index 4ca7daace3..7dd8c152b0 100644 --- a/packages/airnode-examples/dev-scripts/tsconfig.json +++ b/packages/airnode-examples/dev-scripts/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": ".", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts"] diff --git a/packages/airnode-examples/package.json b/packages/airnode-examples/package.json index 8783f4e1e5..db656054ac 100644 --- a/packages/airnode-examples/package.json +++ b/packages/airnode-examples/package.json @@ -9,7 +9,7 @@ ], "scripts": { "build": "yarn run clean && yarn compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "choose-integration": "ts-node src/scripts/choose-integration.ts", "compile": "hardhat compile && tsc --build tsconfig.json", "create-airnode-config": "ts-node src/scripts/create-airnode-config.ts", diff --git a/packages/airnode-examples/src/tsconfig.json b/packages/airnode-examples/src/tsconfig.json index 2828a15d91..dff521bee3 100644 --- a/packages/airnode-examples/src/tsconfig.json +++ b/packages/airnode-examples/src/tsconfig.json @@ -6,6 +6,14 @@ "rootDir": "./", "outDir": "../dist" }, + "references": [ + { "path": "../../airnode-abi/src" }, + { "path": "../../airnode-admin/src" }, + { "path": "../../airnode-deployer/src" }, + { "path": "../../airnode-node/src" }, + { "path": "../../airnode-protocol/src" }, + { "path": "../../airnode-utilities/src" } + ], "include": ["./**/*.ts"], "exclude": ["./**/*.test.ts"] } diff --git a/packages/airnode-examples/test/tsconfig.json b/packages/airnode-examples/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-examples/test/tsconfig.json +++ b/packages/airnode-examples/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-node/.gitignore b/packages/airnode-node/.gitignore index ca1a1d54f3..d801248eea 100644 --- a/packages/airnode-node/.gitignore +++ b/packages/airnode-node/.gitignore @@ -1,5 +1,6 @@ /node_modules /dist +/build /.serverless /.build diff --git a/packages/airnode-node/package.json b/packages/airnode-node/package.json index 0ea5ec44c1..1edf8e9215 100644 --- a/packages/airnode-node/package.json +++ b/packages/airnode-node/package.json @@ -10,7 +10,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "compile": "tsc --build tsconfig.json", "dev:invoke": "ts-node src/cli/validate-config.ts && ts-node src/cli/invoke.ts", "dev:testApi": "ts-node src/cli/test-api.ts", diff --git a/packages/airnode-node/src/tsconfig.json b/packages/airnode-node/src/tsconfig.json index 4b632b5255..db289397db 100644 --- a/packages/airnode-node/src/tsconfig.json +++ b/packages/airnode-node/src/tsconfig.json @@ -2,10 +2,20 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "..", "outDir": "../dist" }, + "references": [ + { "path": "../../airnode-abi/src" }, + { "path": "../../airnode-adapter/src" }, + { "path": "../../airnode-ois/src" }, + { "path": "../../airnode-protocol/src" }, + { "path": "../../airnode-utilities/src" }, + { "path": "../../airnode-validator/src" }, + { "path": "../../airnode-operation/src" } + ], "include": ["./**/*.ts", "../package.json"], "exclude": ["./**/*.test.ts"] } diff --git a/packages/airnode-node/test/tsconfig.json b/packages/airnode-node/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-node/test/tsconfig.json +++ b/packages/airnode-node/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-ois/.gitignore b/packages/airnode-ois/.gitignore index aebc9e0cf1..d3180687ce 100644 --- a/packages/airnode-ois/.gitignore +++ b/packages/airnode-ois/.gitignore @@ -1,5 +1,6 @@ /node_modules /dist +/build /.serverless /.build diff --git a/packages/airnode-ois/package.json b/packages/airnode-ois/package.json index ac330d46f7..49349c4c2f 100644 --- a/packages/airnode-ois/package.json +++ b/packages/airnode-ois/package.json @@ -10,7 +10,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "compile": "tsc --build tsconfig.json", "pack": "yarn pack" }, diff --git a/packages/airnode-ois/src/tsconfig.json b/packages/airnode-ois/src/tsconfig.json index 2828a15d91..722986e3ec 100644 --- a/packages/airnode-ois/src/tsconfig.json +++ b/packages/airnode-ois/src/tsconfig.json @@ -6,6 +6,7 @@ "rootDir": "./", "outDir": "../dist" }, + "references": [{ "path": "../../airnode-validator/src" }], "include": ["./**/*.ts"], "exclude": ["./**/*.test.ts"] } diff --git a/packages/airnode-ois/test/tsconfig.json b/packages/airnode-ois/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-ois/test/tsconfig.json +++ b/packages/airnode-ois/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-operation/.gitignore b/packages/airnode-operation/.gitignore index 89115a4dc5..d0e04d80c8 100644 --- a/packages/airnode-operation/.gitignore +++ b/packages/airnode-operation/.gitignore @@ -1,5 +1,6 @@ node_modules /dist +/build # Hardhat files cache diff --git a/packages/airnode-operation/package.json b/packages/airnode-operation/package.json index c3471b512e..eb73ec24a1 100644 --- a/packages/airnode-operation/package.json +++ b/packages/airnode-operation/package.json @@ -10,7 +10,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "compile": "tsc --build tsconfig.json", "compile:watch": "tsc --build tsconfig.json -w", "dev:api": "ts-node src/server.ts", diff --git a/packages/airnode-operation/src/tsconfig.json b/packages/airnode-operation/src/tsconfig.json index 2828a15d91..3cc3c4d66f 100644 --- a/packages/airnode-operation/src/tsconfig.json +++ b/packages/airnode-operation/src/tsconfig.json @@ -2,10 +2,16 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "./", "outDir": "../dist" }, + "references": [ + { "path": "../../airnode-abi/src" }, + { "path": "../../airnode-protocol/src" }, + { "path": "../../airnode-utilities/src" } + ], "include": ["./**/*.ts"], "exclude": ["./**/*.test.ts"] } diff --git a/packages/airnode-protocol/.gitignore b/packages/airnode-protocol/.gitignore index bf97793698..c7ade95e1d 100644 --- a/packages/airnode-protocol/.gitignore +++ b/packages/airnode-protocol/.gitignore @@ -1,5 +1,6 @@ /node_modules /dist +/build /cache /artifacts diff --git a/packages/airnode-protocol/package.json b/packages/airnode-protocol/package.json index 51ad8108da..22dce366ac 100644 --- a/packages/airnode-protocol/package.json +++ b/packages/airnode-protocol/package.json @@ -10,7 +10,7 @@ ], "scripts": { "build": "yarn run clean && yarn compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "compile": "yarn run compile:contracts && yarn run compile:tsc", "compile:contracts": "hardhat compile", "compile:tsc": "yarn compile:contract-dts && yarn compile:copy-contract-dts && tsc --build tsconfig.json", diff --git a/packages/airnode-protocol/src/tsconfig.json b/packages/airnode-protocol/src/tsconfig.json index 8c2b2dcd8d..e0c55fe8f4 100644 --- a/packages/airnode-protocol/src/tsconfig.json +++ b/packages/airnode-protocol/src/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "..", "outDir": "../dist" diff --git a/packages/airnode-protocol/test/tsconfig.json b/packages/airnode-protocol/test/tsconfig.json index caf91992d6..a33c59ed81 100644 --- a/packages/airnode-protocol/test/tsconfig.json +++ b/packages/airnode-protocol/test/tsconfig.json @@ -1,5 +1,6 @@ // The tests inside this directory are Hardhat tests (using Mocha) and they do not depend on sources. -// For this reason, the TS configuration does not reference the sources inside "src" directory. +// For this reason, the TS configuration does not reference the sources inside the "src" +// directory and has "noEmit" set to true. { "extends": "../tsconfig.json", "compilerOptions": { diff --git a/packages/airnode-utilities/.gitignore b/packages/airnode-utilities/.gitignore index 8225baa4a7..936992d30c 100644 --- a/packages/airnode-utilities/.gitignore +++ b/packages/airnode-utilities/.gitignore @@ -1,2 +1,3 @@ /node_modules /dist +/build diff --git a/packages/airnode-utilities/package.json b/packages/airnode-utilities/package.json index 1ef12332f8..051870572a 100644 --- a/packages/airnode-utilities/package.json +++ b/packages/airnode-utilities/package.json @@ -9,7 +9,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "compile": "tsc --build tsconfig.json", "test": "SILENCE_LOGGER=true jest --selectProjects unit", "pack": "yarn pack" diff --git a/packages/airnode-utilities/src/tsconfig.json b/packages/airnode-utilities/src/tsconfig.json index 2828a15d91..b5673f51b9 100644 --- a/packages/airnode-utilities/src/tsconfig.json +++ b/packages/airnode-utilities/src/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { "composite": true, + "tsBuildInfoFile": "../build/src-tsconfig.tsbuildinfo", "rootDir": "./", "outDir": "../dist" diff --git a/packages/airnode-utilities/test/tsconfig.json b/packages/airnode-utilities/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-utilities/test/tsconfig.json +++ b/packages/airnode-utilities/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/packages/airnode-validator/.gitignore b/packages/airnode-validator/.gitignore index 7573aa1425..c98d601cf2 100644 --- a/packages/airnode-validator/.gitignore +++ b/packages/airnode-validator/.gitignore @@ -1,3 +1,4 @@ node_modules/ /dist +/build build/ diff --git a/packages/airnode-validator/package.json b/packages/airnode-validator/package.json index cbefe7d4d7..54782ca612 100644 --- a/packages/airnode-validator/package.json +++ b/packages/airnode-validator/package.json @@ -14,7 +14,7 @@ ], "scripts": { "build": "yarn run clean && yarn run compile", - "clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", + "clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", "cli": "ts-node bin/validator.ts", "compile": "yarn tsc --build tsconfig.json", "pack": "yarn pack", diff --git a/packages/airnode-validator/src/tsconfig.cjs.json b/packages/airnode-validator/src/tsconfig.cjs.json index ef668df8d2..1d73e7baff 100644 --- a/packages/airnode-validator/src/tsconfig.cjs.json +++ b/packages/airnode-validator/src/tsconfig.cjs.json @@ -4,6 +4,7 @@ "target": "es6", "module": "commonJS", "moduleResolution": "node", - "outDir": "../dist/cjs" + "outDir": "../dist/cjs", + "tsBuildInfoFile": "../build/cjs-src-tsconfig.tsbuildinfo" } } diff --git a/packages/airnode-validator/src/tsconfig.es6.json b/packages/airnode-validator/src/tsconfig.es6.json index e12981bab5..35a9610590 100644 --- a/packages/airnode-validator/src/tsconfig.es6.json +++ b/packages/airnode-validator/src/tsconfig.es6.json @@ -4,6 +4,7 @@ "target": "es6", "module": "es6", "moduleResolution": "node", - "outDir": "../dist/es6" + "outDir": "../dist/es6", + "tsBuildInfoFile": "../build/es6-src-tsconfig.tsbuildinfo" } } diff --git a/packages/airnode-validator/src/tsconfig.esm.json b/packages/airnode-validator/src/tsconfig.esm.json index ffb1daa938..8055b2a7ad 100644 --- a/packages/airnode-validator/src/tsconfig.esm.json +++ b/packages/airnode-validator/src/tsconfig.esm.json @@ -4,6 +4,7 @@ "target": "esnext", "module": "esnext", "moduleResolution": "node", - "outDir": "../dist/esm" + "outDir": "../dist/esm", + "tsBuildInfoFile": "../build/esnext-src-tsconfig.tsbuildinfo" } } diff --git a/packages/airnode-validator/src/tsconfig.json b/packages/airnode-validator/src/tsconfig.json index d56aa19f43..a3da873bce 100644 --- a/packages/airnode-validator/src/tsconfig.json +++ b/packages/airnode-validator/src/tsconfig.json @@ -12,7 +12,8 @@ "references": [ { "path": "./tsconfig.cjs.json" }, { "path": "./tsconfig.es6.json" }, - { "path": "./tsconfig.esm.json" } + { "path": "./tsconfig.esm.json" }, + { "path": "../../airnode-utilities/src" } ], "include": ["./**/*.ts", "../bin/**/*.ts", "../package.json"], "exclude": ["./**/*.test.ts"] diff --git a/packages/airnode-validator/test/tsconfig.json b/packages/airnode-validator/test/tsconfig.json index 853f7710ed..0b0d2e68ae 100644 --- a/packages/airnode-validator/test/tsconfig.json +++ b/packages/airnode-validator/test/tsconfig.json @@ -2,7 +2,9 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", - "noEmit": true + // The output files of this TS config are for development only. See the referenced TS configs + // which build the sources into the "dist" folder in the root of the validator project. + "outDir": "../build" }, "references": [{ "path": "../src" }], "include": ["./**/*.ts", "../src/**/*.test.ts"] diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +/build diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 0000000000..6f8f71f5b7 --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,9 @@ +// This TS config only exist as a TS configuration for the scripts which are invoked via ts-node +// and don't have to be compiled. For this reason "noEmit" is set to true. +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "include": ["./**/*.ts"] +} diff --git a/scripts/validate-ts-references.ts b/scripts/validate-ts-references.ts new file mode 100644 index 0000000000..b42f7a3835 --- /dev/null +++ b/scripts/validate-ts-references.ts @@ -0,0 +1,51 @@ +import { readFileSync, readdirSync } from 'fs'; +import { join } from 'path'; +import { parse as parseJsonWithComments } from 'comment-json'; + +const toPrettyJson = (value: unknown) => JSON.stringify(value, null, 2); + +const packagesDir = join(__dirname, '../packages'); +const packageNames = readdirSync(packagesDir, { withFileTypes: true }) + .filter( + // Only folders starting with "airnode-" are packages, other files should be ignored + (dirent) => dirent.isDirectory() && dirent.name.startsWith('airnode-') + ) + .map((dirent) => dirent.name); + +packageNames.forEach((packageName) => { + const packageDir = join(packagesDir, packageName); + const packageJson = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf-8')); + const dependencies = Object.keys({ ...packageJson.dependencies, ...packageJson.devDependencies }); + const monorepoDependencies = dependencies.filter( + (dependency) => dependency.startsWith('@api3/') && packageNames.includes(dependency.replace('@api3/', '')) + ); + + const tsConfig: any = parseJsonWithComments( + readFileSync(join(packageDir, 'src/tsconfig.json'), 'utf-8'), + undefined, + true + ); + const tsConfigReferences: string[] = (tsConfig.references ?? []).map((reference: any) => reference.path); + const monorepoReferences = tsConfigReferences.filter((reference) => reference.startsWith('../../')); + + if (monorepoDependencies.length !== monorepoReferences.length) { + throw new Error( + [ + `Package ${packageName} has wrong number of TS references.`, + `Dependencies:`, + `${toPrettyJson(monorepoDependencies)}`, + `References:`, + `${toPrettyJson(monorepoReferences)}`, + ].join('\n') + ); + } + + monorepoDependencies.forEach((dependency) => { + const tsReference = monorepoReferences.find( + (reference) => reference === '../../' + dependency.replace('@api3/', '') + '/src' + ); + if (!tsReference) { + throw new Error(`Package ${packageName} has no TS reference found for dependency ${dependency}.`); + } + }); +}); diff --git a/tsconfig.json b/tsconfig.json index dd7811f8cc..d6f4bde149 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,8 +3,6 @@ "declaration": true, "declarationMap": true, "sourceMap": true, - // Enable noEmit in every TS config which does not contain sources. This will make the compilation faster - "noEmit": false, "esModuleInterop": true, "lib": ["es2015"], @@ -45,6 +43,7 @@ { "path": "./packages/airnode-validator" }, { "path": "./packages/airnode-admin" }, { "path": "./packages/airnode-node" }, - { "path": "./packages/airnode-protocol" } + { "path": "./packages/airnode-protocol" }, + { "path": "./scripts" } ] } diff --git a/yarn.lock b/yarn.lock index 2069086bdd..65273e439a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3814,6 +3814,11 @@ array-includes@^3.1.4: get-intrinsic "^1.1.1" is-string "^1.0.7" +array-timsort@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-timsort/-/array-timsort-1.0.3.tgz#3c9e4199e54fb2b9c3fe5976396a21614ef0d926" + integrity sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -5635,6 +5640,17 @@ commander@^7.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +comment-json@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.2.2.tgz#5fae70a94e0c8f84a077bd31df5aa5269252f293" + integrity sha512-H8T+kl3nZesZu41zO2oNXIJWojNeK3mHxCLrsBNu6feksBXsgb+PtYz5daP5P86A0F3sz3840KVYehr04enISQ== + dependencies: + array-timsort "^1.0.3" + core-util-is "^1.0.3" + esprima "^4.0.1" + has-own-prop "^2.0.0" + repeat-string "^1.6.1" + common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" @@ -5870,6 +5886,11 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +core-util-is@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cors@^2.8.1: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -9101,6 +9122,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-own-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-own-prop/-/has-own-prop-2.0.0.tgz#f0f95d58f65804f5d218db32563bb85b8e0417af" + integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ== + has-property-descriptors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861"