diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5508c503..dfecf030 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,40 @@ permissions: contents: read jobs: + bun: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + + - name: Setup Bun + uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 + + - name: Install dependencies + run: bun install + + - name: Run unit tests + run: bun run typescript:bun + + deno: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + + - name: Setup Deno + uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb + + - name: Install dependencies + run: deno install + + - name: Run unit tests + run: deno run typescript:deno + test: permissions: contents: write diff --git a/lib/runtime.js b/lib/runtime.js index 9179a7af..bbcf03b2 100644 --- a/lib/runtime.js +++ b/lib/runtime.js @@ -36,6 +36,18 @@ function checkEnvVariable (name, value) { const runtime = {} // use Object.defineProperties to provide lazy load Object.defineProperties(runtime, { + bun: { + get () { + cache.bun ??= 'Bun' in globalThis + return cache.bun + } + }, + deno: { + get () { + cache.deno ??= 'Deno' in globalThis + return cache.deno + } + }, tsNode: { get () { cache.tsNode ??= ( @@ -108,6 +120,8 @@ Object.defineProperties(runtime, { get () { cache.supportTypeScript ??= ( checkEnvVariable('FASTIFY_AUTOLOAD_TYPESCRIPT') || + runtime.bun || + runtime.deno || runtime.tsNode || runtime.vitest || runtime.babelNode || diff --git a/package.json b/package.json index 8ff6cfeb..75fbef04 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "lint:fix": "eslint --fix", "test": "npm run typescript && npm run typescript:native && npm run typescript:jest && npm run typescript:swc-node-register && npm run typescript:tsm && npm run typescript:tsx && npm run typescript:vitest && npm run typescript:esbuild && npm run unit", "typescript": "tsd", + "typescript:bun": "bun scripts/unit-typescript-bun-esm.js", + "typescript:deno": "deno -A scripts/unit-typescript-deno-esm.js", "typescript:jest": "jest", "typescript:esm": "node scripts/unit-typescript-esm.js", "typescript:swc-node-register": "node scripts/unit-typescript-swc-node-register.js", @@ -75,8 +77,8 @@ "devDependencies": { "@fastify/url-data": "^6.0.0", "@jsumners/line-reporter": "^1.0.1", - "@swc-node/register": "^1.9.1", - "@swc/core": "^1.5.25", + "@swc-node/register": "1.11.1", + "@swc/core": "1.13.20", "@types/jest": "^30.0.0", "@types/node": "^24.0.8", "borp": "^0.20.0", @@ -96,7 +98,7 @@ "tsx": "^4.15.7", "typescript": "5.5", "vite": "^7.0.0", - "vitest": "^3.0.4" + "vitest": "^4.0.3" }, "jest": { "preset": "ts-jest", diff --git a/scripts/unit-typescript-bun-esm.js b/scripts/unit-typescript-bun-esm.js new file mode 100644 index 00000000..1a3aa96a --- /dev/null +++ b/scripts/unit-typescript-bun-esm.js @@ -0,0 +1,28 @@ +'use strict' + +const { exec } = require('node:child_process') +const { argv } = require('node:process') + +const args = [ + argv[0], + 'test', + './test/typescript-esm/forceESM.ts' +] + +const child = exec(args.join(' '), { + shell: true, + env: { + ...process.env, + TS_NODE_COMPILER_OPTIONS: JSON.stringify({ + module: 'ESNext', + target: 'ES2020', + allowJs: false, + moduleResolution: 'node', + esModuleInterop: true + }) + } +}) + +child.stdout.pipe(process.stdout) +child.stderr.pipe(process.stderr) +child.once('close', process.exit) diff --git a/scripts/unit-typescript-deno-esm.js b/scripts/unit-typescript-deno-esm.js new file mode 100644 index 00000000..f61d80b4 --- /dev/null +++ b/scripts/unit-typescript-deno-esm.js @@ -0,0 +1,29 @@ +'use strict' + +const { exec } = require('node:child_process') +const { argv } = require('node:process') + +const args = [ + argv[0], + 'test', + '-A', + './test/typescript-esm/forceESM.ts' +] + +const child = exec(args.join(' '), { + shell: true, + env: { + ...process.env, + TS_NODE_COMPILER_OPTIONS: JSON.stringify({ + module: 'ESNext', + target: 'ES2020', + allowJs: false, + moduleResolution: 'node', + esModuleInterop: true + }) + } +}) + +child.stdout.pipe(process.stdout) +child.stderr.pipe(process.stderr) +child.once('close', process.exit) diff --git a/scripts/unit-typescript-swc-node-register.js b/scripts/unit-typescript-swc-node-register.js index 2d9398d5..5d37e507 100644 --- a/scripts/unit-typescript-swc-node-register.js +++ b/scripts/unit-typescript-swc-node-register.js @@ -4,7 +4,8 @@ const { exec } = require('node:child_process') const args = [ 'node', - '--require=@swc-node/register', + '-r', + '@swc-node/register', 'test/typescript/basic.ts' ] diff --git a/test/typescript-esm/forceESM.ts b/test/typescript-esm/forceESM.ts index c694cfb7..a58d6752 100644 --- a/test/typescript-esm/forceESM.ts +++ b/test/typescript-esm/forceESM.ts @@ -1,4 +1,4 @@ -import test, { describe, before, after } from 'node:test' +import { describe, test } from 'node:test' import assert from 'node:assert' import fastify from 'fastify' @@ -10,18 +10,15 @@ const __dirname = dirname(fileURLToPath(import.meta.url)) describe('typescript/basic test suite', function () { const app = fastify() - before(async function () { + + test('should load routes and respond correctly', async function () { app.register(fastifyAutoLoad, { dir: resolve(__dirname, 'app'), forceESM: true }) await app.ready() - }) - after(async function () { - await app.close() - }) - - test('should load routes and respond correctly', async function () { const res = await app.inject({ url: '/installed' }) assert.strictEqual(res.statusCode, 200) assert.deepStrictEqual(JSON.parse(res.payload), { result: 'ok' }) + + await app.close() }) })