From 9b55a8190b049e1e1ae435b4627d7e51d23d5aa0 Mon Sep 17 00:00:00 2001 From: Fardjad Davari Date: Wed, 27 Jul 2022 21:19:17 +0200 Subject: [PATCH] Add TypeScript extensions to EXTENSION_RE (#14) * add compatibility with typescript when using ts-node * add missing newline * fix typescript tests * run typescript tests with imhotap * separate js tests from ts tests * do not run test:ts with node 16.10.0 * add a FIXME comment for EXTENSION_RE changes The addition of TS extensions to EXTENSION_RE should be temporary until we find a better way of supporting arbitrary extensions Co-authored-by: rochdev --- .github/workflows/ci.yml | 2 ++ hook.mjs | 4 +++- package.json | 6 +++++- test/fixtures/say-hi.mts | 3 +++ test/runtest | 7 ++++++- test/typescript/iitm-ts-node-loader.mjs | 18 ++++++++++++++++++ test/typescript/ts-node.test.mts | 11 +++++++++++ tsconfig.json | 14 ++++++++++++++ 8 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/say-hi.mts create mode 100644 test/typescript/iitm-ts-node-loader.mjs create mode 100644 test/typescript/ts-node.test.mts create mode 100644 tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 149e624..d8294cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,3 +17,5 @@ jobs: node-version: ${{ matrix.node-version }} - run: npm install - run: npm test + - run: npm run test:ts + if: (matrix.node-version != '12.x' && matrix.node-version != '14.x' && matrix.node-version != '16.10.0') \ No newline at end of file diff --git a/hook.mjs b/hook.mjs index 7581f92..d5c1a30 100644 --- a/hook.mjs +++ b/hook.mjs @@ -4,7 +4,9 @@ const specifiers = new Map() -const EXTENSION_RE = /\.(js|mjs|cjs)$/ +// FIXME: Typescript extensions are added temporarily until we find a better +// way of supporting arbitrary extensions +const EXTENSION_RE = /\.(js|mjs|cjs|ts|mts|cts)$/ const NODE_MAJOR = Number(process.versions.node.split('.')[0]) diff --git a/package.json b/package.json index b07c64e..1a65c7a 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "index.js", "scripts": { "test": "c8 --check-coverage --lines 90 imhotap --runner test/runtest --files test/{hook,low-level,other}/*", + "test:ts": "c8 imhotap --runner test/runtest --files test/typescript/*.test.mts", "coverage": "c8 --reporter html imhotap --runner test/runtest --files test/{hook,low-level,other}/* && echo '\nNow open coverage/index.html\n'" }, "repository": { @@ -26,8 +27,11 @@ }, "homepage": "https://github.com/DataDog/import-in-the-middle#readme", "devDependencies": { + "@types/node": "^18.0.6", "c8": "^7.8.0", - "imhotap": "^2.0.0" + "imhotap": "^2.0.0", + "ts-node": "^10.9.1", + "typescript": "^4.7.4" }, "dependencies": { "module-details-from-path": "^1.0.3" diff --git a/test/fixtures/say-hi.mts b/test/fixtures/say-hi.mts new file mode 100644 index 0000000..e7502a8 --- /dev/null +++ b/test/fixtures/say-hi.mts @@ -0,0 +1,3 @@ +export const sayHi = (name: string) => { + return `Hi ${name}` +}; diff --git a/test/runtest b/test/runtest index d8592c1..f3b9dba 100755 --- a/test/runtest +++ b/test/runtest @@ -15,7 +15,12 @@ const args = [ ...process.argv.slice(2) ] if (!filename.includes('disabled')) { - args.unshift(`--experimental-loader=${path.join(__dirname, '..', 'hook.mjs')}`) + const isTypescript = path.extname(filename).slice(-2) === 'ts' + const loaderPath = isTypescript + ? path.join(__dirname, 'typescript', 'iitm-ts-node-loader.mjs') + : path.join(__dirname, '..', 'hook.mjs') + + args.unshift(`--experimental-loader=${loaderPath}`) } spawn('node', args, { stdio: 'inherit' }).on('close', code => { diff --git a/test/typescript/iitm-ts-node-loader.mjs b/test/typescript/iitm-ts-node-loader.mjs new file mode 100644 index 0000000..3d753b9 --- /dev/null +++ b/test/typescript/iitm-ts-node-loader.mjs @@ -0,0 +1,18 @@ +import * as iitm from '../../hook.mjs' +import * as tsNode from 'ts-node/esm.mjs' + +const makeNext = (loader, fnName, parentResolveOrLoad) => { + return (specifierOrUrl, context) => { + return loader[fnName](specifierOrUrl, context, parentResolveOrLoad) + } +} + +export async function resolve(specifier, context, defaultResolve) { + const next = makeNext(tsNode, 'resolve', defaultResolve) + return iitm.resolve(specifier, context, next) +} + +export async function load(url, context, defaultLoad) { + let next = makeNext(tsNode, 'load', defaultLoad) + return iitm.load(url, context, next) +} \ No newline at end of file diff --git a/test/typescript/ts-node.test.mts b/test/typescript/ts-node.test.mts new file mode 100644 index 0000000..6591aec --- /dev/null +++ b/test/typescript/ts-node.test.mts @@ -0,0 +1,11 @@ +import assert from 'node:assert/strict' +import { addHook } from '../../index.js' +import { sayHi } from '../fixtures/say-hi.mjs' + +addHook((url, exported) => { + if (url.toLowerCase().endsWith('say-hi.mts')) { + exported.sayHi = () => 'Hooked' + } +}) + +assert.equal(sayHi('test'), 'Hooked') \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..da2a510 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "allowSyntheticDefaultImports": true, + "noEmit": true + }, + "ts-node": { + "esm": true + } + }