diff --git a/.gitattributes b/.gitattributes index 9778fb4..d0a55c4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,9 +10,5 @@ *.debug text eol=lf merge=union # Generated codes -index.js linguist-detectable=false -index.d.ts linguist-detectable=false -hyperjs.wasi-browser.js linguist-detectable=false -hyperjs.wasi.cjs linguist-detectable=false -wasi-worker-browser.mjs linguist-detectable=false -wasi-worker.mjs linguist-detectable=false +hyperjs-core/index.js linguist-detectable=false +hyperjs-core/index.d.ts linguist-detectable=false diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 436b455..2239d99 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -50,40 +50,60 @@ jobs: settings: - host: macos-latest target: x86_64-apple-darwin - build: yarn build --target x86_64-apple-darwin + build: yarn build:core --target x86_64-apple-darwin - host: windows-latest - build: yarn build --target x86_64-pc-windows-msvc + build: yarn build:core --target x86_64-pc-windows-msvc target: x86_64-pc-windows-msvc - host: windows-latest - build: yarn build --target i686-pc-windows-msvc + build: | + yarn build:core --target i686-pc-windows-msvc + yarn build:js target: i686-pc-windows-msvc - host: ubuntu-22.04 target: x86_64-unknown-linux-gnu - build: yarn build --target x86_64-unknown-linux-gnu + build: | + yarn build:core --target x86_64-unknown-linux-gnu + yarn build:js - host: ubuntu-latest target: x86_64-unknown-linux-musl - build: yarn build --target x86_64-unknown-linux-musl -x + build: | + yarn build:core --target x86_64-unknown-linux-musl -x + yarn build:js - host: macos-latest target: aarch64-apple-darwin - build: yarn build --target aarch64-apple-darwin + build: | + yarn build:core --target aarch64-apple-darwin + yarn build:js - host: ubuntu-22.04 target: aarch64-unknown-linux-gnu - build: yarn build --target aarch64-unknown-linux-gnu + build: | + yarn build:core --target aarch64-unknown-linux-gnu + yarn build:js - host: ubuntu-latest target: armv7-unknown-linux-gnueabihf - build: yarn build --target armv7-unknown-linux-gnueabihf --use-napi-cross + build: | + yarn build:core --target armv7-unknown-linux-gnueabihf --use-napi-cross + yarn build:js - host: ubuntu-latest target: aarch64-linux-android - build: yarn build --target aarch64-linux-android + build: | + yarn build:core --target aarch64-linux-android + yarn build:js - host: ubuntu-latest target: armv7-linux-androideabi - build: yarn build --target armv7-linux-androideabi + build: | + yarn build:core --target armv7-linux-androideabi + yarn build:js - host: ubuntu-latest target: aarch64-unknown-linux-musl - build: yarn build --target aarch64-unknown-linux-musl -x + build: | + yarn build:core --target aarch64-unknown-linux-musl -x + yarn build:js - host: windows-latest target: aarch64-pc-windows-msvc - build: yarn build --target aarch64-pc-windows-msvc + build: | + yarn build:core --target aarch64-pc-windows-msvc + yarn build:js name: stable - ${{ matrix.settings.target }} - node@22 runs-on: ${{ matrix.settings.host }} steps: @@ -152,8 +172,8 @@ jobs: with: name: bindings-${{ matrix.settings.target }} path: | - ${{ env.APP_NAME }}.*.node - ${{ env.APP_NAME }}.*.wasm + hyperjs-core/${{ env.APP_NAME }}.*.node + hyperjs-core/${{ env.APP_NAME }}.*.wasm if-no-files-found: error build-freebsd: runs-on: ubuntu-latest @@ -192,7 +212,8 @@ jobs: env freebsd-version yarn install - yarn build + yarn build:core + yarn build:js rm -rf node_modules rm -rf target rm -rf .yarn/cache @@ -200,7 +221,7 @@ jobs: uses: actions/upload-artifact@v6 with: name: bindings-freebsd - path: ${{ env.APP_NAME }}.*.node + path: hyperjs-core/${{ env.APP_NAME }}.*.node if-no-files-found: error test-macOS-windows-binding: name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }} @@ -240,7 +261,7 @@ jobs: uses: actions/download-artifact@v7 with: name: bindings-${{ matrix.settings.target }} - path: . + path: ./hyperjs-core - name: List packages run: ls -R . shell: bash @@ -298,7 +319,7 @@ jobs: uses: actions/download-artifact@v7 with: name: bindings-${{ matrix.target }} - path: . + path: ./hyperjs-core - name: List packages run: ls -R . shell: bash diff --git a/.husky/.gitignore b/.husky/.gitignore deleted file mode 100644 index 31354ec..0000000 --- a/.husky/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_ diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index d2ae35e..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -yarn lint-staged diff --git a/.prettierignore b/.prettierignore index 901e6b6..8120ecf 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,8 +1,4 @@ target .yarn -index.js -package-template.wasi-browser.js -package-template.wasi.cjs -wasi-worker-browser.mjs -wasi-worker.mjs +hyperjs-core/index.js .yarnrc.yml \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 5568270..8cdbac1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ rustls-acme = {version = "0.15.1", features = ["tokio"]} serde_json = "1.0.148" serde_qs = "1.0.0" serde_urlencoded = "0.7.1" +socket2 = "0.6.3" tempfile = "3.24.0" tokio-stream = {version = "0.1.18", features = ["net"]} urlencoding = "2.1.3" diff --git a/__test__/.yarn/install-state.gz b/__test__/.yarn/install-state.gz new file mode 100644 index 0000000..f0cf28e Binary files /dev/null and b/__test__/.yarn/install-state.gz differ diff --git a/__test__/health.spec.ts b/__test__/core/health.spec.ts similarity index 69% rename from __test__/health.spec.ts rename to __test__/core/health.spec.ts index 3e93f87..03756c9 100644 --- a/__test__/health.spec.ts +++ b/__test__/core/health.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from './server.js' +import * as server from '../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/middlewares/cookie_parser.spec.ts b/__test__/core/middlewares/cookie_parser.spec.ts similarity index 75% rename from __test__/middlewares/cookie_parser.spec.ts rename to __test__/core/middlewares/cookie_parser.spec.ts index 9acef99..4bb0db0 100644 --- a/__test__/middlewares/cookie_parser.spec.ts +++ b/__test__/core/middlewares/cookie_parser.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/middlewares/json.spec.ts b/__test__/core/middlewares/json.spec.ts similarity index 82% rename from __test__/middlewares/json.spec.ts rename to __test__/core/middlewares/json.spec.ts index 3a4b6af..1da2867 100644 --- a/__test__/middlewares/json.spec.ts +++ b/__test__/core/middlewares/json.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/middlewares/raw.spec.ts b/__test__/core/middlewares/raw.spec.ts similarity index 81% rename from __test__/middlewares/raw.spec.ts rename to __test__/core/middlewares/raw.spec.ts index 72f3eef..aaef72f 100644 --- a/__test__/middlewares/raw.spec.ts +++ b/__test__/core/middlewares/raw.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/middlewares/static.spec.ts b/__test__/core/middlewares/static.spec.ts similarity index 80% rename from __test__/middlewares/static.spec.ts rename to __test__/core/middlewares/static.spec.ts index 4e9e5cb..ad2b540 100644 --- a/__test__/middlewares/static.spec.ts +++ b/__test__/core/middlewares/static.spec.ts @@ -2,8 +2,9 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' import { readFileSync } from 'node:fs' import path, { dirname } from 'node:path' import { fileURLToPath } from 'node:url' @@ -13,9 +14,10 @@ const __dirname = dirname(__filename) let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) @@ -28,7 +30,7 @@ test('fetch index.html in the public directory', async (t) => { const res = await axios.get(`http://localhost:${port}/public/index.html`) // Don't store the full response object, just extract the data const data = res.data - let index_file_contents = readFileSync(path.join(__dirname, '../../public/index.html'), { encoding: 'utf-8' }) + let index_file_contents = readFileSync(path.join(__dirname, '../../../public/index.html'), { encoding: 'utf-8' }) t.is(data, index_file_contents) }) @@ -36,7 +38,7 @@ test('fetch alternative_index.html in the public directory', async (t) => { const res = await axios.get(`http://localhost:${port}/public/alternative_index.html`) // Don't store the full response object, just extract the data const data = res.data - let index_file_contents = readFileSync(path.join(__dirname, '../../public/alternative_index.html'), { + let index_file_contents = readFileSync(path.join(__dirname, '../../../public/alternative_index.html'), { encoding: 'utf-8', }) t.is(data, index_file_contents) diff --git a/__test__/middlewares/text.spec.ts b/__test__/core/middlewares/text.spec.ts similarity index 79% rename from __test__/middlewares/text.spec.ts rename to __test__/core/middlewares/text.spec.ts index f5654f3..457c228 100644 --- a/__test__/middlewares/text.spec.ts +++ b/__test__/core/middlewares/text.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/middlewares/urlencoded.spec.ts b/__test__/core/middlewares/urlencoded.spec.ts similarity index 83% rename from __test__/middlewares/urlencoded.spec.ts rename to __test__/core/middlewares/urlencoded.spec.ts index 8e35fb0..f8b6f1c 100644 --- a/__test__/middlewares/urlencoded.spec.ts +++ b/__test__/core/middlewares/urlencoded.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/request/accepts.spec.ts b/__test__/core/request/accepts.spec.ts similarity index 70% rename from __test__/request/accepts.spec.ts rename to __test__/core/request/accepts.spec.ts index cf4cc4d..5a195fc 100644 --- a/__test__/request/accepts.spec.ts +++ b/__test__/core/request/accepts.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Request } from '../../index' +import { Request } from '../../../hyperjs-core/index' test('accepts', (t) => { const req = new Request() diff --git a/__test__/request/method.spec.ts b/__test__/core/request/method.spec.ts similarity index 81% rename from __test__/request/method.spec.ts rename to __test__/core/request/method.spec.ts index e5b8a76..a3177eb 100644 --- a/__test__/request/method.spec.ts +++ b/__test__/core/request/method.spec.ts @@ -1,14 +1,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/request/range.spec.ts b/__test__/core/request/range.spec.ts similarity index 87% rename from __test__/request/range.spec.ts rename to __test__/core/request/range.spec.ts index 3a9f3be..1bd6163 100644 --- a/__test__/request/range.spec.ts +++ b/__test__/core/request/range.spec.ts @@ -1,14 +1,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/response/append.spec.ts b/__test__/core/response/append.spec.ts similarity index 89% rename from __test__/response/append.spec.ts rename to __test__/core/response/append.spec.ts index 457a320..19b6c4e 100644 --- a/__test__/response/append.spec.ts +++ b/__test__/core/response/append.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('append', (t) => { const res = new Response() diff --git a/__test__/response/attachment.spec.ts b/__test__/core/response/attachment.spec.ts similarity index 87% rename from __test__/response/attachment.spec.ts rename to __test__/core/response/attachment.spec.ts index 1458b56..af610eb 100644 --- a/__test__/response/attachment.spec.ts +++ b/__test__/core/response/attachment.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('attachment - no value', (t) => { const res = new Response() diff --git a/__test__/response/clear_cookie.spec.ts b/__test__/core/response/clear_cookie.spec.ts similarity index 82% rename from __test__/response/clear_cookie.spec.ts rename to __test__/core/response/clear_cookie.spec.ts index e6af6b2..7d1095a 100644 --- a/__test__/response/clear_cookie.spec.ts +++ b/__test__/core/response/clear_cookie.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('clearCookie', (t) => { let res = new Response() diff --git a/__test__/response/content_type.spec.ts b/__test__/core/response/content_type.spec.ts similarity index 92% rename from __test__/response/content_type.spec.ts rename to __test__/core/response/content_type.spec.ts index d4127ce..e9f60c5 100644 --- a/__test__/response/content_type.spec.ts +++ b/__test__/core/response/content_type.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('type', (t) => { const res = new Response() diff --git a/__test__/response/cookie.spec.ts b/__test__/core/response/cookie.spec.ts similarity index 96% rename from __test__/response/cookie.spec.ts rename to __test__/core/response/cookie.spec.ts index 92183c0..77d468e 100644 --- a/__test__/response/cookie.spec.ts +++ b/__test__/core/response/cookie.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('cookie - multiple', (t) => { const res = new Response() diff --git a/__test__/response/download.spec.ts b/__test__/core/response/download.spec.ts similarity index 77% rename from __test__/response/download.spec.ts rename to __test__/core/response/download.spec.ts index fd7c342..4909414 100644 --- a/__test__/response/download.spec.ts +++ b/__test__/core/response/download.spec.ts @@ -1,8 +1,9 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' import { readFileSync } from 'node:fs' import { fileURLToPath } from 'url' import { dirname } from 'path' @@ -13,9 +14,10 @@ const __dirname = dirname(__filename) let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) @@ -29,6 +31,6 @@ test('/download', async (t) => { const data = res.data const contentDispositionHeader = res.headers['content-disposition'] t.is(contentDispositionHeader, 'attachment; filename=".dotfile.html"') - let dotfile_contents = readFileSync(path.join(__dirname, '../../public/.dotfile.html'), { encoding: 'utf-8' }) + let dotfile_contents = readFileSync(path.join(__dirname, '../../../public/.dotfile.html'), { encoding: 'utf-8' }) t.is(data, dotfile_contents) }) diff --git a/__test__/response/end.spec.ts b/__test__/core/response/end.spec.ts similarity index 68% rename from __test__/response/end.spec.ts rename to __test__/core/response/end.spec.ts index 480c097..1e7c6b5 100644 --- a/__test__/response/end.spec.ts +++ b/__test__/core/response/end.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/response/format.spec.ts b/__test__/core/response/format.spec.ts similarity index 83% rename from __test__/response/format.spec.ts rename to __test__/core/response/format.spec.ts index 2ff2d05..b83181f 100644 --- a/__test__/response/format.spec.ts +++ b/__test__/core/response/format.spec.ts @@ -1,14 +1,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/response/links.spec.ts b/__test__/core/response/links.spec.ts similarity index 92% rename from __test__/response/links.spec.ts rename to __test__/core/response/links.spec.ts index 5dc0d68..d8dfd06 100644 --- a/__test__/response/links.spec.ts +++ b/__test__/core/response/links.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('links', (t) => { let res = new Response() diff --git a/__test__/response/location.spec.ts b/__test__/core/response/location.spec.ts similarity index 84% rename from __test__/response/location.spec.ts rename to __test__/core/response/location.spec.ts index 48f4e87..0824681 100644 --- a/__test__/response/location.spec.ts +++ b/__test__/core/response/location.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('location', (t) => { let res = new Response() diff --git a/__test__/response/redirect.spec.ts b/__test__/core/response/redirect.spec.ts similarity index 89% rename from __test__/response/redirect.spec.ts rename to __test__/core/response/redirect.spec.ts index 94964a9..0418257 100644 --- a/__test__/response/redirect.spec.ts +++ b/__test__/core/response/redirect.spec.ts @@ -2,14 +2,16 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios, { isAxiosError } from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) diff --git a/__test__/response/send_file.spec.ts b/__test__/core/response/send_file.spec.ts similarity index 84% rename from __test__/response/send_file.spec.ts rename to __test__/core/response/send_file.spec.ts index c677947..05f99db 100644 --- a/__test__/response/send_file.spec.ts +++ b/__test__/core/response/send_file.spec.ts @@ -1,8 +1,9 @@ import test from 'ava' import { ChildProcess } from 'node:child_process' import axios, { isAxiosError } from 'axios' +import { join } from 'node:path' -import * as server from '../server.js' +import * as server from '../../server-setup.js' import { readFileSync } from 'node:fs' import { fileURLToPath } from 'url' import { dirname } from 'path' @@ -13,9 +14,10 @@ const __dirname = dirname(__filename) let serverApp: ChildProcess let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') test.before(async () => { - const result = await server.start() + const result = await server.start(serverPath) serverApp = result.process port = result.port }) @@ -27,7 +29,7 @@ test.after.always(() => { test('/send-file - dotfiles = allow', async (t) => { const res = await axios.get(`http://localhost:${port}/send-file/allow/.dotfile.html`) const data = res.data - let dotfile_contents = readFileSync(path.join(__dirname, '../../public/.dotfile.html'), { encoding: 'utf-8' }) + let dotfile_contents = readFileSync(path.join(__dirname, '../../../public/.dotfile.html'), { encoding: 'utf-8' }) t.is(data, dotfile_contents) }) @@ -60,6 +62,6 @@ test('/send-file - dotfiles = ignore', async (t) => { test('/folder - dir default index', async (t) => { const res = await axios.get(`http://localhost:${port}/folder`) const data = res.data - let index_file_contents = readFileSync(path.join(__dirname, '../../public/index.html'), { encoding: 'utf-8' }) + let index_file_contents = readFileSync(path.join(__dirname, '../../../public/index.html'), { encoding: 'utf-8' }) t.is(data, index_file_contents) }) diff --git a/__test__/response/set.spec.ts b/__test__/core/response/set.spec.ts similarity index 93% rename from __test__/response/set.spec.ts rename to __test__/core/response/set.spec.ts index 92eeb42..3abdd38 100644 --- a/__test__/response/set.spec.ts +++ b/__test__/core/response/set.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('set - (string, string)', (t) => { let res = new Response() diff --git a/__test__/response/vary.spec.ts b/__test__/core/response/vary.spec.ts similarity index 84% rename from __test__/response/vary.spec.ts rename to __test__/core/response/vary.spec.ts index e8f6f91..73ba0a5 100644 --- a/__test__/response/vary.spec.ts +++ b/__test__/core/response/vary.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { Response } from '../../index' +import { Response } from '../../../hyperjs-core/index' test('vary', (t) => { let res = new Response() diff --git a/server.ts b/__test__/core/server.ts similarity index 99% rename from server.ts rename to __test__/core/server.ts index 2f4cf0d..277d249 100644 --- a/server.ts +++ b/__test__/core/server.ts @@ -10,7 +10,7 @@ import { FileStat, UrlencodedMiddleware, CookieParserMiddleware, -} from './index.js' +} from '../../hyperjs-core/index.js' import path from 'path' import process from 'process' diff --git a/__test__/utilities.spec.ts b/__test__/core/utilities.spec.ts similarity index 73% rename from __test__/utilities.spec.ts rename to __test__/core/utilities.spec.ts index b870d05..4cb4aff 100644 --- a/__test__/utilities.spec.ts +++ b/__test__/core/utilities.spec.ts @@ -1,6 +1,6 @@ import test from 'ava' -import { serializeNapiObject } from '../index' +import { serializeNapiObject } from '../../hyperjs-core/index' test('serializeNapiObject', (t) => { t.is(serializeNapiObject({}), '{}') diff --git a/__test__/package.json b/__test__/package.json index 3dbc1ca..cb671d8 100644 --- a/__test__/package.json +++ b/__test__/package.json @@ -1,3 +1,6 @@ { - "type": "module" + "type": "module", + "dependencies": { + "@types/node": "^25.6.0" + } } diff --git a/__test__/public/hello.server.ts b/__test__/public/hello.server.ts new file mode 100644 index 0000000..03756c9 --- /dev/null +++ b/__test__/public/hello.server.ts @@ -0,0 +1,27 @@ +// __test__/health.spec.ts +import test from 'ava' +import { ChildProcess } from 'node:child_process' +import axios from 'axios' +import { join } from 'node:path' + +import * as server from '../server-setup.js' + +let serverApp: ChildProcess +let port: number +const serverPath = join(process.cwd(), '__test__', 'core', 'server.ts') + +test.before(async () => { + const result = await server.start(serverPath) + serverApp = result.process + port = result.port +}) + +test.after.always(() => { + server.stop(serverApp) +}) + +test('/health', async (t) => { + const res = await axios.get(`http://localhost:${port}/health`) + const data = res.data + t.is(data, 'OK') +}) diff --git a/__test__/server.ts b/__test__/server-setup.ts similarity index 90% rename from __test__/server.ts rename to __test__/server-setup.ts index 9b2f569..f5ef57c 100644 --- a/__test__/server.ts +++ b/__test__/server-setup.ts @@ -1,13 +1,11 @@ import { ChildProcess, spawn } from 'node:child_process' -import { join } from 'node:path' import { pathToFileURL } from 'node:url' import { createRequire } from 'node:module' const require = createRequire(import.meta.url) -async function start(): Promise<{ process: ChildProcess; port: number }> { +async function start(serverPath: string): Promise<{ process: ChildProcess; port: number }> { const port = Math.floor(Math.random() * 10000) + 10000 - const serverPath = join(process.cwd(), 'server.ts') // Let Node find the correct path to the tsx package automatically const tsxEntry = require.resolve('tsx') diff --git a/__test__/tsconfig.json b/__test__/tsconfig.json index ec0d2a6..42b1815 100644 --- a/__test__/tsconfig.json +++ b/__test__/tsconfig.json @@ -4,14 +4,9 @@ "module": "ESNext", "moduleResolution": "Bundler", "outDir": "lib", - "rootDir": "." + "rootDir": ".", + "types": ["node"] }, - "include": [ - "**/*.spec.ts" - // "response/format.spec.ts", - // "response/redirect.spec.ts", - // "response/end.spec.ts", - // "middlewares/text.spec.ts" - ], + "include": ["**/*.ts"], "exclude": ["lib"] } diff --git a/__test__/yarn.lock b/__test__/yarn.lock new file mode 100644 index 0000000..045efcb --- /dev/null +++ b/__test__/yarn.lock @@ -0,0 +1,30 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@types/node@npm:^25.6.0": + version: 25.6.0 + resolution: "@types/node@npm:25.6.0" + dependencies: + undici-types: "npm:~7.19.0" + checksum: 10c0/d2d2015630ff098a201407f55f5077a20270ae4f465c739b40865cd9933b91b9c5d2b85568eadaf3db0801b91e267333ca7eb39f007428b173d1cdab4b339ac5 + languageName: node + linkType: hard + +"root-workspace-0b6124@workspace:.": + version: 0.0.0-use.local + resolution: "root-workspace-0b6124@workspace:." + dependencies: + "@types/node": "npm:^25.6.0" + languageName: unknown + linkType: soft + +"undici-types@npm:~7.19.0": + version: 7.19.2 + resolution: "undici-types@npm:7.19.2" + checksum: 10c0/7159f10546f9f6c47d36776bb1bbf8671e87c1e587a6fee84ae1f111ae8de4f914efa8ca0dfcd224f4f4a9dfc3f6028f627ccb5ddaccf82d7fd54671b89fac3e + languageName: node + linkType: hard diff --git a/benchmark/bench.ts b/benchmark/bench.ts deleted file mode 100644 index 7761e87..0000000 --- a/benchmark/bench.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Bench } from 'tinybench' - -import { plus100 } from '../index.js' - -function add(a: number) { - return a + 100 -} - -const b = new Bench() - -b.add('Native a + 100', () => { - plus100(10) -}) - -b.add('JavaScript a + 100', () => { - add(10) -}) - -await b.run() - -console.table(b.table()) diff --git a/benchmark/package.json b/benchmark/package.json deleted file mode 100644 index 3dbc1ca..0000000 --- a/benchmark/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json deleted file mode 100644 index e95988d..0000000 --- a/benchmark/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "moduleResolution": "NodeNext", - "module": "NodeNext", - "outDir": "lib" - }, - "include": ["."], - "exclude": ["lib"] -} diff --git a/browser.js b/browser.js deleted file mode 100644 index 58f8a57..0000000 --- a/browser.js +++ /dev/null @@ -1 +0,0 @@ -export * from 'hyperjs-wasm32-wasi' diff --git a/examples/hello.js b/examples/hello.js new file mode 100644 index 0000000..ad2b8dc --- /dev/null +++ b/examples/hello.js @@ -0,0 +1,11 @@ +const hyperjs = require('../index') +const app = hyperjs() +const port = 3000 + +app.get('/', (req, res) => { + res.send('Hello World!') +}) + +app.listen(port, () => { + console.log(`Example app listening on port ${port}`) +}) diff --git a/hyperjs-core/dts-header.d.ts b/hyperjs-core/dts-header.d.ts new file mode 100644 index 0000000..9a72cea --- /dev/null +++ b/hyperjs-core/dts-header.d.ts @@ -0,0 +1,3 @@ +export type JsHandlerFn = (req: Request, res: Response) => boolean | void | Promise +export type JsVerifyFn = (req: Request, res: Response, buf: Buffer, encoding: String) => void +export type JsSetHeadersFn = (res: Response, path: string, stat: any) => void diff --git a/index.d.ts b/hyperjs-core/index.d.ts similarity index 95% rename from index.d.ts rename to hyperjs-core/index.d.ts index e8c83ad..4d9bfa8 100644 --- a/index.d.ts +++ b/hyperjs-core/index.d.ts @@ -1,5 +1,6 @@ -/* auto-generated by NAPI-RS */ -/* eslint-disable */ +export type JsHandlerFn = (req: Request, res: Response) => boolean | void | Promise +export type JsVerifyFn = (req: Request, res: Response, buf: Buffer, encoding: String) => void +export type JsSetHeadersFn = (res: Response, path: string, stat: any) => void export declare class Bytes { constructor() static fromOwner(owner: Buffer): Bytes @@ -763,6 +764,8 @@ export declare class Response { /** HTTP Server that integrates with JavaScript handlers via Router */ export declare class Server { + listenIpc(options: IpcServerListenOptions, callback: ListenCallbackFn): void + listenTcp(options: TcpServerListenOptions, callback: ListenCallbackFn): void /** Create a new server with a router */ constructor() delete(route: string, handler: JsHandlerFn): void @@ -981,6 +984,23 @@ export interface DownloadOptions { immutable?: boolean } +export interface IpcServerListenOptions { + /** + * Unix domain socket path the server should listen on. + * + * Ignored if [`port`] is also specified — TCP takes precedence. + * + * Defaults to `None`. + * + * [`port`]: Self::port + */ + path: string + /** Makes the pipe readable for all users. Default: false. */ + readableAll?: boolean + /** Makes the pipe writable for all users. Default: false. */ + writableAll?: boolean +} + export interface JsCookieParserOptions { /** * If `true`, the cookie value will be percent-decoded @@ -1325,6 +1345,9 @@ export interface JsUrlencodedOptions { depth?: number } +export type ListenCallbackFn<> = + (arg: Error | undefined | null) => void + /** Represents a single byte range with start and end positions */ export interface Range { start: number @@ -1354,3 +1377,53 @@ export interface SendFileOptions { } export declare function serializeNapiObject(obj: object): string + +export interface TcpServerListenOptions { + /** + * The maximum number of pending connections that can be queued before the OS + * starts refusing new ones. Passed directly to the underlying `listen(2)` syscall. + * + * A value of `0` lets the OS choose a reasonable default. + * + * Default = 0 + */ + backlog?: number + /** + * The local address the server will bind to. + * + * Defaults to `"0.0.0.0"` (all IPv4 interfaces) when [`ipv6_only`] is `false`, + * or `"::"` (all IPv6 interfaces) when [`ipv6_only`] is `true`. + * + * [`ipv6_only`]: Self::ipv6_only + */ + host?: string + /** + * When `true`, opens an IPv6-only socket (`AF_INET6` with `IPV6_V6ONLY` enabled), + * rejecting any IPv4 connections. When `false` (the default), a dual-stack socket + * is used that accepts both IPv4 and IPv6 connections. + * + * Defaults to `false`. + */ + ipv6Only?: boolean + /** + * When `true`, sets `SO_REUSEPORT` on the socket, allowing multiple sockets to + * bind to the same address and port. Useful for load-balancing incoming connections + * across several threads or processes. + * + * Not supported on all platforms (e.g. older Windows versions). + * + * Defaults to `false`. + */ + reusePort?: boolean + /** + * The TCP port the server should bind to. When set, takes precedence over [`path`]. + * + * A value of `0` asks the OS to assign an available ephemeral port, which can then + * be retrieved after binding. + * + * Defaults to `0`. + * + * [`path`]: Self::path + */ + port?: number +} diff --git a/hyperjs-core/index.js b/hyperjs-core/index.js new file mode 100644 index 0000000..e6af579 --- /dev/null +++ b/hyperjs-core/index.js @@ -0,0 +1,592 @@ +// prettier-ignore +/* eslint-disable */ +// @ts-nocheck +/* auto-generated by NAPI-RS */ + +const { readFileSync } = require('node:fs') +let nativeBinding = null +const loadErrors = [] + +const isMusl = () => { + let musl = false + if (process.platform === 'linux') { + musl = isMuslFromFilesystem() + if (musl === null) { + musl = isMuslFromReport() + } + if (musl === null) { + musl = isMuslFromChildProcess() + } + } + return musl +} + +const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') + +const isMuslFromFilesystem = () => { + try { + return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') + } catch { + return null + } +} + +const isMuslFromReport = () => { + let report = null + if (typeof process.report?.getReport === 'function') { + process.report.excludeNetwork = true + report = process.report.getReport() + } + if (!report) { + return null + } + if (report.header && report.header.glibcVersionRuntime) { + return false + } + if (Array.isArray(report.sharedObjects)) { + if (report.sharedObjects.some(isFileMusl)) { + return true + } + } + return false +} + +const isMuslFromChildProcess = () => { + try { + return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') + } catch (e) { + // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false + return false + } +} + +function requireNative() { + if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) { + try { + return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH); + } catch (err) { + loadErrors.push(err) + } + } else if (process.platform === 'android') { + if (process.arch === 'arm64') { + try { + return require('./hyperjs.android-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-android-arm64') + const bindingPackageVersion = require('@saltcorn/hyperjs-android-arm64/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm') { + try { + return require('./hyperjs.android-arm-eabi.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-android-arm-eabi') + const bindingPackageVersion = require('@saltcorn/hyperjs-android-arm-eabi/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) + } + } else if (process.platform === 'win32') { + if (process.arch === 'x64') { + if (process.config?.variables?.shlib_suffix === 'dll.a' || process.config?.variables?.node_target_type === 'shared_library') { + try { + return require('./hyperjs.win32-x64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-win32-x64-gnu') + const bindingPackageVersion = require('@saltcorn/hyperjs-win32-x64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./hyperjs.win32-x64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-win32-x64-msvc') + const bindingPackageVersion = require('@saltcorn/hyperjs-win32-x64-msvc/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'ia32') { + try { + return require('./hyperjs.win32-ia32-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-win32-ia32-msvc') + const bindingPackageVersion = require('@saltcorn/hyperjs-win32-ia32-msvc/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./hyperjs.win32-arm64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-win32-arm64-msvc') + const bindingPackageVersion = require('@saltcorn/hyperjs-win32-arm64-msvc/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) + } + } else if (process.platform === 'darwin') { + try { + return require('./hyperjs.darwin-universal.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-darwin-universal') + const bindingPackageVersion = require('@saltcorn/hyperjs-darwin-universal/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + if (process.arch === 'x64') { + try { + return require('./hyperjs.darwin-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-darwin-x64') + const bindingPackageVersion = require('@saltcorn/hyperjs-darwin-x64/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./hyperjs.darwin-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-darwin-arm64') + const bindingPackageVersion = require('@saltcorn/hyperjs-darwin-arm64/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) + } + } else if (process.platform === 'freebsd') { + if (process.arch === 'x64') { + try { + return require('./hyperjs.freebsd-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-freebsd-x64') + const bindingPackageVersion = require('@saltcorn/hyperjs-freebsd-x64/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./hyperjs.freebsd-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-freebsd-arm64') + const bindingPackageVersion = require('@saltcorn/hyperjs-freebsd-arm64/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) + } + } else if (process.platform === 'linux') { + if (process.arch === 'x64') { + if (isMusl()) { + try { + return require('./hyperjs.linux-x64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-x64-musl') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-x64-musl/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./hyperjs.linux-x64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-x64-gnu') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-x64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'arm64') { + if (isMusl()) { + try { + return require('./hyperjs.linux-arm64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-arm64-musl') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm64-musl/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./hyperjs.linux-arm64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-arm64-gnu') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'arm') { + if (isMusl()) { + try { + return require('./hyperjs.linux-arm-musleabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-arm-musleabihf') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm-musleabihf/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./hyperjs.linux-arm-gnueabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-arm-gnueabihf') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm-gnueabihf/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'loong64') { + if (isMusl()) { + try { + return require('./hyperjs.linux-loong64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-loong64-musl') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-loong64-musl/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./hyperjs.linux-loong64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-loong64-gnu') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-loong64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'riscv64') { + if (isMusl()) { + try { + return require('./hyperjs.linux-riscv64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-riscv64-musl') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-riscv64-musl/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./hyperjs.linux-riscv64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-riscv64-gnu') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-riscv64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'ppc64') { + try { + return require('./hyperjs.linux-ppc64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-ppc64-gnu') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-ppc64-gnu/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 's390x') { + try { + return require('./hyperjs.linux-s390x-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-linux-s390x-gnu') + const bindingPackageVersion = require('@saltcorn/hyperjs-linux-s390x-gnu/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) + } + } else if (process.platform === 'openharmony') { + if (process.arch === 'arm64') { + try { + return require('./hyperjs.openharmony-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-openharmony-arm64') + const bindingPackageVersion = require('@saltcorn/hyperjs-openharmony-arm64/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'x64') { + try { + return require('./hyperjs.openharmony-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-openharmony-x64') + const bindingPackageVersion = require('@saltcorn/hyperjs-openharmony-x64/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm') { + try { + return require('./hyperjs.openharmony-arm.node') + } catch (e) { + loadErrors.push(e) + } + try { + const binding = require('@saltcorn/hyperjs-openharmony-arm') + const bindingPackageVersion = require('@saltcorn/hyperjs-openharmony-arm/package.json').version + if (bindingPackageVersion !== '0.1.0' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { + throw new Error(`Native binding package version mismatch, expected 0.1.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) + } + return binding + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`)) + } + } else { + loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) + } +} + +nativeBinding = requireNative() + +if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { + let wasiBinding = null + let wasiBindingError = null + try { + wasiBinding = require('./hyperjs.wasi.cjs') + nativeBinding = wasiBinding + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + wasiBindingError = err + } + } + if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { + try { + wasiBinding = require('@saltcorn/hyperjs-wasm32-wasi') + nativeBinding = wasiBinding + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + if (!wasiBindingError) { + wasiBindingError = err + } else { + wasiBindingError.cause = err + } + loadErrors.push(err) + } + } + } + if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) { + const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error') + error.cause = wasiBindingError + throw error + } +} + +if (!nativeBinding) { + if (loadErrors.length > 0) { + throw new Error( + `Cannot find native binding. ` + + `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` + + 'Please try `npm i` again after removing both package-lock.json and node_modules directory.', + { + cause: loadErrors.reduce((err, cur) => { + cur.cause = err + return cur + }), + }, + ) + } + throw new Error(`Failed to load native binding`) +} + +module.exports = nativeBinding +module.exports.Bytes = nativeBinding.Bytes +module.exports.CookieParserMiddleware = nativeBinding.CookieParserMiddleware +module.exports.FileStat = nativeBinding.FileStat +module.exports.JsonMiddleware = nativeBinding.JsonMiddleware +module.exports.RawMiddleware = nativeBinding.RawMiddleware +module.exports.Request = nativeBinding.Request +module.exports.Response = nativeBinding.Response +module.exports.Server = nativeBinding.Server +module.exports.StaticMiddleware = nativeBinding.StaticMiddleware +module.exports.StatusCode = nativeBinding.StatusCode +module.exports.TextMiddleware = nativeBinding.TextMiddleware +module.exports.UrlencodedMiddleware = nativeBinding.UrlencodedMiddleware +module.exports.Version = nativeBinding.Version +module.exports.serializeNapiObject = nativeBinding.serializeNapiObject diff --git a/hyperjs-core/package.json b/hyperjs-core/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/hyperjs-core/package.json @@ -0,0 +1 @@ +{} diff --git a/hyperjs.wasi-browser.js b/hyperjs.wasi-browser.js deleted file mode 100644 index 95deb56..0000000 --- a/hyperjs.wasi-browser.js +++ /dev/null @@ -1,72 +0,0 @@ -import { - createOnMessage as __wasmCreateOnMessageForFsProxy, - getDefaultContext as __emnapiGetDefaultContext, - instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync, - WASI as __WASI, -} from '@napi-rs/wasm-runtime' - - - -const __wasi = new __WASI({ - version: 'preview1', -}) - -const __wasmUrl = new URL('./hyperjs.wasm32-wasi.wasm', import.meta.url).href -const __emnapiContext = __emnapiGetDefaultContext() - - -const __sharedMemory = new WebAssembly.Memory({ - initial: 4000, - maximum: 65536, - shared: true, -}) - -const __wasmFile = await fetch(__wasmUrl).then((res) => res.arrayBuffer()) - -const { - instance: __napiInstance, - module: __wasiModule, - napiModule: __napiModule, -} = __emnapiInstantiateNapiModuleSync(__wasmFile, { - context: __emnapiContext, - asyncWorkPoolSize: 4, - wasi: __wasi, - onCreateWorker() { - const worker = new Worker(new URL('./wasi-worker-browser.mjs', import.meta.url), { - type: 'module', - }) - - return worker - }, - overwriteImports(importObject) { - importObject.env = { - ...importObject.env, - ...importObject.napi, - ...importObject.emnapi, - memory: __sharedMemory, - } - return importObject - }, - beforeInit({ instance }) { - for (const name of Object.keys(instance.exports)) { - if (name.startsWith('__napi_register__')) { - instance.exports[name]() - } - } - }, -}) -export default __napiModule.exports -export const Bytes = __napiModule.exports.Bytes -export const CookieParserMiddleware = __napiModule.exports.CookieParserMiddleware -export const FileStat = __napiModule.exports.FileStat -export const JsonMiddleware = __napiModule.exports.JsonMiddleware -export const RawMiddleware = __napiModule.exports.RawMiddleware -export const Request = __napiModule.exports.Request -export const Response = __napiModule.exports.Response -export const Server = __napiModule.exports.Server -export const StaticMiddleware = __napiModule.exports.StaticMiddleware -export const StatusCode = __napiModule.exports.StatusCode -export const TextMiddleware = __napiModule.exports.TextMiddleware -export const UrlencodedMiddleware = __napiModule.exports.UrlencodedMiddleware -export const Version = __napiModule.exports.Version -export const serializeNapiObject = __napiModule.exports.serializeNapiObject diff --git a/hyperjs.wasi.cjs b/hyperjs.wasi.cjs deleted file mode 100644 index 634a0c8..0000000 --- a/hyperjs.wasi.cjs +++ /dev/null @@ -1,124 +0,0 @@ -/* eslint-disable */ -/* prettier-ignore */ - -/* auto-generated by NAPI-RS */ - -const __nodeFs = require('node:fs') -const __nodePath = require('node:path') -const { WASI: __nodeWASI } = require('node:wasi') -const { Worker } = require('node:worker_threads') - -const { - createOnMessage: __wasmCreateOnMessageForFsProxy, - getDefaultContext: __emnapiGetDefaultContext, - instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync, -} = require('@napi-rs/wasm-runtime') - -const __rootDir = __nodePath.parse(process.cwd()).root - -const __wasi = new __nodeWASI({ - version: 'preview1', - env: process.env, - preopens: { - [__rootDir]: __rootDir, - } -}) - -const __emnapiContext = __emnapiGetDefaultContext() - -const __sharedMemory = new WebAssembly.Memory({ - initial: 4000, - maximum: 65536, - shared: true, -}) - -let __wasmFilePath = __nodePath.join(__dirname, 'hyperjs.wasm32-wasi.wasm') -const __wasmDebugFilePath = __nodePath.join(__dirname, 'hyperjs.wasm32-wasi.debug.wasm') - -if (__nodeFs.existsSync(__wasmDebugFilePath)) { - __wasmFilePath = __wasmDebugFilePath -} else if (!__nodeFs.existsSync(__wasmFilePath)) { - try { - __wasmFilePath = require.resolve('hyperjs-wasm32-wasi/hyperjs.wasm32-wasi.wasm') - } catch { - throw new Error('Cannot find hyperjs.wasm32-wasi.wasm file, and hyperjs-wasm32-wasi package is not installed.') - } -} - -const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), { - context: __emnapiContext, - asyncWorkPoolSize: (function() { - const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE) - // NaN > 0 is false - if (threadsSizeFromEnv > 0) { - return threadsSizeFromEnv - } else { - return 4 - } - })(), - reuseWorker: true, - wasi: __wasi, - onCreateWorker() { - const worker = new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), { - env: process.env, - }) - worker.onmessage = ({ data }) => { - __wasmCreateOnMessageForFsProxy(__nodeFs)(data) - } - - // The main thread of Node.js waits for all the active handles before exiting. - // But Rust threads are never waited without `thread::join`. - // So here we hack the code of Node.js to prevent the workers from being referenced (active). - // According to https://github.com/nodejs/node/blob/19e0d472728c79d418b74bddff588bea70a403d0/lib/internal/worker.js#L415, - // a worker is consist of two handles: kPublicPort and kHandle. - { - const kPublicPort = Object.getOwnPropertySymbols(worker).find(s => - s.toString().includes("kPublicPort") - ); - if (kPublicPort) { - worker[kPublicPort].ref = () => {}; - } - - const kHandle = Object.getOwnPropertySymbols(worker).find(s => - s.toString().includes("kHandle") - ); - if (kHandle) { - worker[kHandle].ref = () => {}; - } - - worker.unref(); - } - return worker - }, - overwriteImports(importObject) { - importObject.env = { - ...importObject.env, - ...importObject.napi, - ...importObject.emnapi, - memory: __sharedMemory, - } - return importObject - }, - beforeInit({ instance }) { - for (const name of Object.keys(instance.exports)) { - if (name.startsWith('__napi_register__')) { - instance.exports[name]() - } - } - }, -}) -module.exports = __napiModule.exports -module.exports.Bytes = __napiModule.exports.Bytes -module.exports.CookieParserMiddleware = __napiModule.exports.CookieParserMiddleware -module.exports.FileStat = __napiModule.exports.FileStat -module.exports.JsonMiddleware = __napiModule.exports.JsonMiddleware -module.exports.RawMiddleware = __napiModule.exports.RawMiddleware -module.exports.Request = __napiModule.exports.Request -module.exports.Response = __napiModule.exports.Response -module.exports.Server = __napiModule.exports.Server -module.exports.StaticMiddleware = __napiModule.exports.StaticMiddleware -module.exports.StatusCode = __napiModule.exports.StatusCode -module.exports.TextMiddleware = __napiModule.exports.TextMiddleware -module.exports.UrlencodedMiddleware = __napiModule.exports.UrlencodedMiddleware -module.exports.Version = __napiModule.exports.Version -module.exports.serializeNapiObject = __napiModule.exports.serializeNapiObject diff --git a/index.js b/index.js index be2e07e..c46c558 100644 --- a/index.js +++ b/index.js @@ -1,592 +1,9 @@ -// prettier-ignore -/* eslint-disable */ -// @ts-nocheck -/* auto-generated by NAPI-RS */ - -const { readFileSync } = require('node:fs') -let nativeBinding = null -const loadErrors = [] - -const isMusl = () => { - let musl = false - if (process.platform === 'linux') { - musl = isMuslFromFilesystem() - if (musl === null) { - musl = isMuslFromReport() - } - if (musl === null) { - musl = isMuslFromChildProcess() - } - } - return musl -} - -const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') - -const isMuslFromFilesystem = () => { - try { - return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') - } catch { - return null - } -} - -const isMuslFromReport = () => { - let report = null - if (typeof process.report?.getReport === 'function') { - process.report.excludeNetwork = true - report = process.report.getReport() - } - if (!report) { - return null - } - if (report.header && report.header.glibcVersionRuntime) { - return false - } - if (Array.isArray(report.sharedObjects)) { - if (report.sharedObjects.some(isFileMusl)) { - return true - } - } - return false -} - -const isMuslFromChildProcess = () => { - try { - return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') - } catch (e) { - // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false - return false - } -} - -function requireNative() { - if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) { - try { - return require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH); - } catch (err) { - loadErrors.push(err) - } - } else if (process.platform === 'android') { - if (process.arch === 'arm64') { - try { - return require('./hyperjs.android-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-android-arm64') - const bindingPackageVersion = require('@saltcorn/hyperjs-android-arm64/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm') { - try { - return require('./hyperjs.android-arm-eabi.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-android-arm-eabi') - const bindingPackageVersion = require('@saltcorn/hyperjs-android-arm-eabi/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) - } - } else if (process.platform === 'win32') { - if (process.arch === 'x64') { - if (process.config?.variables?.shlib_suffix === 'dll.a' || process.config?.variables?.node_target_type === 'shared_library') { - try { - return require('./hyperjs.win32-x64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-win32-x64-gnu') - const bindingPackageVersion = require('@saltcorn/hyperjs-win32-x64-gnu/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./hyperjs.win32-x64-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-win32-x64-msvc') - const bindingPackageVersion = require('@saltcorn/hyperjs-win32-x64-msvc/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'ia32') { - try { - return require('./hyperjs.win32-ia32-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-win32-ia32-msvc') - const bindingPackageVersion = require('@saltcorn/hyperjs-win32-ia32-msvc/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm64') { - try { - return require('./hyperjs.win32-arm64-msvc.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-win32-arm64-msvc') - const bindingPackageVersion = require('@saltcorn/hyperjs-win32-arm64-msvc/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) - } - } else if (process.platform === 'darwin') { - try { - return require('./hyperjs.darwin-universal.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-darwin-universal') - const bindingPackageVersion = require('@saltcorn/hyperjs-darwin-universal/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - if (process.arch === 'x64') { - try { - return require('./hyperjs.darwin-x64.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-darwin-x64') - const bindingPackageVersion = require('@saltcorn/hyperjs-darwin-x64/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm64') { - try { - return require('./hyperjs.darwin-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-darwin-arm64') - const bindingPackageVersion = require('@saltcorn/hyperjs-darwin-arm64/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) - } - } else if (process.platform === 'freebsd') { - if (process.arch === 'x64') { - try { - return require('./hyperjs.freebsd-x64.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-freebsd-x64') - const bindingPackageVersion = require('@saltcorn/hyperjs-freebsd-x64/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm64') { - try { - return require('./hyperjs.freebsd-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-freebsd-arm64') - const bindingPackageVersion = require('@saltcorn/hyperjs-freebsd-arm64/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) - } - } else if (process.platform === 'linux') { - if (process.arch === 'x64') { - if (isMusl()) { - try { - return require('./hyperjs.linux-x64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-x64-musl') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-x64-musl/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./hyperjs.linux-x64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-x64-gnu') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-x64-gnu/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'arm64') { - if (isMusl()) { - try { - return require('./hyperjs.linux-arm64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-arm64-musl') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm64-musl/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./hyperjs.linux-arm64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-arm64-gnu') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm64-gnu/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'arm') { - if (isMusl()) { - try { - return require('./hyperjs.linux-arm-musleabihf.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-arm-musleabihf') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm-musleabihf/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./hyperjs.linux-arm-gnueabihf.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-arm-gnueabihf') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-arm-gnueabihf/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'loong64') { - if (isMusl()) { - try { - return require('./hyperjs.linux-loong64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-loong64-musl') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-loong64-musl/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./hyperjs.linux-loong64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-loong64-gnu') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-loong64-gnu/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'riscv64') { - if (isMusl()) { - try { - return require('./hyperjs.linux-riscv64-musl.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-riscv64-musl') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-riscv64-musl/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - try { - return require('./hyperjs.linux-riscv64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-riscv64-gnu') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-riscv64-gnu/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } - } else if (process.arch === 'ppc64') { - try { - return require('./hyperjs.linux-ppc64-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-ppc64-gnu') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-ppc64-gnu/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 's390x') { - try { - return require('./hyperjs.linux-s390x-gnu.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-linux-s390x-gnu') - const bindingPackageVersion = require('@saltcorn/hyperjs-linux-s390x-gnu/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) - } - } else if (process.platform === 'openharmony') { - if (process.arch === 'arm64') { - try { - return require('./hyperjs.openharmony-arm64.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-openharmony-arm64') - const bindingPackageVersion = require('@saltcorn/hyperjs-openharmony-arm64/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'x64') { - try { - return require('./hyperjs.openharmony-x64.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-openharmony-x64') - const bindingPackageVersion = require('@saltcorn/hyperjs-openharmony-x64/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else if (process.arch === 'arm') { - try { - return require('./hyperjs.openharmony-arm.node') - } catch (e) { - loadErrors.push(e) - } - try { - const binding = require('@saltcorn/hyperjs-openharmony-arm') - const bindingPackageVersion = require('@saltcorn/hyperjs-openharmony-arm/package.json').version - if (bindingPackageVersion !== '1.0.4' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { - throw new Error(`Native binding package version mismatch, expected 1.0.4 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) - } - return binding - } catch (e) { - loadErrors.push(e) - } - } else { - loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`)) - } - } else { - loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) - } -} - -nativeBinding = requireNative() - -if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { - let wasiBinding = null - let wasiBindingError = null - try { - wasiBinding = require('./hyperjs.wasi.cjs') - nativeBinding = wasiBinding - } catch (err) { - if (process.env.NAPI_RS_FORCE_WASI) { - wasiBindingError = err - } - } - if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { - try { - wasiBinding = require('@saltcorn/hyperjs-wasm32-wasi') - nativeBinding = wasiBinding - } catch (err) { - if (process.env.NAPI_RS_FORCE_WASI) { - if (!wasiBindingError) { - wasiBindingError = err - } else { - wasiBindingError.cause = err - } - loadErrors.push(err) - } - } - } - if (process.env.NAPI_RS_FORCE_WASI === 'error' && !wasiBinding) { - const error = new Error('WASI binding not found and NAPI_RS_FORCE_WASI is set to error') - error.cause = wasiBindingError - throw error - } -} - -if (!nativeBinding) { - if (loadErrors.length > 0) { - throw new Error( - `Cannot find native binding. ` + - `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` + - 'Please try `npm i` again after removing both package-lock.json and node_modules directory.', - { - cause: loadErrors.reduce((err, cur) => { - cur.cause = err - return cur - }), - }, - ) - } - throw new Error(`Failed to load native binding`) -} - -module.exports = nativeBinding -module.exports.Bytes = nativeBinding.Bytes -module.exports.CookieParserMiddleware = nativeBinding.CookieParserMiddleware -module.exports.FileStat = nativeBinding.FileStat -module.exports.JsonMiddleware = nativeBinding.JsonMiddleware -module.exports.RawMiddleware = nativeBinding.RawMiddleware -module.exports.Request = nativeBinding.Request -module.exports.Response = nativeBinding.Response -module.exports.Server = nativeBinding.Server -module.exports.StaticMiddleware = nativeBinding.StaticMiddleware -module.exports.StatusCode = nativeBinding.StatusCode -module.exports.TextMiddleware = nativeBinding.TextMiddleware -module.exports.UrlencodedMiddleware = nativeBinding.UrlencodedMiddleware -module.exports.Version = nativeBinding.Version -module.exports.serializeNapiObject = nativeBinding.serializeNapiObject +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const index_1 = require("./hyperjs-core/index"); +const hyper_js_1 = require("./src-ts/hyper_js"); +function hyperjs() { + return new hyper_js_1.HyperJs(); +} +exports.default = hyperjs; +module.exports = Object.assign(hyperjs, { Request: index_1.Request, Response: index_1.Response }); diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..93e6781 --- /dev/null +++ b/index.ts @@ -0,0 +1,9 @@ +import { Request, Response } from './hyperjs-core/index' +import { HyperJs } from './src-ts/hyper_js' + +function hyperjs() { + return new HyperJs() +} + +export default hyperjs +module.exports = Object.assign(hyperjs, { Request, Response }) diff --git a/package.json b/package.json index 5279137..afbb7ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@saltcorn/hyperjs", - "version": "1.0.4", + "version": "0.1.0", "description": "Template project for writing node package with napi-rs", "main": "index.js", "repository": { @@ -19,8 +19,7 @@ ], "files": [ "index.d.ts", - "index.js", - "browser.js" + "index.js" ], "napi": { "binaryName": "hyperjs", @@ -38,7 +37,8 @@ "aarch64-unknown-linux-musl", "aarch64-pc-windows-msvc", "armv7-linux-androideabi" - ] + ], + "dtsHeaderFile": "hyperjs-core/dts-header.d.ts" }, "engines": { "node": ">= 6.14.2 < 7 || >= 8.11.2 < 9 || >= 9.11.0 < 10 || >= 10.0.0" @@ -49,9 +49,9 @@ }, "scripts": { "artifacts": "napi artifacts", - "bench": "node --import @oxc-node/core/register benchmark/bench.ts", - "build": "napi build --platform --release", - "build:debug": "napi build --platform", + "build:js": "tsc -p ./tsconfig.json", + "build:core": "napi build --output-dir hyperjs-core --platform --release", + "build:debug": "napi build --output-dir hyperjs-core --platform", "format": "run-p format:prettier format:rs format:toml", "format:prettier": "prettier . -w", "format:toml": "taplo format", @@ -59,9 +59,8 @@ "lint": "oxlint .", "prepublishOnly": "napi prepublish -t npm", "test": "ava", - "preversion": "napi build --platform && git add .", - "version": "napi version", - "prepare": "husky" + "preversion": "napi build --output-dir hyperjs-core --platform && git add .", + "version": "napi version" }, "devDependencies": { "@emnapi/core": "^1.5.0", @@ -71,7 +70,7 @@ "@taplo/cli": "^0.7.0", "@tybys/wasm-util": "^0.10.0", "@types/node": "^25.0.3", - "ava": "^6.4.1", + "ava": "^7.0.0", "axios": "^1.13.2", "chalk": "^5.6.2", "husky": "^9.1.7", @@ -82,7 +81,7 @@ "tinybench": "^6.0.0", "tree-kill": "^1.2.2", "tsx": "^4.21.0", - "typescript": "^5.9.2" + "typescript": "^6.0.2" }, "lint-staged": { "*.@(js|ts|tsx)": [ @@ -116,5 +115,10 @@ "singleQuote": true, "arrowParens": "always" }, - "packageManager": "yarn@4.12.0" + "packageManager": "yarn@4.12.0", + "dependencies": { + "@types/express": "^5.0.6", + "@types/express-serve-static-core": "^5.1.1", + "@types/qs": "^6.15.0" + } } diff --git a/src-ts/hyper_js.js b/src-ts/hyper_js.js new file mode 100644 index 0000000..523e6e3 --- /dev/null +++ b/src-ts/hyper_js.js @@ -0,0 +1,52 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HyperJs = void 0; +const index_1 = require("../hyperjs-core/index"); +class HyperJs { + listen() { + const args = Array.prototype.slice.call(arguments); + const done = typeof args[args.length - 1] === 'function' ? args[args.length - 1] : () => { }; + let rsServer = new index_1.Server(); + // (port, hostname, backlog[, callback]) + if (typeof args[0] === 'number' && typeof args[1] === 'string' && typeof args[2] === 'number') { + const options = { + port: args[0], + host: args[1], + backlog: args[2], + }; + rsServer.listenTcp(options, done); + } + // (port, hostname[, callback]) + else if (typeof args[0] === 'number' && typeof args[1] === 'string') { + const options = { + port: args[0], + host: args[1], + }; + rsServer.listenTcp(options, done); + } + // (port[, callback]) + else if (typeof args[0] === 'number') { + const options = { + port: args[0], + }; + rsServer.listenTcp(options, done); + } + // (path[, callback]) + else if (typeof args[0] === 'string') { + const options = { + path: args[0], + }; + rsServer.listenIpc(options, done); + } + // ([callback]) + else if (done) { + rsServer.listenTcp({}, done); + } + // (handle, listeningListener) + else { + throw new Error('Listening on handle is not supported in this implementation'); + } + return rsServer; + } +} +exports.HyperJs = HyperJs; diff --git a/src-ts/hyper_js.ts b/src-ts/hyper_js.ts new file mode 100644 index 0000000..ce12b9a --- /dev/null +++ b/src-ts/hyper_js.ts @@ -0,0 +1,157 @@ +import { + Server as RsServer, + TcpServerListenOptions, + IpcServerListenOptions, + ListenCallbackFn, +} from '../hyperjs-core/index' +import type { IRouter, IRouterMatcher } from 'express-serve-static-core' + +type IRouterPartial = { + get: IRouterMatcher +} + +class HyperJs implements IRouterPartial { + /** + * Listen for connections. + */ + listen(port: number, hostname: string, backlog: number, callback?: ListenCallbackFn): RsServer + listen(port: number, hostname: string, callback?: ListenCallbackFn): RsServer + listen(port: number, callback?: ListenCallbackFn): RsServer + listen(callback?: ListenCallbackFn): RsServer + listen(path: string, callback?: ListenCallbackFn): RsServer + listen(handle: any, listeningListener?: ListenCallbackFn): RsServer + + listen(): RsServer { + const args = Array.prototype.slice.call(arguments) + const done: ListenCallbackFn = typeof args[args.length - 1] === 'function' ? args[args.length - 1] : () => {} + let rsServer: RsServer = new RsServer() + + // (port, hostname, backlog[, callback]) + if (typeof args[0] === 'number' && typeof args[1] === 'string' && typeof args[2] === 'number') { + const options: TcpServerListenOptions = { + port: args[0], + host: args[1], + backlog: args[2], + } + rsServer.listenTcp(options, done) + } + // (port, hostname[, callback]) + else if (typeof args[0] === 'number' && typeof args[1] === 'string') { + const options: TcpServerListenOptions = { + port: args[0], + host: args[1], + } + rsServer.listenTcp(options, done) + } + // (port[, callback]) + else if (typeof args[0] === 'number') { + const options: TcpServerListenOptions = { + port: args[0], + } + rsServer.listenTcp(options, done) + } + // (path[, callback]) + else if (typeof args[0] === 'string') { + const options: IpcServerListenOptions = { + path: args[0], + } + rsServer.listenIpc(options, done) + } + // ([callback]) + else if (done) { + rsServer.listenTcp({}, done) + } + // (handle, listeningListener) + else { + throw new Error('Listening on handle is not supported in this implementation') + } + + return rsServer + } + + // get + // 1. (string | regex, ...) + // ... = one or more + // - (req, res, next): unknown | RequestHandler + // | Request.params has properties extracted from path + // + // 2. (string | regex, ...) + // ... = one or more + // - (req, res, next): unknown | RequestHandler + // | Request.params has properties extracted from path + // + // - (err, req, res, next) | ErrorRequestHandler + // | Request.params has properties extracted from path + // + // - (RequestHandler | ErrorRequestHandler)[] | An Array containing a mixture of RequestHandlers and ErrorRequestHandlers + // | Request.params has properties extracted from path + // + // 3. (string | regex | (string | regex)[], ...) + // - (req, res, next): unknown | RequestHandler + // | Request.params = { number: string; string: string; string: string[] } + // + // 4. (string | regex | (string | regex)[], ...) + // ... = one or more + // - (req, res, next): unknown | RequestHandler + // | Request.params = { number: string; string: string; string: string[] } + // + // - (err, req, res, next) | ErrorRequestHandler + // | Request.params = { number: string; string: string; string: string[] } + // + // - (RequestHandler | ErrorRequestHandler)[] | An Array containing a mixture of RequestHandlers and ErrorRequestHandlers + // | Request.params = { number: string; string: string; string: string[] } + // + // 5. (string | regex | (string | regex)[], Application) + get(...args: any[]): IRouterPartial { + // Here are three tricky things I need to be mindful of: + // 1. Flattening Arrays: + // In cases 2, 4, and 5, users can pass nested arrays of middleware + // handlers. I need to flatten them into a single-level list of + // functions. + // + // 2. Identifying Error Handlers: + // Normal handlers take 3 arguments (req, res, next). Error handlers + // take 4 arguments (err, req, res, next). JavaScript lets me check + // this at runtime using fn.length. + // + // 3. Handling Sub-Applications: + // Case 5 passes a sub-app instead of callback functions. + const path = args[0] + const rawHandlers = args.slice(1) + + // 1. Flatten any nested arrays from signatures 2 and 4 + const flattenedHandlers = rawHandlers.flat(Infinity) + + // 2. Check if signature 5 was used (mounting a sub-application) + if (flattenedHandlers.length === 1 && typeof flattenedHandlers[0] === 'object') { + const subApp = flattenedHandlers[0] + // Pass the sub-app mounting logic to your Rust backend + // this.rsServer.mountSubApp(path, subApp); + return this + } + + // 3. Separate standard handlers from error handlers using fn.length + const normalHandlers = [] + const errorHandlers = [] + + for (const handler of flattenedHandlers) { + if (typeof handler === 'function') { + if (handler.length === 4) { + // (err, req, res, next) -> ErrorRequestHandler + errorHandlers.push(handler) + } else { + // (req, res, next) -> RequestHandler + normalHandlers.push(handler) + } + } + } + + // 4. Pass the cleaned data to your Rust Napi bindings + // Example: + // this.rsServer.registerGetRoute(path, normalHandlers, errorHandlers); + + return this + } +} + +export { HyperJs } diff --git a/src/server/_listen_tcp.rs b/src/server/_listen_tcp.rs new file mode 100644 index 0000000..a90c0c9 --- /dev/null +++ b/src/server/_listen_tcp.rs @@ -0,0 +1,109 @@ +use env_logger::Builder as EnvLoggerBuilder; +use futures::prelude::*; + +use hyper::rt::{Read, Write}; +use hyper::{server::conn::http1, service::service_fn}; +use hyper_util::rt::tokio::{TokioIo, TokioTimer}; +use log::LevelFilter; +use matchit::Router; +use napi::bindgen_prelude::*; +use napi::threadsafe_function::ThreadsafeFunctionCallMode; +use rustls_acme::AcmeConfig; +use rustls_acme::caches::DirCache; +use std::sync::Arc; +use tokio::net::TcpListener; +use tokio_stream::wrappers::TcpListenerStream; + +use super::{MiddlewareMeta, Server, ThreadsafeCallbackFn, handle_http_request}; + +impl Server { + pub(super) fn _listen_tcp(&self, create_tcp_listener: F, callback: ThreadsafeCallbackFn) + where + F: FnOnce() -> Fut + Send + 'static, + Fut: Future> + Send, + { + let router = Arc::new(self.router.clone()); + let middlewares = Arc::new(self.middlewares.clone()); + let acme_config_meta = self.acme_config_meta.clone(); + + EnvLoggerBuilder::new() + .filter_level(LevelFilter::max()) + .init(); + + std::thread::spawn(move || { + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async move { + let tcp_listener = create_tcp_listener().await.unwrap(); + let addr = tcp_listener.local_addr().unwrap(); + let server_status_message = format!("Server listening on {}", addr); + log::debug!("{server_status_message}"); + + #[cfg(unix)] + systemd_notify(&server_status_message); + + callback.call(None, ThreadsafeFunctionCallMode::Blocking); + + match acme_config_meta { + Some(acme) => { + let tcp_stream = TcpListenerStream::new(tcp_listener); + + let mut tls_incoming = AcmeConfig::new(acme.domains) + .contact_push(format!("mailto:{}", acme.contact_email)) + .cache(DirCache::new(acme.cache_dir)) + .tokio_incoming(tcp_stream, Vec::new()); + + while let Some(tls) = tls_incoming.next().await { + let tls = match tls { + Ok(t) => t, + Err(e) => { + log::error!("TLS accept error: {}", e); + continue; + } + }; + + let io = TokioIo::new(tls); + let router = router.clone(); + let middlewares = middlewares.clone(); + + create_handler_task(io, router, middlewares); + } + } + None => loop { + let (socket, _) = tcp_listener.accept().await.unwrap(); + let io = TokioIo::new(socket); + let router = router.clone(); + let middlewares = middlewares.clone(); + + create_handler_task(Box::new(io), router, middlewares); + }, + } + }); + }); + } +} + +#[cfg(unix)] +fn systemd_notify(server_status_message: &str) { + use sd_notify::{NotifyState, notify}; + if let Err(e) = notify(&[NotifyState::Ready]) { + log::error!("Failed to notify systemd: {}", e); + } + + let _ = notify(&[NotifyState::Status(server_status_message)]); +} + +fn create_handler_task( + io: I, + router: Arc>, + middlewares: Arc>, +) { + tokio::task::spawn(async move { + let _ = http1::Builder::new() + .timer(TokioTimer::new()) + .serve_connection( + io, + service_fn(move |req| handle_http_request(req, router.clone(), middlewares.clone())), + ) + .await; + }); +} diff --git a/src/server/create_handler_task.rs b/src/server/create_handler_task.rs new file mode 100644 index 0000000..4f371d4 --- /dev/null +++ b/src/server/create_handler_task.rs @@ -0,0 +1,23 @@ +use hyper::rt::{Read, Write}; +use hyper::{server::conn::http1, service::service_fn}; +use hyper_util::rt::tokio::TokioTimer; +use matchit::Router; +use std::sync::Arc; + +use super::{MiddlewareMeta, handle_http_request::handle_http_request}; + +pub fn create_handler_task( + io: I, + router: Arc>, + middlewares: Arc>, +) { + tokio::task::spawn(async move { + let _ = http1::Builder::new() + .timer(TokioTimer::new()) + .serve_connection( + io, + service_fn(move |req| handle_http_request(req, router.clone(), middlewares.clone())), + ) + .await; + }); +} diff --git a/src/server/listen_ipc.rs b/src/server/listen_ipc.rs new file mode 100644 index 0000000..b242027 --- /dev/null +++ b/src/server/listen_ipc.rs @@ -0,0 +1,211 @@ +#[cfg(unix)] +use std::path::Path; +use std::sync::Arc; +#[cfg(unix)] +use std::{fs::Permissions, os::unix::fs::PermissionsExt}; + +use env_logger::Builder as EnvLoggerBuilder; +use hyper_util::rt::TokioIo; +use log::LevelFilter; +use napi::{ + bindgen_prelude::*, + threadsafe_function::{ThreadsafeCallContext, ThreadsafeFunctionCallMode}, +}; +use napi_derive::napi; +#[cfg(unix)] +use tokio::net::UnixListener; +#[cfg(windows)] +use tokio::net::windows::named_pipe::ServerOptions; + +#[cfg(unix)] +use super::systemd_notify::systemd_notify; +use super::{Server, create_handler_task::create_handler_task}; +use crate::server::{ListenCallbackFn, ThreadsafeCallbackFn}; + +#[napi(object)] +pub struct IpcServerListenOptions { + /// Unix domain socket path the server should listen on. + /// + /// Ignored if [`port`] is also specified — TCP takes precedence. + /// + /// Defaults to `None`. + /// + /// [`port`]: Self::port + pub path: String, + + /// Makes the pipe readable for all users. Default: false. + pub readable_all: Option, + + /// Makes the pipe writable for all users. Default: false. + pub writable_all: Option, +} + +#[cfg(unix)] +struct SetSocketPermissionsParams> { + path: P, + readable_all: bool, + writeable_all: bool, +} + +#[cfg(unix)] +fn set_socket_permissions>(params: SetSocketPermissionsParams

) -> Result<()> { + let permissions_mode = match (params.readable_all, params.writeable_all) { + // owner read+write only + (false, false) => 0o600, + + // all users read+write — necessary for non-owner clients to connect + (true, true) => 0o666, + + // read without write is insufficient for clients to connect to a Unix socket + (true, false) => { + return Err(Error::from_reason( + "Invalid combination (readable_all = true, writeable_all = false): + connecting to a Unix socket requires both read and write permissions, + so granting read alone to all users does not enable them to connect.", + )); + } + + // write without read is insufficient for clients to connect to a Unix socket + (false, true) => { + return Err(Error::from_reason( + "Invalid combination (readable_all = false, writeable_all = true): + connecting to a Unix socket requires both read and write permissions, + so granting write alone to all users does not enable them to connect.", + )); + } + }; + let perm = Permissions::from_mode(permissions_mode); + std::fs::set_permissions(params.path, perm)?; + Ok(()) +} + +fn setup_logging() { + EnvLoggerBuilder::new() + .filter_level(LevelFilter::max()) + .init(); +} + +#[napi] +impl Server { + #[cfg(unix)] + pub fn _listen_ipc_unix( + &self, + options: IpcServerListenOptions, + callback: ThreadsafeCallbackFn, + ) -> Result<()> { + let ipc_listener = UnixListener::bind(&options.path) + .map_err(|e| Error::from_reason(format!("Error creating IPC listener. {e}")))?; + + set_socket_permissions(SetSocketPermissionsParams { + path: options.path.to_owned(), + readable_all: options.readable_all.unwrap_or_default(), + writeable_all: options.writable_all.unwrap_or_default(), + })?; + + log::info!("IPC server listening on {}", options.path); + + let router = Arc::new(self.router.clone()); + let middlewares = Arc::new(self.middlewares.clone()); + + setup_logging(); + + std::thread::spawn(move || { + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async move { + let addr = ipc_listener.local_addr().unwrap(); + let mut addr_str = addr.as_pathname().and_then(|p| p.to_str()); + #[cfg(all(unix, not(any(target_vendor = "apple", target_os = "freebsd"))))] + { + addr_str = addr_str.or( + addr + .as_abstract_name() + .and_then(|bytes| std::str::from_utf8(bytes).ok()), + ); + } + let addr = addr_str.unwrap_or_default(); + let server_status_message = format!("Server listening on '{}'", addr); + log::debug!("{server_status_message}"); + + systemd_notify(&server_status_message); + + callback.call(None, ThreadsafeFunctionCallMode::Blocking); + + loop { + let (stream, _) = ipc_listener.accept().await.unwrap(); + let io = TokioIo::new(stream); + let router = router.clone(); + let middlewares = middlewares.clone(); + + create_handler_task(Box::new(io), router, middlewares); + } + }); + }); + + Ok(()) + } + + #[cfg(windows)] + pub fn _listen_ipc_windows( + &self, + options: IpcServerListenOptions, + callback: ThreadsafeCallbackFn, + ) -> Result<()> { + let router = Arc::new(self.router.clone()); + let middlewares = Arc::new(self.middlewares.clone()); + let pipe_path = options.path.clone(); + + setup_logging(); + + let mut server = ServerOptions::new() + .first_pipe_instance(true) + .create(options.path)?; + + std::thread::spawn(move || { + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async move { + callback.call(pipe_path.to_owned(), ThreadsafeFunctionCallMode::Blocking); + + loop { + server.connect().await.unwrap(); + let connected_client = server; + + // Construct the next server to be connected before sending the one + // we already have of onto a task. This ensures that the server + // isn't closed (after it's done in the task) before a new one is + // available. Otherwise the client might error with + // `io::ErrorKind::NotFound`. + server = ServerOptions::new().create(pipe_path.clone()).unwrap(); + let io = TokioIo::new(connected_client); + let router = router.clone(); + let middlewares = middlewares.clone(); + + create_handler_task(io, router, middlewares); + } + }); + }); + + Ok(()) + } + + #[napi] + pub fn listen_ipc( + &self, + options: IpcServerListenOptions, + callback: ListenCallbackFn, + ) -> Result<()> { + let ts_callback = callback.build_threadsafe_function().build_callback( + |ctx: ThreadsafeCallContext>| { + #[allow(clippy::unit_arg)] + Ok(ctx.value) + }, + )?; + + #[cfg(unix)] + self._listen_ipc_unix(options, ts_callback)?; + + #[cfg(windows)] + self._listen_ipc_windows(options, ts_callback)?; + + Ok(()) + } +} diff --git a/src/server/listen_tcp.rs b/src/server/listen_tcp.rs new file mode 100644 index 0000000..f6ed489 --- /dev/null +++ b/src/server/listen_tcp.rs @@ -0,0 +1,181 @@ +use std::{ + future, + net::{IpAddr, SocketAddr}, +}; + +use napi::{ + bindgen_prelude::*, + threadsafe_function::{ThreadsafeCallContext, ThreadsafeFunctionCallMode}, +}; +use napi_derive::napi; +use socket2::{Domain, Protocol, Socket, Type}; +use tokio::net::TcpListener; + +use super::{ListenCallbackFn, Server}; + +#[napi(object)] +pub struct TcpServerListenOptions { + /// The maximum number of pending connections that can be queued before the OS + /// starts refusing new ones. Passed directly to the underlying `listen(2)` syscall. + /// + /// A value of `0` lets the OS choose a reasonable default. + /// + /// Default = 0 + pub backlog: Option, + + /// The local address the server will bind to. + /// + /// Defaults to `"0.0.0.0"` (all IPv4 interfaces) when [`ipv6_only`] is `false`, + /// or `"::"` (all IPv6 interfaces) when [`ipv6_only`] is `true`. + /// + /// [`ipv6_only`]: Self::ipv6_only + pub host: Option, + + /// When `true`, opens an IPv6-only socket (`AF_INET6` with `IPV6_V6ONLY` enabled), + /// rejecting any IPv4 connections. When `false` (the default), a dual-stack socket + /// is used that accepts both IPv4 and IPv6 connections. + /// + /// Defaults to `false`. + pub ipv6_only: Option, + + /// When `true`, sets `SO_REUSEPORT` on the socket, allowing multiple sockets to + /// bind to the same address and port. Useful for load-balancing incoming connections + /// across several threads or processes. + /// + /// Not supported on all platforms (e.g. older Windows versions). + /// + /// Defaults to `false`. + pub reuse_port: Option, + + /// The TCP port the server should bind to. When set, takes precedence over [`path`]. + /// + /// A value of `0` asks the OS to assign an available ephemeral port, which can then + /// be retrieved after binding. + /// + /// Defaults to `0`. + /// + /// [`path`]: Self::path + pub port: Option, +} + +pub struct LibTcpServerListenOptions { + backlog: i32, + host: String, + ipv6_only: bool, + #[cfg(all(unix, windows))] + reuse_port: bool, + port: u16, +} + +impl From for LibTcpServerListenOptions { + fn from(options: TcpServerListenOptions) -> Self { + Self { + backlog: options.backlog.unwrap_or(0) as i32, + host: match options.ipv6_only.unwrap_or_default() { + true => "::".to_owned(), + false => "0.0.0.0".to_owned(), + }, + ipv6_only: options.ipv6_only.unwrap_or_default(), + #[cfg(all(unix, windows))] + reuse_port: options.ipv6_only.unwrap_or_default(), + port: options.port.unwrap_or(0), + } + } +} + +fn host_to_ip_addr(host: &str) -> Result { + host + .parse() + .map_err(|e| Error::new(Status::InvalidArg, format!("Invalid host: {e}"))) +} + +struct CreateTcpSocketParams { + #[cfg(all(unix, windows))] + reuse_port: bool, + ipv6_only: bool, +} + +fn create_tcp_socket(params: CreateTcpSocketParams) -> Result { + let domain = match params.ipv6_only { + true => Domain::IPV6, + false => Domain::IPV4, + }; + let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP)) + .map_err(|e| Error::from_reason(e.to_string()))?; + socket + .set_only_v6(params.ipv6_only) + .map_err(|e| Error::from_reason(e.to_string()))?; + #[cfg(all(unix, windows))] + socket + .set_reuse_port(params.reuse_port) + .map_err(|e| Error::from_reason(e.to_string()))?; + Ok(socket) +} + +struct CreateTcpListenerParams { + addr: SocketAddr, + backlog: i32, + socket: CreateTcpSocketParams, +} + +fn create_tcp_listener(params: CreateTcpListenerParams) -> Result { + let socket = create_tcp_socket(params.socket)?; + socket + .bind(¶ms.addr.into()) + .map_err(|e| Error::from_reason(e.to_string()))?; + socket + .listen(params.backlog) + .map_err(|e| Error::from_reason(e.to_string()))?; + TcpListener::from_std(socket.into()).map_err(|e| Error::from_reason(e.to_string())) +} + +#[napi] +impl Server { + #[napi] + pub fn listen_tcp( + &self, + options: TcpServerListenOptions, + callback: ListenCallbackFn, + ) -> Result<()> { + let options: LibTcpServerListenOptions = options.into(); + + let ts_callback = callback.build_threadsafe_function().build_callback( + |ctx: ThreadsafeCallContext>| { + #[allow(clippy::unit_arg)] + Ok(ctx.value) + }, + )?; + + let ip_addr = match host_to_ip_addr(&options.host) { + Ok(ip_addr) => ip_addr, + Err(e) => { + ts_callback.call(Some(e), ThreadsafeFunctionCallMode::NonBlocking); + return Ok(()); + } + }; + + let create_tcp_listener_params = CreateTcpListenerParams { + addr: SocketAddr::from((ip_addr, options.port)), + backlog: options.backlog, + socket: CreateTcpSocketParams { + ipv6_only: options.ipv6_only, + #[cfg(all(unix, windows))] + reuse_port: options.reuse_port, + }, + }; + + let tcp_listener = match create_tcp_listener(create_tcp_listener_params) { + Ok(tcp_listener) => tcp_listener, + Err(e) => { + ts_callback.call(Some(e), ThreadsafeFunctionCallMode::NonBlocking); + return Ok(()); + } + }; + + let create_tcp_listener = move || future::ready(Ok(tcp_listener)); + + self._listen_tcp(create_tcp_listener, ts_callback); + + Ok(()) + } +} diff --git a/src/server/mod.rs b/src/server/mod.rs index bcfefef..21e5ada 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,32 +1,44 @@ +mod _listen_tcp; +mod create_handler_task; mod get_next_id; mod handle_http_request; +mod listen_ipc; +mod listen_tcp; +mod register_middleware; +mod register_route; +mod systemd_notify; use env_logger::Builder as EnvLoggerBuilder; use futures::prelude::*; use hyper::Method as LibMethod; -use hyper::{server::conn::http1, service::service_fn}; -use hyper_util::rt::tokio::{TokioIo, TokioTimer}; +use hyper_util::rt::TokioIo; use log::LevelFilter; -use matchit::{InsertError, Router}; +use matchit::Router; use napi::bindgen_prelude::*; -use napi::threadsafe_function::{ThreadsafeCallContext, ThreadsafeFunction}; +use napi::threadsafe_function::ThreadsafeFunction; use napi_derive::napi; use rustls_acme::AcmeConfig; use rustls_acme::caches::DirCache; +use std::net::ToSocketAddrs; +use std::os::unix::net::SocketAddr; use std::sync::Arc; use tokio::net::TcpListener; use tokio_stream::wrappers::TcpListenerStream; use crate::request::Request; use crate::response::Response; +use create_handler_task::create_handler_task; use handle_http_request::handle_http_request; +use listen_tcp::TcpServerListenOptions; +#[cfg(unix)] +use systemd_notify::systemd_notify; // Global state for pending requests lazy_static::lazy_static! { static ref NEXT_ID: Arc> = Arc::new(std::sync::Mutex::new(0)); } -type JsHandlerFn<'a> = +pub type JsHandlerFn<'a> = Function<'a, FnArgs<(Request, Response)>, Either, Promise>>>; type ThreadsafeMiddlewareFn = ThreadsafeFunction< @@ -39,6 +51,12 @@ type ThreadsafeMiddlewareFn = ThreadsafeFunction< 0, >; +type ThreadsafeCallbackFn = + ThreadsafeFunction, (), Option, Status, false, false, 0>; + +#[napi] +pub type ListenCallbackFn<'a> = Function<'a, Option, ()>; + #[derive(Clone)] pub struct MiddlewareMeta { /// The string used to register the middleware in the router. @@ -79,48 +97,6 @@ pub struct Server { acme_config_meta: Option, } -impl Server { - fn register_middleware( - &mut self, - route: Option, - handler: JsHandlerFn, - _env: Env, - ) -> Result<()> { - let tsfn = handler - .build_threadsafe_function() - .build_callback(|ctx: ThreadsafeCallContext>| Ok(ctx.value))?; - self.middlewares.push(MiddlewareMeta { - route, - handler: Arc::new(tsfn), - method: None, - }); - Ok(()) - } - - fn register_route( - &mut self, - route: String, - handler: JsHandlerFn, - method: LibMethod, - ) -> Result<()> { - let tsfn = handler - .build_threadsafe_function() - .build_callback(|ctx: ThreadsafeCallContext>| Ok(ctx.value))?; - if let Err(e) = self.router.insert(route.to_owned(), route.to_owned()) { - match e { - InsertError::Conflict { .. } => {} - _ => return Err(Error::new(Status::GenericFailure, e.to_string())), - } - } - self.middlewares.push(MiddlewareMeta { - route: Some(route), - handler: Arc::new(tsfn), - method: Some(method), - }); - Ok(()) - } -} - #[napi] impl Server { /// Create a new server with a router @@ -181,14 +157,7 @@ impl Server { log::debug!("{server_status_message}"); #[cfg(unix)] - { - use sd_notify::{NotifyState, notify}; - if let Err(e) = notify(&[NotifyState::Ready]) { - log::error!("Failed to notify systemd: {}", e); - } - - let _ = notify(&[NotifyState::Status(&server_status_message)]); - } + systemd_notify(&server_status_message); match acme_config_meta { Some(acme) => { @@ -212,17 +181,7 @@ impl Server { let router = router.clone(); let middlewares = middlewares.clone(); - tokio::task::spawn(async move { - let _ = http1::Builder::new() - .timer(TokioTimer::new()) - .serve_connection( - io, - service_fn(move |req| { - handle_http_request(req, router.clone(), middlewares.clone()) - }), - ) - .await; - }); + create_handler_task(io, router, middlewares); } } None => loop { @@ -231,17 +190,7 @@ impl Server { let router = router.clone(); let middlewares = middlewares.clone(); - tokio::task::spawn(async move { - let _ = http1::Builder::new() - .timer(TokioTimer::new()) - .serve_connection( - io, - service_fn(move |req| { - handle_http_request(req, router.clone(), middlewares.clone()) - }), - ) - .await; - }); + create_handler_task(Box::new(io), router, middlewares); }, } }); diff --git a/src/server/register_middleware.rs b/src/server/register_middleware.rs new file mode 100644 index 0000000..545d7ac --- /dev/null +++ b/src/server/register_middleware.rs @@ -0,0 +1,26 @@ +use napi::bindgen_prelude::*; +use napi::threadsafe_function::ThreadsafeCallContext; +use std::sync::Arc; + +use super::{JsHandlerFn, MiddlewareMeta, Server}; +use crate::request::Request; +use crate::response::Response; + +impl Server { + pub(super) fn register_middleware( + &mut self, + route: Option, + handler: JsHandlerFn, + _env: Env, + ) -> Result<()> { + let tsfn = handler + .build_threadsafe_function() + .build_callback(|ctx: ThreadsafeCallContext>| Ok(ctx.value))?; + self.middlewares.push(MiddlewareMeta { + route, + handler: Arc::new(tsfn), + method: None, + }); + Ok(()) + } +} diff --git a/src/server/register_route.rs b/src/server/register_route.rs new file mode 100644 index 0000000..7eb6168 --- /dev/null +++ b/src/server/register_route.rs @@ -0,0 +1,34 @@ +use hyper::Method as LibMethod; +use matchit::InsertError; +use napi::bindgen_prelude::*; +use napi::threadsafe_function::ThreadsafeCallContext; +use std::sync::Arc; + +use super::{JsHandlerFn, MiddlewareMeta, Server}; +use crate::request::Request; +use crate::response::Response; + +impl Server { + pub(super) fn register_route( + &mut self, + route: String, + handler: JsHandlerFn, + method: LibMethod, + ) -> Result<()> { + let tsfn = handler + .build_threadsafe_function() + .build_callback(|ctx: ThreadsafeCallContext>| Ok(ctx.value))?; + if let Err(e) = self.router.insert(route.to_owned(), route.to_owned()) { + match e { + InsertError::Conflict { .. } => {} + _ => return Err(Error::new(Status::GenericFailure, e.to_string())), + } + } + self.middlewares.push(MiddlewareMeta { + route: Some(route), + handler: Arc::new(tsfn), + method: Some(method), + }); + Ok(()) + } +} diff --git a/src/server/systemd_notify.rs b/src/server/systemd_notify.rs new file mode 100644 index 0000000..803bd8a --- /dev/null +++ b/src/server/systemd_notify.rs @@ -0,0 +1,11 @@ +#[cfg(unix)] +pub fn systemd_notify(server_status_message: &str) { + { + use sd_notify::{NotifyState, notify}; + if let Err(e) = notify(&[NotifyState::Ready]) { + log::error!("Failed to notify systemd: {}", e); + } + + let _ = notify(&[NotifyState::Status(server_status_message)]); + } +} diff --git a/tsconfig.json b/tsconfig.json index 5056788..b36fc56 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,8 +2,9 @@ "compilerOptions": { "target": "ESNext", "strict": true, - "moduleResolution": "node", - "module": "CommonJS", + "moduleResolution": "NodeNext", + "module": "NodeNext", + "types": ["node"], "noUnusedLocals": true, "noUnusedParameters": true, "esModuleInterop": true, diff --git a/wasi-worker-browser.mjs b/wasi-worker-browser.mjs deleted file mode 100644 index 8b1b172..0000000 --- a/wasi-worker-browser.mjs +++ /dev/null @@ -1,32 +0,0 @@ -import { instantiateNapiModuleSync, MessageHandler, WASI } from '@napi-rs/wasm-runtime' - -const handler = new MessageHandler({ - onLoad({ wasmModule, wasmMemory }) { - const wasi = new WASI({ - print: function () { - // eslint-disable-next-line no-console - console.log.apply(console, arguments) - }, - printErr: function() { - // eslint-disable-next-line no-console - console.error.apply(console, arguments) - }, - }) - return instantiateNapiModuleSync(wasmModule, { - childThread: true, - wasi, - overwriteImports(importObject) { - importObject.env = { - ...importObject.env, - ...importObject.napi, - ...importObject.emnapi, - memory: wasmMemory, - } - }, - }) - }, -}) - -globalThis.onmessage = function (e) { - handler.handle(e) -} diff --git a/wasi-worker.mjs b/wasi-worker.mjs deleted file mode 100644 index 84b448f..0000000 --- a/wasi-worker.mjs +++ /dev/null @@ -1,63 +0,0 @@ -import fs from "node:fs"; -import { createRequire } from "node:module"; -import { parse } from "node:path"; -import { WASI } from "node:wasi"; -import { parentPort, Worker } from "node:worker_threads"; - -const require = createRequire(import.meta.url); - -const { instantiateNapiModuleSync, MessageHandler, getDefaultContext } = require("@napi-rs/wasm-runtime"); - -if (parentPort) { - parentPort.on("message", (data) => { - globalThis.onmessage({ data }); - }); -} - -Object.assign(globalThis, { - self: globalThis, - require, - Worker, - importScripts: function (f) { - ;(0, eval)(fs.readFileSync(f, "utf8") + "//# sourceURL=" + f); - }, - postMessage: function (msg) { - if (parentPort) { - parentPort.postMessage(msg); - } - }, -}); - -const emnapiContext = getDefaultContext(); - -const __rootDir = parse(process.cwd()).root; - -const handler = new MessageHandler({ - onLoad({ wasmModule, wasmMemory }) { - const wasi = new WASI({ - version: 'preview1', - env: process.env, - preopens: { - [__rootDir]: __rootDir, - }, - }); - - return instantiateNapiModuleSync(wasmModule, { - childThread: true, - wasi, - context: emnapiContext, - overwriteImports(importObject) { - importObject.env = { - ...importObject.env, - ...importObject.napi, - ...importObject.emnapi, - memory: wasmMemory - }; - }, - }); - }, -}); - -globalThis.onmessage = function (e) { - handler.handle(e); -}; diff --git a/yarn.lock b/yarn.lock index 3a45399..195a147 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,22 +5,22 @@ __metadata: version: 8 cacheKey: 10c0 -"@emnapi/core@npm:^1.5.0, @emnapi/core@npm:^1.7.1": - version: 1.9.0 - resolution: "@emnapi/core@npm:1.9.0" +"@emnapi/core@npm:^1.5.0": + version: 1.9.1 + resolution: "@emnapi/core@npm:1.9.1" dependencies: "@emnapi/wasi-threads": "npm:1.2.0" tslib: "npm:^2.4.0" - checksum: 10c0/defbfa5861aa5ff1346dbc6a19df50d727ae76ae276a31a97b178db8eecae0c5179976878087b43ac2441750e40e6c50e465280383256deb16dd2fb167dd515c + checksum: 10c0/00e7a99a2bc3ad908ca8272ba861a934da87dffa8797a41316c4a3b571a1e4d2743e2fa14b1a0f131fa4a3c2018ddb601cd2a8cb7f574fa940af696df3c2fe8d languageName: node linkType: hard -"@emnapi/runtime@npm:^1.5.0, @emnapi/runtime@npm:^1.7.1": - version: 1.9.0 - resolution: "@emnapi/runtime@npm:1.9.0" +"@emnapi/runtime@npm:^1.5.0": + version: 1.9.1 + resolution: "@emnapi/runtime@npm:1.9.1" dependencies: tslib: "npm:^2.4.0" - checksum: 10c0/f825e53b2d3f9d31fd880e669197d006bb5158c3a52ab25f0546f3d52ac58eb539a4bd1dcc378af6c10d202956fa064b28ab7b572a76de58972c0b8656a692ef + checksum: 10c0/750edca117e0363ab2de10622f8ee60e57d8690c2f29c49704813da5cd627c641798d7f3cb0d953c62fdc71688e02e333ddbf2c1204f38b47e3e40657332a6f5 languageName: node linkType: hard @@ -216,11 +216,9 @@ __metadata: linkType: hard "@gar/promise-retry@npm:^1.0.0": - version: 1.0.2 - resolution: "@gar/promise-retry@npm:1.0.2" - dependencies: - retry: "npm:^0.13.1" - checksum: 10c0/748a84fb0ab962f7867966f21dc24d1872c53c1656dd3352320fe69ad3b2043f2dfdb3be024c7636ce4904c5ba1da22d0f3558e489c3de578f5bb520f062d0fd + version: 1.0.3 + resolution: "@gar/promise-retry@npm:1.0.3" + checksum: 10c0/885b02c8b0d75b2d215da25f3b639158c4fbe8fefe0d79163304534b9a6d0710db4b7699f7cd3cc1a730792bff04cbe19f4850a62d3e105a663eaeec88f38332 languageName: node linkType: hard @@ -465,20 +463,6 @@ __metadata: languageName: node linkType: hard -"@isaacs/cliui@npm:^8.0.2": - version: 8.0.2 - resolution: "@isaacs/cliui@npm:8.0.2" - dependencies: - string-width: "npm:^5.1.2" - string-width-cjs: "npm:string-width@^4.2.0" - strip-ansi: "npm:^7.0.1" - strip-ansi-cjs: "npm:strip-ansi@^6.0.1" - wrap-ansi: "npm:^8.1.0" - wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" - checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e - languageName: node - linkType: hard - "@isaacs/fs-minipass@npm:^4.0.0": version: 4.0.1 resolution: "@isaacs/fs-minipass@npm:4.0.1" @@ -506,8 +490,8 @@ __metadata: linkType: hard "@napi-rs/cli@npm:^3.2.0": - version: 3.5.1 - resolution: "@napi-rs/cli@npm:3.5.1" + version: 3.6.0 + resolution: "@napi-rs/cli@npm:3.6.0" dependencies: "@inquirer/prompts": "npm:^8.0.0" "@napi-rs/cross-toolchain": "npm:^1.0.3" @@ -515,7 +499,7 @@ __metadata: "@octokit/rest": "npm:^22.0.1" clipanion: "npm:^4.0.0-rc.4" colorette: "npm:^2.0.20" - emnapi: "npm:^1.7.1" + emnapi: "npm:^1.9.1" es-toolkit: "npm:^1.41.0" js-yaml: "npm:^4.1.0" obug: "npm:^2.0.0" @@ -529,7 +513,7 @@ __metadata: bin: napi: dist/cli.js napi-raw: cli.mjs - checksum: 10c0/b67d057a052a28917c90653101dfcff9e7f60342b1120f4613d571533cf8080116d97d9825ad88d672c79a5165a0edf7aec4eb4db702464c0551ed48c1b81adf + checksum: 10c0/9956e4fb95e302545d54a725427521bc411dd5bceb1878e54e2e30ef2f1c959869d235e58755aa0e21896d0c489f80059320688e09a1565942c014bd167fd795 languageName: node linkType: hard @@ -929,13 +913,14 @@ __metadata: linkType: hard "@napi-rs/wasm-runtime@npm:^1.0.3, @napi-rs/wasm-runtime@npm:^1.0.7": - version: 1.1.1 - resolution: "@napi-rs/wasm-runtime@npm:1.1.1" + version: 1.1.2 + resolution: "@napi-rs/wasm-runtime@npm:1.1.2" dependencies: - "@emnapi/core": "npm:^1.7.1" - "@emnapi/runtime": "npm:^1.7.1" "@tybys/wasm-util": "npm:^0.10.1" - checksum: 10c0/04d57b67e80736e41fe44674a011878db0a8ad893f4d44abb9d3608debb7c174224cba2796ed5b0c1d367368159f3ca6be45f1c59222f70e32ddc880f803d447 + peerDependencies: + "@emnapi/core": ^1.7.1 + "@emnapi/runtime": ^1.7.1 + checksum: 10c0/725c30ec9c480a8d0c1a6a4ce31dc6c830365d485e23ad560e143d1cb9db89a0c95fbb5b9d53c07121729817a3683db6f1ab65d7e4f38fa7482a11b15ef6c6fd languageName: node linkType: hard @@ -1129,6 +1114,13 @@ __metadata: languageName: node linkType: hard +"@npmcli/redact@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/redact@npm:4.0.0" + checksum: 10c0/a1e9ba9c70a6b40e175bda2c3dd8cfdaf096e6b7f7a132c855c083c8dfe545c3237cd56702e2e6627a580b1d63373599d49a1192c4078a85bf47bbde824df31c + languageName: node + linkType: hard + "@octokit/auth-token@npm:^6.0.0": version: 6.0.0 resolution: "@octokit/auth-token@npm:6.0.0" @@ -1436,146 +1428,139 @@ __metadata: languageName: node linkType: hard -"@oxlint/binding-android-arm-eabi@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-android-arm-eabi@npm:1.56.0" +"@oxlint/binding-android-arm-eabi@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-android-arm-eabi@npm:1.57.0" conditions: os=android & cpu=arm languageName: node linkType: hard -"@oxlint/binding-android-arm64@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-android-arm64@npm:1.56.0" +"@oxlint/binding-android-arm64@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-android-arm64@npm:1.57.0" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@oxlint/binding-darwin-arm64@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-darwin-arm64@npm:1.56.0" +"@oxlint/binding-darwin-arm64@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-darwin-arm64@npm:1.57.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@oxlint/binding-darwin-x64@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-darwin-x64@npm:1.56.0" +"@oxlint/binding-darwin-x64@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-darwin-x64@npm:1.57.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@oxlint/binding-freebsd-x64@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-freebsd-x64@npm:1.56.0" +"@oxlint/binding-freebsd-x64@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-freebsd-x64@npm:1.57.0" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@oxlint/binding-linux-arm-gnueabihf@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-arm-gnueabihf@npm:1.56.0" +"@oxlint/binding-linux-arm-gnueabihf@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-arm-gnueabihf@npm:1.57.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@oxlint/binding-linux-arm-musleabihf@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-arm-musleabihf@npm:1.56.0" +"@oxlint/binding-linux-arm-musleabihf@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-arm-musleabihf@npm:1.57.0" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@oxlint/binding-linux-arm64-gnu@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-arm64-gnu@npm:1.56.0" +"@oxlint/binding-linux-arm64-gnu@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-arm64-gnu@npm:1.57.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@oxlint/binding-linux-arm64-musl@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-arm64-musl@npm:1.56.0" +"@oxlint/binding-linux-arm64-musl@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-arm64-musl@npm:1.57.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@oxlint/binding-linux-ppc64-gnu@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-ppc64-gnu@npm:1.56.0" +"@oxlint/binding-linux-ppc64-gnu@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-ppc64-gnu@npm:1.57.0" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@oxlint/binding-linux-riscv64-gnu@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-riscv64-gnu@npm:1.56.0" +"@oxlint/binding-linux-riscv64-gnu@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-riscv64-gnu@npm:1.57.0" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@oxlint/binding-linux-riscv64-musl@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-riscv64-musl@npm:1.56.0" +"@oxlint/binding-linux-riscv64-musl@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-riscv64-musl@npm:1.57.0" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@oxlint/binding-linux-s390x-gnu@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-s390x-gnu@npm:1.56.0" +"@oxlint/binding-linux-s390x-gnu@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-s390x-gnu@npm:1.57.0" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@oxlint/binding-linux-x64-gnu@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-x64-gnu@npm:1.56.0" +"@oxlint/binding-linux-x64-gnu@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-x64-gnu@npm:1.57.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@oxlint/binding-linux-x64-musl@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-linux-x64-musl@npm:1.56.0" +"@oxlint/binding-linux-x64-musl@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-linux-x64-musl@npm:1.57.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@oxlint/binding-openharmony-arm64@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-openharmony-arm64@npm:1.56.0" +"@oxlint/binding-openharmony-arm64@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-openharmony-arm64@npm:1.57.0" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@oxlint/binding-win32-arm64-msvc@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-win32-arm64-msvc@npm:1.56.0" +"@oxlint/binding-win32-arm64-msvc@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-win32-arm64-msvc@npm:1.57.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@oxlint/binding-win32-ia32-msvc@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-win32-ia32-msvc@npm:1.56.0" +"@oxlint/binding-win32-ia32-msvc@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-win32-ia32-msvc@npm:1.57.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@oxlint/binding-win32-x64-msvc@npm:1.56.0": - version: 1.56.0 - resolution: "@oxlint/binding-win32-x64-msvc@npm:1.56.0" +"@oxlint/binding-win32-x64-msvc@npm:1.57.0": + version: 1.57.0 + resolution: "@oxlint/binding-win32-x64-msvc@npm:1.57.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd - languageName: node - linkType: hard - "@rollup/pluginutils@npm:^5.1.3": version: 5.3.0 resolution: "@rollup/pluginutils@npm:5.3.0" @@ -1602,8 +1587,11 @@ __metadata: "@oxc-node/core": "npm:^0.0.35" "@taplo/cli": "npm:^0.7.0" "@tybys/wasm-util": "npm:^0.10.0" + "@types/express": "npm:^5.0.6" + "@types/express-serve-static-core": "npm:^5.1.1" "@types/node": "npm:^25.0.3" - ava: "npm:^6.4.1" + "@types/qs": "npm:^6.15.0" + ava: "npm:^7.0.0" axios: "npm:^1.13.2" chalk: "npm:^5.6.2" husky: "npm:^9.1.7" @@ -1614,14 +1602,14 @@ __metadata: tinybench: "npm:^6.0.0" tree-kill: "npm:^1.2.2" tsx: "npm:^4.21.0" - typescript: "npm:^5.9.2" + typescript: "npm:^6.0.2" languageName: unknown linkType: soft -"@sindresorhus/merge-streams@npm:^2.1.0": - version: 2.3.0 - resolution: "@sindresorhus/merge-streams@npm:2.3.0" - checksum: 10c0/69ee906f3125fb2c6bb6ec5cdd84e8827d93b49b3892bce8b62267116cc7e197b5cccf20c160a1d32c26014ecd14470a72a5e3ee37a58f1d6dadc0db1ccf3894 +"@sindresorhus/merge-streams@npm:^4.0.0": + version: 4.0.0 + resolution: "@sindresorhus/merge-streams@npm:4.0.0" + checksum: 10c0/482ee543629aa1933b332f811a1ae805a213681ecdd98c042b1c1b89387df63e7812248bb4df3910b02b3cc5589d3d73e4393f30e197c9dde18046ccd471fc6b languageName: node linkType: hard @@ -1643,6 +1631,25 @@ __metadata: languageName: node linkType: hard +"@types/body-parser@npm:*": + version: 1.19.6 + resolution: "@types/body-parser@npm:1.19.6" + dependencies: + "@types/connect": "npm:*" + "@types/node": "npm:*" + checksum: 10c0/542da05c924dce58ee23f50a8b981fee36921850c82222e384931fda3e106f750f7880c47be665217d72dbe445129049db6eb1f44e7a06b09d62af8f3cca8ea7 + languageName: node + linkType: hard + +"@types/connect@npm:*": + version: 3.4.38 + resolution: "@types/connect@npm:3.4.38" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/2e1cdba2c410f25649e77856505cd60223250fa12dff7a503e492208dbfdd25f62859918f28aba95315251fd1f5e1ffbfca1e25e73037189ab85dd3f8d0a148c + languageName: node + linkType: hard + "@types/estree@npm:^1.0.0": version: 1.0.8 resolution: "@types/estree@npm:1.0.8" @@ -1650,6 +1657,45 @@ __metadata: languageName: node linkType: hard +"@types/express-serve-static-core@npm:^5.0.0, @types/express-serve-static-core@npm:^5.1.1": + version: 5.1.1 + resolution: "@types/express-serve-static-core@npm:5.1.1" + dependencies: + "@types/node": "npm:*" + "@types/qs": "npm:*" + "@types/range-parser": "npm:*" + "@types/send": "npm:*" + checksum: 10c0/ee88216e114368ef06bcafeceb74a7e8671b90900fb0ab1d49ff41542c3a344231ef0d922bf63daa79f0585f3eebe2ce5ec7f83facc581eff8bcdb136a225ef3 + languageName: node + linkType: hard + +"@types/express@npm:^5.0.6": + version: 5.0.6 + resolution: "@types/express@npm:5.0.6" + dependencies: + "@types/body-parser": "npm:*" + "@types/express-serve-static-core": "npm:^5.0.0" + "@types/serve-static": "npm:^2" + checksum: 10c0/f1071e3389a955d4f9a38aae38634121c7cd9b3171ba4201ec9b56bd534aba07866839d278adc0dda05b942b05a901a02fd174201c3b1f70ce22b10b6c68f24b + languageName: node + linkType: hard + +"@types/http-errors@npm:*": + version: 2.0.5 + resolution: "@types/http-errors@npm:2.0.5" + checksum: 10c0/00f8140fbc504f47356512bd88e1910c2f07e04233d99c88c854b3600ce0523c8cd0ba7d1897667243282eb44c59abb9245959e2428b9de004f93937f52f7c15 + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 25.6.0 + resolution: "@types/node@npm:25.6.0" + dependencies: + undici-types: "npm:~7.19.0" + checksum: 10c0/d2d2015630ff098a201407f55f5077a20270ae4f465c739b40865cd9933b91b9c5d2b85568eadaf3db0801b91e267333ca7eb39f007428b173d1cdab4b339ac5 + languageName: node + linkType: hard + "@types/node@npm:^25.0.3": version: 25.5.0 resolution: "@types/node@npm:25.5.0" @@ -1659,9 +1705,42 @@ __metadata: languageName: node linkType: hard -"@vercel/nft@npm:^0.29.4": - version: 0.29.4 - resolution: "@vercel/nft@npm:0.29.4" +"@types/qs@npm:*, @types/qs@npm:^6.15.0": + version: 6.15.0 + resolution: "@types/qs@npm:6.15.0" + checksum: 10c0/1b104cac50e655fc41d7fc1de2c2aba2908c4cf833a555b6808fb4c96752662b439238f2392a15d2590a7a6ca75dbd40e42d9378ac2be0d548ee484954363688 + languageName: node + linkType: hard + +"@types/range-parser@npm:*": + version: 1.2.7 + resolution: "@types/range-parser@npm:1.2.7" + checksum: 10c0/361bb3e964ec5133fa40644a0b942279ed5df1949f21321d77de79f48b728d39253e5ce0408c9c17e4e0fd95ca7899da36841686393b9f7a1e209916e9381a3c + languageName: node + linkType: hard + +"@types/send@npm:*": + version: 1.2.1 + resolution: "@types/send@npm:1.2.1" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/7673747f8c2d8e67f3b1b3b57e9d4d681801a4f7b526ecf09987bb9a84a61cf94aa411c736183884dc762c1c402a61681eb1ef200d8d45d7e5ec0ab67ea5f6c1 + languageName: node + linkType: hard + +"@types/serve-static@npm:^2": + version: 2.2.0 + resolution: "@types/serve-static@npm:2.2.0" + dependencies: + "@types/http-errors": "npm:*" + "@types/node": "npm:*" + checksum: 10c0/a3c6126bdbf9685e6c7dc03ad34639666eff32754e912adeed9643bf3dd3aa0ff043002a7f69039306e310d233eb8e160c59308f95b0a619f32366bbc48ee094 + languageName: node + linkType: hard + +"@vercel/nft@npm:^1.3.2": + version: 1.5.0 + resolution: "@vercel/nft@npm:1.5.0" dependencies: "@mapbox/node-pre-gyp": "npm:^2.0.0" "@rollup/pluginutils": "npm:^5.1.3" @@ -1670,14 +1749,14 @@ __metadata: async-sema: "npm:^3.1.1" bindings: "npm:^1.4.0" estree-walker: "npm:2.0.2" - glob: "npm:^10.4.5" + glob: "npm:^13.0.0" graceful-fs: "npm:^4.2.9" node-gyp-build: "npm:^4.2.2" picomatch: "npm:^4.0.2" resolve-from: "npm:^5.0.0" bin: nft: out/cli.js - checksum: 10c0/84ba32c685f9d7c2c849b1e8c963d3b7eb09d122e666143ed97c3776f5b04a4745605e1d29fd81383f72b1d1c0d7d58e39f06dc92f021b5de079dfa4e8523574 + checksum: 10c0/e44f2bb41908f11ece98aa5c4f33b7ff6575a5102ab2db2675f4ee74bcc62439dce4d363a393f80a677898f63f7cac5741685653ee97a924e61e75c9d5b504d6 languageName: node linkType: hard @@ -1704,7 +1783,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.3.4": +"acorn-walk@npm:^8.3.5": version: 8.3.5 resolution: "acorn-walk@npm:8.3.5" dependencies: @@ -1713,7 +1792,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.6.0": +"acorn@npm:^8.11.0, acorn@npm:^8.16.0, acorn@npm:^8.6.0": version: 8.16.0 resolution: "acorn@npm:8.16.0" bin: @@ -1738,13 +1817,6 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^5.0.1": - version: 5.0.1 - resolution: "ansi-regex@npm:5.0.1" - checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 - languageName: node - linkType: hard - "ansi-regex@npm:^6.2.2": version: 6.2.2 resolution: "ansi-regex@npm:6.2.2" @@ -1752,16 +1824,7 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^4.0.0": - version: 4.3.0 - resolution: "ansi-styles@npm:4.3.0" - dependencies: - color-convert: "npm:^2.0.1" - checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 - languageName: node - linkType: hard - -"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1, ansi-styles@npm:^6.2.3": +"ansi-styles@npm:^6.2.1, ansi-styles@npm:^6.2.3": version: 6.2.3 resolution: "ansi-styles@npm:6.2.3" checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 @@ -1833,50 +1896,49 @@ __metadata: languageName: node linkType: hard -"ava@npm:^6.4.1": - version: 6.4.1 - resolution: "ava@npm:6.4.1" +"ava@npm:^7.0.0": + version: 7.0.0 + resolution: "ava@npm:7.0.0" dependencies: - "@vercel/nft": "npm:^0.29.4" - acorn: "npm:^8.15.0" - acorn-walk: "npm:^8.3.4" - ansi-styles: "npm:^6.2.1" + "@vercel/nft": "npm:^1.3.2" + acorn: "npm:^8.16.0" + acorn-walk: "npm:^8.3.5" + ansi-styles: "npm:^6.2.3" arrgv: "npm:^1.0.2" arrify: "npm:^3.0.0" callsites: "npm:^4.2.0" - cbor: "npm:^10.0.9" - chalk: "npm:^5.4.1" + cbor: "npm:^10.0.11" + chalk: "npm:^5.6.2" chunkd: "npm:^2.0.1" - ci-info: "npm:^4.3.0" + ci-info: "npm:^4.4.0" ci-parallel-vars: "npm:^1.0.1" - cli-truncate: "npm:^4.0.0" + cli-truncate: "npm:^5.1.1" code-excerpt: "npm:^4.0.0" common-path-prefix: "npm:^3.0.0" concordance: "npm:^5.0.4" currently-unhandled: "npm:^0.4.1" - debug: "npm:^4.4.1" + debug: "npm:^4.4.3" emittery: "npm:^1.2.0" figures: "npm:^6.1.0" - globby: "npm:^14.1.0" + globby: "npm:^16.1.1" ignore-by-default: "npm:^2.1.0" indent-string: "npm:^5.0.0" is-plain-object: "npm:^5.0.0" is-promise: "npm:^4.0.0" - matcher: "npm:^5.0.0" - memoize: "npm:^10.1.0" + matcher: "npm:^6.0.0" + memoize: "npm:^10.2.0" ms: "npm:^2.1.3" - p-map: "npm:^7.0.3" + p-map: "npm:^7.0.4" package-config: "npm:^5.0.0" - picomatch: "npm:^4.0.2" - plur: "npm:^5.1.0" - pretty-ms: "npm:^9.2.0" + picomatch: "npm:^4.0.3" + plur: "npm:^6.0.0" + pretty-ms: "npm:^9.3.0" resolve-cwd: "npm:^3.0.0" stack-utils: "npm:^2.0.6" - strip-ansi: "npm:^7.1.0" supertap: "npm:^3.0.1" temp-dir: "npm:^3.0.0" - write-file-atomic: "npm:^6.0.0" - yargs: "npm:^17.7.2" + write-file-atomic: "npm:^7.0.0" + yargs: "npm:^18.0.0" peerDependencies: "@ava/typescript": "*" peerDependenciesMeta: @@ -1884,25 +1946,18 @@ __metadata: optional: true bin: ava: entrypoints/cli.mjs - checksum: 10c0/21972df1031ef46533ea1b7daa132a5fc66841c8a221b6901163d12d2a1cac39bfd8a6d3459da7eb9344fa90fc02f237f2fe2aac8785d04bf5894fa43625be28 + checksum: 10c0/19c5e494bac1cc8140e78cb1440f299f9ae07baea50740c4d66daec3e2af048e71b8b5313e4834e100aeead7182d9bfe1b7acaad3dab7317ef2a00f23d39bc92 languageName: node linkType: hard "axios@npm:^1.13.2": - version: 1.13.6 - resolution: "axios@npm:1.13.6" + version: 1.14.0 + resolution: "axios@npm:1.14.0" dependencies: follow-redirects: "npm:^1.15.11" form-data: "npm:^4.0.5" - proxy-from-env: "npm:^1.1.0" - checksum: 10c0/51fb5af055c3b85662fa97df17d986ae2c37d13bf86d50b6bb36b6b3a2dec6966a1d3a14ab3774b71707b155ae3597ed9b7babdf1a1a863d1a31840cb8e7ec71 - languageName: node - linkType: hard - -"balanced-match@npm:^1.0.0": - version: 1.0.2 - resolution: "balanced-match@npm:1.0.2" - checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + proxy-from-env: "npm:^2.1.0" + checksum: 10c0/2541f4aa215a7d1842429dad006fc682d82bc0e74bd14500823f7d8cce3bbae0e0a8c328c8538946718f366ab8ce5a4c12e9ad40e5a0f3482ff8bff0cd115d45 languageName: node linkType: hard @@ -1936,21 +1991,12 @@ __metadata: languageName: node linkType: hard -"brace-expansion@npm:^2.0.2": - version: 2.0.2 - resolution: "brace-expansion@npm:2.0.2" - dependencies: - balanced-match: "npm:^1.0.0" - checksum: 10c0/6d117a4c793488af86b83172deb6af143e94c17bc53b0b3cec259733923b4ca84679d506ac261f4ba3c7ed37c46018e2ff442f9ce453af8643ecd64f4a54e6cf - languageName: node - linkType: hard - "brace-expansion@npm:^5.0.2": - version: 5.0.4 - resolution: "brace-expansion@npm:5.0.4" + version: 5.0.5 + resolution: "brace-expansion@npm:5.0.5" dependencies: balanced-match: "npm:^4.0.2" - checksum: 10c0/359cbcfa80b2eb914ca1f3440e92313fbfe7919ee6b274c35db55bec555aded69dac5ee78f102cec90c35f98c20fa43d10936d0cd9978158823c249257e1643a + checksum: 10c0/4d238e14ed4f5cc9c07285550a41cef23121ca08ba99fa9eb5b55b580dcb6bf868b8210aa10526bdc9f8dc97f33ca2a7259039c4cc131a93042beddb424c48e3 languageName: node linkType: hard @@ -1964,8 +2010,8 @@ __metadata: linkType: hard "cacache@npm:^20.0.1": - version: 20.0.3 - resolution: "cacache@npm:20.0.3" + version: 20.0.4 + resolution: "cacache@npm:20.0.4" dependencies: "@npmcli/fs": "npm:^5.0.0" fs-minipass: "npm:^3.0.0" @@ -1977,8 +2023,7 @@ __metadata: minipass-pipeline: "npm:^1.2.4" p-map: "npm:^7.0.2" ssri: "npm:^13.0.0" - unique-filename: "npm:^5.0.0" - checksum: 10c0/c7da1ca694d20e8f8aedabd21dc11518f809a7d2b59aa76a1fc655db5a9e62379e465c157ddd2afe34b19230808882288effa6911b2de26a088a6d5645123462 + checksum: 10c0/539bf4020e44ba9ca5afc2ec435623ed7e0dd80c020097677e6b4a0545df5cc9d20b473212d01209c8b4aea43c0d095af0bb6da97bcb991642ea6fac0d7c462b languageName: node linkType: hard @@ -1999,7 +2044,7 @@ __metadata: languageName: node linkType: hard -"cbor@npm:^10.0.9": +"cbor@npm:^10.0.11": version: 10.0.12 resolution: "cbor@npm:10.0.12" dependencies: @@ -2008,7 +2053,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.4.1, chalk@npm:^5.6.2": +"chalk@npm:^5.6.2": version: 5.6.2 resolution: "chalk@npm:5.6.2" checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976 @@ -2036,7 +2081,7 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^4.3.0": +"ci-info@npm:^4.4.0": version: 4.4.0 resolution: "ci-info@npm:4.4.0" checksum: 10c0/44156201545b8dde01aa8a09ee2fe9fc7a73b1bef9adbd4606c9f61c8caeeb73fb7a575c88b0443f7b4edb5ee45debaa59ed54ba5f99698339393ca01349eb3a @@ -2059,17 +2104,7 @@ __metadata: languageName: node linkType: hard -"cli-truncate@npm:^4.0.0": - version: 4.0.0 - resolution: "cli-truncate@npm:4.0.0" - dependencies: - slice-ansi: "npm:^5.0.0" - string-width: "npm:^7.0.0" - checksum: 10c0/d7f0b73e3d9b88cb496e6c086df7410b541b56a43d18ade6a573c9c18bd001b1c3fba1ad578f741a4218fdc794d042385f8ac02c25e1c295a2d8b9f3cb86eb4c - languageName: node - linkType: hard - -"cli-truncate@npm:^5.0.0": +"cli-truncate@npm:^5.0.0, cli-truncate@npm:^5.1.1": version: 5.2.0 resolution: "cli-truncate@npm:5.2.0" dependencies: @@ -2097,14 +2132,14 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^8.0.1": - version: 8.0.1 - resolution: "cliui@npm:8.0.1" +"cliui@npm:^9.0.1": + version: 9.0.1 + resolution: "cliui@npm:9.0.1" dependencies: - string-width: "npm:^4.2.0" - strip-ansi: "npm:^6.0.1" - wrap-ansi: "npm:^7.0.0" - checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 + string-width: "npm:^7.2.0" + strip-ansi: "npm:^7.1.0" + wrap-ansi: "npm:^9.0.0" + checksum: 10c0/13441832e9efe7c7a76bd2b8e683555c478d461a9f249dc5db9b17fe8d4b47fa9277b503914b90bd00e4a151abb6b9b02b2288972ffe2e5e3ca40bcb1c2330d3 languageName: node linkType: hard @@ -2117,22 +2152,6 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^2.0.1": - version: 2.0.1 - resolution: "color-convert@npm:2.0.1" - dependencies: - color-name: "npm:~1.1.4" - checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 - languageName: node - linkType: hard - -"color-name@npm:~1.1.4": - version: 1.1.4 - resolution: "color-name@npm:1.1.4" - checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 - languageName: node - linkType: hard - "colorette@npm:^2.0.20": version: 2.0.20 resolution: "colorette@npm:2.0.20" @@ -2222,7 +2241,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.3.4, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.3.4, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -2259,13 +2278,6 @@ __metadata: languageName: node linkType: hard -"eastasianwidth@npm:^0.2.0": - version: 0.2.0 - resolution: "eastasianwidth@npm:0.2.0" - checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 - languageName: node - linkType: hard - "emittery@npm:^1.2.0": version: 1.2.1 resolution: "emittery@npm:1.2.1" @@ -2273,15 +2285,15 @@ __metadata: languageName: node linkType: hard -"emnapi@npm:^1.7.1": - version: 1.9.0 - resolution: "emnapi@npm:1.9.0" +"emnapi@npm:^1.9.1": + version: 1.9.1 + resolution: "emnapi@npm:1.9.1" peerDependencies: node-addon-api: ">= 6.1.0" peerDependenciesMeta: node-addon-api: optional: true - checksum: 10c0/e639ec31e3d71418b2b57fc1a340b84aedbd2f2f1b1eb5e24b5b76591a31b1c03c75e77f71e92eb3a00ae86c64613b2a290902f7c541eec5a89106793f6ef93c + checksum: 10c0/d2dfc4f7ab1999a77147a924776e8d4d852776a2d246a88a1aff2090774c43d087ab1045ec83e22b999acd4bbef80298c519b0705938384945f4842a1df38f40 languageName: node linkType: hard @@ -2292,20 +2304,6 @@ __metadata: languageName: node linkType: hard -"emoji-regex@npm:^8.0.0": - version: 8.0.0 - resolution: "emoji-regex@npm:8.0.0" - checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 - languageName: node - linkType: hard - -"emoji-regex@npm:^9.2.2": - version: 9.2.2 - resolution: "emoji-regex@npm:9.2.2" - checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 - languageName: node - linkType: hard - "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -2630,16 +2628,6 @@ __metadata: languageName: node linkType: hard -"foreground-child@npm:^3.1.0": - version: 3.3.1 - resolution: "foreground-child@npm:3.3.1" - dependencies: - cross-spawn: "npm:^7.0.6" - signal-exit: "npm:^4.0.1" - checksum: 10c0/8986e4af2430896e65bc2788d6679067294d6aee9545daefc84923a0a4b399ad9c7a3ea7bd8c0b2b80fdf4a92de4c69df3f628233ff3224260e9c1541a9e9ed3 - languageName: node - linkType: hard - "form-data@npm:^4.0.5": version: 4.0.5 resolution: "form-data@npm:4.0.5" @@ -2741,11 +2729,11 @@ __metadata: linkType: hard "get-tsconfig@npm:^4.7.5": - version: 4.13.6 - resolution: "get-tsconfig@npm:4.13.6" + version: 4.13.7 + resolution: "get-tsconfig@npm:4.13.7" dependencies: resolve-pkg-maps: "npm:^1.0.0" - checksum: 10c0/bab6937302f542f97217cbe7cbbdfa7e85a56a377bc7a73e69224c1f0b7c9ae8365918e55752ae8648265903f506c1705f63c0de1d4bab1ec2830fef3e539a1a + checksum: 10c0/1118eb7e9b27bce0b9b6f042e98f0d067e26dfa1ca32bc4b56e892b615b57a5a4af9e6f801c7b0611a4afef2e31c4941be4c6026e0e6a480aaf1ddaf261113d5 languageName: node linkType: hard @@ -2758,22 +2746,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.4.5": - version: 10.5.0 - resolution: "glob@npm:10.5.0" - dependencies: - foreground-child: "npm:^3.1.0" - jackspeak: "npm:^3.1.2" - minimatch: "npm:^9.0.4" - minipass: "npm:^7.1.2" - package-json-from-dist: "npm:^1.0.0" - path-scurry: "npm:^1.11.1" - bin: - glob: dist/esm/bin.mjs - checksum: 10c0/100705eddbde6323e7b35e1d1ac28bcb58322095bd8e63a7d0bef1a2cdafe0d0f7922a981b2b48369a4f8c1b077be5c171804534c3509dfe950dde15fbe6d828 - languageName: node - linkType: hard - "glob@npm:^13.0.0": version: 13.0.6 resolution: "glob@npm:13.0.6" @@ -2785,17 +2757,17 @@ __metadata: languageName: node linkType: hard -"globby@npm:^14.1.0": - version: 14.1.0 - resolution: "globby@npm:14.1.0" +"globby@npm:^16.1.1": + version: 16.2.0 + resolution: "globby@npm:16.2.0" dependencies: - "@sindresorhus/merge-streams": "npm:^2.1.0" + "@sindresorhus/merge-streams": "npm:^4.0.0" fast-glob: "npm:^3.3.3" - ignore: "npm:^7.0.3" - path-type: "npm:^6.0.0" + ignore: "npm:^7.0.5" + is-path-inside: "npm:^4.0.0" slash: "npm:^5.1.0" - unicorn-magic: "npm:^0.3.0" - checksum: 10c0/527a1063c5958255969620c6fa4444a2b2e9278caddd571d46dfbfa307cb15977afb746e84d682ba5b6c94fc081e8997f80ff05dd235441ba1cb16f86153e58e + unicorn-magic: "npm:^0.4.0" + checksum: 10c0/fc0675e01dc1da5095f30dccc46a3047fc38d45ca08c21c1aa871bd79d38682f507d84a159be168019db5fffaa09c5663c3679c29190a2d4f999dc91d7ff6406 languageName: node linkType: hard @@ -2890,20 +2862,13 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^7.0.3": +"ignore@npm:^7.0.5": version: 7.0.5 resolution: "ignore@npm:7.0.5" checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d languageName: node linkType: hard -"imurmurhash@npm:^0.1.4": - version: 0.1.4 - resolution: "imurmurhash@npm:0.1.4" - checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 - languageName: node - linkType: hard - "indent-string@npm:^5.0.0": version: 5.0.0 resolution: "indent-string@npm:5.0.0" @@ -2918,10 +2883,10 @@ __metadata: languageName: node linkType: hard -"irregular-plurals@npm:^3.3.0": - version: 3.5.0 - resolution: "irregular-plurals@npm:3.5.0" - checksum: 10c0/7c033bbe7325e5a6e0a26949cc6863b6ce273403d4cd5b93bd99b33fecb6605b0884097c4259c23ed0c52c2133bf7d1cdcdd7a0630e8c325161fe269b3447918 +"irregular-plurals@npm:^4.2.0": + version: 4.2.0 + resolution: "irregular-plurals@npm:4.2.0" + checksum: 10c0/f3b86491a2e2879c8bb4f818dede9d1305d02893076e73e6b620fcf570330bcaa0520dc1342d088b35dfea07e79919ff780e21f61c4e1fb6cc50858c1045be81 languageName: node linkType: hard @@ -2932,20 +2897,6 @@ __metadata: languageName: node linkType: hard -"is-fullwidth-code-point@npm:^3.0.0": - version: 3.0.0 - resolution: "is-fullwidth-code-point@npm:3.0.0" - checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc - languageName: node - linkType: hard - -"is-fullwidth-code-point@npm:^4.0.0": - version: 4.0.0 - resolution: "is-fullwidth-code-point@npm:4.0.0" - checksum: 10c0/df2a717e813567db0f659c306d61f2f804d480752526886954a2a3e2246c7745fd07a52b5fecf2b68caf0a6c79dcdace6166fdf29cc76ed9975cc334f0a018b8 - languageName: node - linkType: hard - "is-fullwidth-code-point@npm:^5.0.0, is-fullwidth-code-point@npm:^5.1.0": version: 5.1.0 resolution: "is-fullwidth-code-point@npm:5.1.0" @@ -2971,6 +2922,13 @@ __metadata: languageName: node linkType: hard +"is-path-inside@npm:^4.0.0": + version: 4.0.0 + resolution: "is-path-inside@npm:4.0.0" + checksum: 10c0/51188d7e2b1d907a9a5f7c18d99a90b60870b951ed87cf97595d9aaa429d4c010652c3350bcbf31182e7f4b0eab9a1860b43e16729b13cb1a44baaa6cdb64c46 + languageName: node + linkType: hard + "is-plain-object@npm:^5.0.0": version: 5.0.0 resolution: "is-plain-object@npm:5.0.0" @@ -3013,19 +2971,6 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^3.1.2": - version: 3.4.3 - resolution: "jackspeak@npm:3.4.3" - dependencies: - "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 - languageName: node - linkType: hard - "js-string-escape@npm:^1.0.1": version: 1.0.1 resolution: "js-string-escape@npm:1.0.1" @@ -3064,9 +3009,9 @@ __metadata: linkType: hard "json-with-bigint@npm:^3.5.3": - version: 3.5.7 - resolution: "json-with-bigint@npm:3.5.7" - checksum: 10c0/69f27b712ac113aec2cac0933d81f37a3d6f5f0947543805cf5c6699c19ed14a79515d9aa2f78fde54ffdd7d9105790443408322f23add2a69096e741e176876 + version: 3.5.8 + resolution: "json-with-bigint@npm:3.5.8" + checksum: 10c0/a0c4e37626d74a9a493539f9f9a94855933fa15ea2f028859a787229a42c5f11803db6f94f1ce7b1d89756c1e80a7c1f11006bac266ec7ce819b75701765ca0a languageName: node linkType: hard @@ -3127,13 +3072,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.2.0": - version: 10.4.3 - resolution: "lru-cache@npm:10.4.3" - checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb - languageName: node - linkType: hard - "lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": version: 11.2.7 resolution: "lru-cache@npm:11.2.7" @@ -3142,11 +3080,12 @@ __metadata: linkType: hard "make-fetch-happen@npm:^15.0.0": - version: 15.0.4 - resolution: "make-fetch-happen@npm:15.0.4" + version: 15.0.5 + resolution: "make-fetch-happen@npm:15.0.5" dependencies: "@gar/promise-retry": "npm:^1.0.0" "@npmcli/agent": "npm:^4.0.0" + "@npmcli/redact": "npm:^4.0.0" cacache: "npm:^20.0.1" http-cache-semantics: "npm:^4.1.1" minipass: "npm:^7.0.2" @@ -3156,16 +3095,16 @@ __metadata: negotiator: "npm:^1.0.0" proc-log: "npm:^6.0.0" ssri: "npm:^13.0.0" - checksum: 10c0/b874bf6879fc0b8ef3a3cafdddadea4d956acf94790f8dede1a9d3c74c7886b6cd3eb992616b8e5935e6fd550016a465f10ba51bf6723a0c6f4d98883ae2926b + checksum: 10c0/527580eb5e5476e6ad07a4e3bd017d13e935f4be815674b442081ae5a721c13d3af5715006619e6be79a85723067e047f83a0c9e699f41d8cec43609a8de4f7b languageName: node linkType: hard -"matcher@npm:^5.0.0": - version: 5.0.0 - resolution: "matcher@npm:5.0.0" +"matcher@npm:^6.0.0": + version: 6.0.0 + resolution: "matcher@npm:6.0.0" dependencies: escape-string-regexp: "npm:^5.0.0" - checksum: 10c0/eda5471fc9d5b7264d63c81727824adc3585ddb5cfdc5fce5a9b7c86f946ff181610735d330b1c37a84811df872d1290bf4e9401d2be2a414204343701144b18 + checksum: 10c0/b2eb6a23de82be3cbcf8e79034638a44e22ce6fcc6968ea2a7b342b1e059eb15bc18bf32d8fce7390c9b0710b21a8eabdc133190c0d86a91de2491b0afae3ca7 languageName: node linkType: hard @@ -3185,7 +3124,7 @@ __metadata: languageName: node linkType: hard -"memoize@npm:^10.1.0": +"memoize@npm:^10.2.0": version: 10.2.0 resolution: "memoize@npm:10.2.0" dependencies: @@ -3250,15 +3189,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.4": - version: 9.0.9 - resolution: "minimatch@npm:9.0.9" - dependencies: - brace-expansion: "npm:^2.0.2" - checksum: 10c0/0b6a58530dbb00361745aa6c8cffaba4c90f551afe7c734830bd95fd88ebf469dd7355a027824ea1d09e37181cfeb0a797fb17df60c15ac174303ac110eb7e86 - languageName: node - linkType: hard - "minipass-collect@npm:^2.0.1": version: 2.0.1 resolution: "minipass-collect@npm:2.0.1" @@ -3284,11 +3214,11 @@ __metadata: linkType: hard "minipass-flush@npm:^1.0.5": - version: 1.0.5 - resolution: "minipass-flush@npm:1.0.5" + version: 1.0.7 + resolution: "minipass-flush@npm:1.0.7" dependencies: minipass: "npm:^3.0.0" - checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd + checksum: 10c0/960915c02aa0991662c37c404517dd93708d17f96533b2ca8c1e776d158715d8107c5ced425ffc61674c167d93607f07f48a83c139ce1057f8781e5dfb4b90c2 languageName: node linkType: hard @@ -3319,7 +3249,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3": +"minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3": version: 7.1.3 resolution: "minipass@npm:7.1.3" checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb @@ -3475,28 +3405,28 @@ __metadata: linkType: hard "oxlint@npm:^1.14.0": - version: 1.56.0 - resolution: "oxlint@npm:1.56.0" - dependencies: - "@oxlint/binding-android-arm-eabi": "npm:1.56.0" - "@oxlint/binding-android-arm64": "npm:1.56.0" - "@oxlint/binding-darwin-arm64": "npm:1.56.0" - "@oxlint/binding-darwin-x64": "npm:1.56.0" - "@oxlint/binding-freebsd-x64": "npm:1.56.0" - "@oxlint/binding-linux-arm-gnueabihf": "npm:1.56.0" - "@oxlint/binding-linux-arm-musleabihf": "npm:1.56.0" - "@oxlint/binding-linux-arm64-gnu": "npm:1.56.0" - "@oxlint/binding-linux-arm64-musl": "npm:1.56.0" - "@oxlint/binding-linux-ppc64-gnu": "npm:1.56.0" - "@oxlint/binding-linux-riscv64-gnu": "npm:1.56.0" - "@oxlint/binding-linux-riscv64-musl": "npm:1.56.0" - "@oxlint/binding-linux-s390x-gnu": "npm:1.56.0" - "@oxlint/binding-linux-x64-gnu": "npm:1.56.0" - "@oxlint/binding-linux-x64-musl": "npm:1.56.0" - "@oxlint/binding-openharmony-arm64": "npm:1.56.0" - "@oxlint/binding-win32-arm64-msvc": "npm:1.56.0" - "@oxlint/binding-win32-ia32-msvc": "npm:1.56.0" - "@oxlint/binding-win32-x64-msvc": "npm:1.56.0" + version: 1.57.0 + resolution: "oxlint@npm:1.57.0" + dependencies: + "@oxlint/binding-android-arm-eabi": "npm:1.57.0" + "@oxlint/binding-android-arm64": "npm:1.57.0" + "@oxlint/binding-darwin-arm64": "npm:1.57.0" + "@oxlint/binding-darwin-x64": "npm:1.57.0" + "@oxlint/binding-freebsd-x64": "npm:1.57.0" + "@oxlint/binding-linux-arm-gnueabihf": "npm:1.57.0" + "@oxlint/binding-linux-arm-musleabihf": "npm:1.57.0" + "@oxlint/binding-linux-arm64-gnu": "npm:1.57.0" + "@oxlint/binding-linux-arm64-musl": "npm:1.57.0" + "@oxlint/binding-linux-ppc64-gnu": "npm:1.57.0" + "@oxlint/binding-linux-riscv64-gnu": "npm:1.57.0" + "@oxlint/binding-linux-riscv64-musl": "npm:1.57.0" + "@oxlint/binding-linux-s390x-gnu": "npm:1.57.0" + "@oxlint/binding-linux-x64-gnu": "npm:1.57.0" + "@oxlint/binding-linux-x64-musl": "npm:1.57.0" + "@oxlint/binding-openharmony-arm64": "npm:1.57.0" + "@oxlint/binding-win32-arm64-msvc": "npm:1.57.0" + "@oxlint/binding-win32-ia32-msvc": "npm:1.57.0" + "@oxlint/binding-win32-x64-msvc": "npm:1.57.0" peerDependencies: oxlint-tsgolint: ">=0.15.0" dependenciesMeta: @@ -3543,11 +3473,11 @@ __metadata: optional: true bin: oxlint: bin/oxlint - checksum: 10c0/0b95b03106619574244e0837b94730a988c3188a2d0137c07bcc85ee79cb11a3c64e46910b3bca8befce49459af58a503c7e2c26c6022cc11705cf6db787581c + checksum: 10c0/e2ccd23280615068335c603c7fe9d2590812d7b2f16ee55a3fca1260d600795847e94926026a0d4ef46026c97c3868aee070ecca125eeaac68a8abbbe309d4a1 languageName: node linkType: hard -"p-map@npm:^7.0.2, p-map@npm:^7.0.3": +"p-map@npm:^7.0.2, p-map@npm:^7.0.4": version: 7.0.4 resolution: "p-map@npm:7.0.4" checksum: 10c0/a5030935d3cb2919d7e89454d1ce82141e6f9955413658b8c9403cfe379283770ed3048146b44cde168aa9e8c716505f196d5689db0ae3ce9a71521a2fef3abd @@ -3564,13 +3494,6 @@ __metadata: languageName: node linkType: hard -"package-json-from-dist@npm:^1.0.0": - version: 1.0.1 - resolution: "package-json-from-dist@npm:1.0.1" - checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b - languageName: node - linkType: hard - "parse-ms@npm:^4.0.0": version: 4.0.0 resolution: "parse-ms@npm:4.0.0" @@ -3585,16 +3508,6 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.11.1": - version: 1.11.1 - resolution: "path-scurry@npm:1.11.1" - dependencies: - lru-cache: "npm:^10.2.0" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d - languageName: node - linkType: hard - "path-scurry@npm:^2.0.2": version: 2.0.2 resolution: "path-scurry@npm:2.0.2" @@ -3605,24 +3518,17 @@ __metadata: languageName: node linkType: hard -"path-type@npm:^6.0.0": - version: 6.0.0 - resolution: "path-type@npm:6.0.0" - checksum: 10c0/55baa8b1187d6dc683d5a9cfcc866168d6adff58e5db91126795376d818eee46391e00b2a4d53e44d844c7524a7d96aa68cc68f4f3e500d3d069a39e6535481c - languageName: node - linkType: hard - "picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + version: 2.3.2 + resolution: "picomatch@npm:2.3.2" + checksum: 10c0/a554d1709e59be97d1acb9eaedbbc700a5c03dbd4579807baed95100b00420bc729335440ef15004ae2378984e2487a7c1cebd743cfdb72b6fa9ab69223c0d61 languageName: node linkType: hard "picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": - version: 4.0.3 - resolution: "picomatch@npm:4.0.3" - checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 + version: 4.0.4 + resolution: "picomatch@npm:4.0.4" + checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0 languageName: node linkType: hard @@ -3642,12 +3548,12 @@ __metadata: languageName: node linkType: hard -"plur@npm:^5.1.0": - version: 5.1.0 - resolution: "plur@npm:5.1.0" +"plur@npm:^6.0.0": + version: 6.0.0 + resolution: "plur@npm:6.0.0" dependencies: - irregular-plurals: "npm:^3.3.0" - checksum: 10c0/26bb622b8545fcfd47bbf56fbcca66c08693708a232e403fa3589e00003c56c14231ac57c7588ca5db83ef4be1f61383402c4ea954000768f779f8aef6eb6da8 + irregular-plurals: "npm:^4.2.0" + checksum: 10c0/5c54badee70debea38e7153b197c1235847edc10952c3dd959c9610005f75013c2053be1cba87acde4531498d7a9e8b16c6b358f3940f05aa6e1aeedbc991b7a languageName: node linkType: hard @@ -3660,7 +3566,7 @@ __metadata: languageName: node linkType: hard -"pretty-ms@npm:^9.2.0": +"pretty-ms@npm:^9.3.0": version: 9.3.0 resolution: "pretty-ms@npm:9.3.0" dependencies: @@ -3676,10 +3582,10 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:^1.1.0": - version: 1.1.0 - resolution: "proxy-from-env@npm:1.1.0" - checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b +"proxy-from-env@npm:^2.1.0": + version: 2.1.0 + resolution: "proxy-from-env@npm:2.1.0" + checksum: 10c0/ed01729fd4d094eab619cd7e17ce3698b3413b31eb102c4904f9875e677cd207392795d5b4adee9cec359dfd31c44d5ad7595a3a3ad51c40250e141512281c58 languageName: node linkType: hard @@ -3700,13 +3606,6 @@ __metadata: languageName: node linkType: hard -"require-directory@npm:^2.1.1": - version: 2.1.1 - resolution: "require-directory@npm:2.1.1" - checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 - languageName: node - linkType: hard - "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -3740,13 +3639,6 @@ __metadata: languageName: node linkType: hard -"retry@npm:^0.13.1": - version: 0.13.1 - resolution: "retry@npm:0.13.1" - checksum: 10c0/9ae822ee19db2163497e074ea919780b1efa00431d197c7afdb950e42bf109196774b92a49fc9821f0b8b328a98eea6017410bfc5e8a0fc19c85c6d11adb3772 - languageName: node - linkType: hard - "reusify@npm:^1.0.4": version: 1.1.0 resolution: "reusify@npm:1.1.0" @@ -3832,16 +3724,6 @@ __metadata: languageName: node linkType: hard -"slice-ansi@npm:^5.0.0": - version: 5.0.0 - resolution: "slice-ansi@npm:5.0.0" - dependencies: - ansi-styles: "npm:^6.0.0" - is-fullwidth-code-point: "npm:^4.0.0" - checksum: 10c0/2d4d40b2a9d5cf4e8caae3f698fe24ae31a4d778701724f578e984dcb485ec8c49f0c04dab59c401821e80fcdfe89cace9c66693b0244e40ec485d72e543914f - languageName: node - linkType: hard - "slice-ansi@npm:^7.1.0": version: 7.1.2 resolution: "slice-ansi@npm:7.1.2" @@ -3922,29 +3804,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": - version: 4.2.3 - resolution: "string-width@npm:4.2.3" - dependencies: - emoji-regex: "npm:^8.0.0" - is-fullwidth-code-point: "npm:^3.0.0" - strip-ansi: "npm:^6.0.1" - checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b - languageName: node - linkType: hard - -"string-width@npm:^5.0.1, string-width@npm:^5.1.2": - version: 5.1.2 - resolution: "string-width@npm:5.1.2" - dependencies: - eastasianwidth: "npm:^0.2.0" - emoji-regex: "npm:^9.2.2" - strip-ansi: "npm:^7.0.1" - checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca - languageName: node - linkType: hard - -"string-width@npm:^7.0.0": +"string-width@npm:^7.0.0, string-width@npm:^7.2.0": version: 7.2.0 resolution: "string-width@npm:7.2.0" dependencies: @@ -3965,15 +3825,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": - version: 6.0.1 - resolution: "strip-ansi@npm:6.0.1" - dependencies: - ansi-regex: "npm:^5.0.1" - checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 - languageName: node - linkType: hard - "strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0, strip-ansi@npm:^7.1.2": version: 7.2.0 resolution: "strip-ansi@npm:7.2.0" @@ -3996,15 +3847,15 @@ __metadata: linkType: hard "tar@npm:^7.4.0, tar@npm:^7.5.4": - version: 7.5.11 - resolution: "tar@npm:7.5.11" + version: 7.5.13 + resolution: "tar@npm:7.5.13" dependencies: "@isaacs/fs-minipass": "npm:^4.0.0" chownr: "npm:^3.0.0" minipass: "npm:^7.1.2" minizlib: "npm:^3.1.0" yallist: "npm:^5.0.0" - checksum: 10c0/b6bb420550ef50ef23356018155e956cd83282c97b6128d8d5cfe5740c57582d806a244b2ef0bf686a74ce526babe8b8b9061527623e935e850008d86d838929 + checksum: 10c0/5c65b8084799bde7a791593a1c1a45d3d6ee98182e3700b24c247b7b8f8654df4191642abbdb07ff25043d45dcff35620827c3997b88ae6c12040f64bed5076b languageName: node linkType: hard @@ -4108,23 +3959,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.9.2": - version: 5.9.3 - resolution: "typescript@npm:5.9.3" +"typescript@npm:^6.0.2": + version: 6.0.2 + resolution: "typescript@npm:6.0.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5 + checksum: 10c0/4b860b0bf87cc0fee0f66d8ef2640b5a8a8a8c74d1129adb82e389e5f97124383823c47946bef8a73ede371461143a3aa8544399d2133c7b2e4f07e81860af7f languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.9.2#optional!builtin": - version: 5.9.3 - resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" +"typescript@patch:typescript@npm%3A^6.0.2#optional!builtin": + version: 6.0.2 + resolution: "typescript@patch:typescript@npm%3A6.0.2#optional!builtin::version=6.0.2&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430 + checksum: 10c0/49f0b84fc6ca55653e77752b8a61beabc09ee3dae5d965c31596225aa6ef213c5727b1d2e895b900416dc603854ba0872ac4a812c2a4ed6793a601f9c675de02 languageName: node linkType: hard @@ -4135,28 +3986,17 @@ __metadata: languageName: node linkType: hard -"unicorn-magic@npm:^0.3.0": - version: 0.3.0 - resolution: "unicorn-magic@npm:0.3.0" - checksum: 10c0/0a32a997d6c15f1c2a077a15b1c4ca6f268d574cf5b8975e778bb98e6f8db4ef4e86dfcae4e158cd4c7e38fb4dd383b93b13eefddc7f178dea13d3ac8a603271 +"undici-types@npm:~7.19.0": + version: 7.19.2 + resolution: "undici-types@npm:7.19.2" + checksum: 10c0/7159f10546f9f6c47d36776bb1bbf8671e87c1e587a6fee84ae1f111ae8de4f914efa8ca0dfcd224f4f4a9dfc3f6028f627ccb5ddaccf82d7fd54671b89fac3e languageName: node linkType: hard -"unique-filename@npm:^5.0.0": - version: 5.0.0 - resolution: "unique-filename@npm:5.0.0" - dependencies: - unique-slug: "npm:^6.0.0" - checksum: 10c0/afb897e9cf4c2fb622ea716f7c2bb462001928fc5f437972213afdf1cc32101a230c0f1e9d96fc91ee5185eca0f2feb34127145874975f347be52eb91d6ccc2c - languageName: node - linkType: hard - -"unique-slug@npm:^6.0.0": - version: 6.0.0 - resolution: "unique-slug@npm:6.0.0" - dependencies: - imurmurhash: "npm:^0.1.4" - checksum: 10c0/da7ade4cb04eb33ad0499861f82fe95ce9c7c878b7139dc54d140ecfb6a6541c18a5c8dac16188b8b379fe62c0c1f1b710814baac910cde5f4fec06212126c6a +"unicorn-magic@npm:^0.4.0": + version: 0.4.0 + resolution: "unicorn-magic@npm:0.4.0" + checksum: 10c0/cd6eff90967a5528dfa2016bdb5b38b0cd64c8558f9ba04fb5c2c23f3a232a67dfe2bfa4c45af3685d5f1a40dbac6a36d48e053f80f97ae4da1e0f6a55431685 languageName: node linkType: hard @@ -4224,28 +4064,6 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": - version: 7.0.0 - resolution: "wrap-ansi@npm:7.0.0" - dependencies: - ansi-styles: "npm:^4.0.0" - string-width: "npm:^4.1.0" - strip-ansi: "npm:^6.0.0" - checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da - languageName: node - linkType: hard - -"wrap-ansi@npm:^8.1.0": - version: 8.1.0 - resolution: "wrap-ansi@npm:8.1.0" - dependencies: - ansi-styles: "npm:^6.1.0" - string-width: "npm:^5.0.1" - strip-ansi: "npm:^7.0.1" - checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 - languageName: node - linkType: hard - "wrap-ansi@npm:^9.0.0": version: 9.0.2 resolution: "wrap-ansi@npm:9.0.2" @@ -4257,13 +4075,12 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^6.0.0": - version: 6.0.0 - resolution: "write-file-atomic@npm:6.0.0" +"write-file-atomic@npm:^7.0.0": + version: 7.0.1 + resolution: "write-file-atomic@npm:7.0.1" dependencies: - imurmurhash: "npm:^0.1.4" signal-exit: "npm:^4.0.1" - checksum: 10c0/ae2f1c27474758a9aca92037df6c1dd9cb94c4e4983451210bd686bfe341f142662f6aa5913095e572ab037df66b1bfe661ed4ce4c0369ed0e8219e28e141786 + checksum: 10c0/69cebb64945e22928a24ae7e2a55bf54438c92d6f657c1fa5e96b7c7a50f6c022e7454ab5c259079bb35f60296242f3a21234c79320d64a8ad57675b56a2098d languageName: node linkType: hard @@ -4289,32 +4106,31 @@ __metadata: linkType: hard "yaml@npm:^2.8.2": - version: 2.8.2 - resolution: "yaml@npm:2.8.2" + version: 2.8.3 + resolution: "yaml@npm:2.8.3" bin: yaml: bin.mjs - checksum: 10c0/703e4dc1e34b324aa66876d63618dcacb9ed49f7e7fe9b70f1e703645be8d640f68ab84f12b86df8ac960bac37acf5513e115de7c970940617ce0343c8c9cd96 + checksum: 10c0/ddff0e11c1b467728d7eb4633db61c5f5de3d8e9373cf84d08fb0cdee03e1f58f02b9f1c51a4a8a865751695addbd465a77f73f1079be91fe5493b29c305fd77 languageName: node linkType: hard -"yargs-parser@npm:^21.1.1": - version: 21.1.1 - resolution: "yargs-parser@npm:21.1.1" - checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 +"yargs-parser@npm:^22.0.0": + version: 22.0.0 + resolution: "yargs-parser@npm:22.0.0" + checksum: 10c0/cb7ef81759c4271cb1d96b9351dbbc9a9ce35d3e1122d2b739bf6c432603824fa02c67cc12dcef6ea80283379d63495686e8f41cc7b06c6576e792aba4d33e1c languageName: node linkType: hard -"yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" +"yargs@npm:^18.0.0": + version: 18.0.0 + resolution: "yargs@npm:18.0.0" dependencies: - cliui: "npm:^8.0.1" + cliui: "npm:^9.0.1" escalade: "npm:^3.1.1" get-caller-file: "npm:^2.0.5" - require-directory: "npm:^2.1.1" - string-width: "npm:^4.2.3" + string-width: "npm:^7.2.0" y18n: "npm:^5.0.5" - yargs-parser: "npm:^21.1.1" - checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 + yargs-parser: "npm:^22.0.0" + checksum: 10c0/bf290e4723876ea9c638c786a5c42ac28e03c9ca2325e1424bf43b94e5876456292d3ed905b853ebbba6daf43ed29e772ac2a6b3c5fb1b16533245d6211778f3 languageName: node linkType: hard