From 044bc6608851c3f3d3a68dc413e3c769fa22647c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Charles?= Date: Fri, 12 Jul 2024 14:44:49 +0200 Subject: [PATCH] feat: hono adapter (#10) * feat: hono adapter * chore: cleanup * chore(hono): change build target to neutral * tests: run recursive tests sequentially * refactor: move core utils on new core package * refactor: move test utils on new tests package --- .eslintrc.json | 5 +- .github/workflows/ci.yml | 8 +- .idea/universal-handler.iml | 3 + package.json | 8 +- packages/.DS_Store | Bin 6148 -> 0 bytes packages/adapter-express/deno.json | 8 + packages/adapter-express/deno.lock | 140 +- packages/adapter-express/package.json | 11 +- packages/adapter-express/src/common.ts | 2 +- packages/adapter-express/tests/all.spec.ts | 96 - .../adapter-express/tests/entry-express.ts | 63 +- .../adapter-express/tests/express.spec.ts | 31 + packages/adapter-express/tsconfig.json | 23 +- packages/adapter-hono/deno.json | 8 + packages/adapter-hono/deno.lock | 1697 +++++++++++++++++ packages/adapter-hono/package.json | 42 + packages/adapter-hono/readme.md | 3 + packages/adapter-hono/src/common.ts | 52 + packages/adapter-hono/src/index.ts | 1 + packages/adapter-hono/tests/entry-hono.ts | 52 + packages/adapter-hono/tests/hono.spec.ts | 33 + packages/adapter-hono/tsconfig.json | 3 + packages/adapter-hono/tsup.config.ts | 12 + packages/adapter-hono/vitest.config.ts | 4 + packages/core/CHANGELOG.md | 4 + .../{adapter-express => core}/config.d.ts | 0 packages/core/package.json | 30 + packages/core/readme.md | 3 + packages/core/src/index.ts | 5 + .../{adapter-express => core}/src/types.ts | 0 packages/core/tsconfig.json | 3 + packages/core/tsup.config.ts | 18 + packages/tests/config.d.ts | 7 + packages/tests/package.json | 37 + packages/tests/readme.md | 3 + packages/tests/src/index.ts | 150 ++ packages/tests/tsconfig.json | 3 + packages/tests/tsup.config.ts | 12 + pnpm-lock.yaml | 162 +- tsconfig.json | 2 - 40 files changed, 2361 insertions(+), 383 deletions(-) delete mode 100644 packages/.DS_Store create mode 100644 packages/adapter-express/deno.json delete mode 100644 packages/adapter-express/tests/all.spec.ts create mode 100644 packages/adapter-express/tests/express.spec.ts create mode 100644 packages/adapter-hono/deno.json create mode 100644 packages/adapter-hono/deno.lock create mode 100644 packages/adapter-hono/package.json create mode 100644 packages/adapter-hono/readme.md create mode 100644 packages/adapter-hono/src/common.ts create mode 100644 packages/adapter-hono/src/index.ts create mode 100644 packages/adapter-hono/tests/entry-hono.ts create mode 100644 packages/adapter-hono/tests/hono.spec.ts create mode 100644 packages/adapter-hono/tsconfig.json create mode 100644 packages/adapter-hono/tsup.config.ts create mode 100644 packages/adapter-hono/vitest.config.ts create mode 100644 packages/core/CHANGELOG.md rename packages/{adapter-express => core}/config.d.ts (100%) create mode 100644 packages/core/package.json create mode 100644 packages/core/readme.md create mode 100644 packages/core/src/index.ts rename packages/{adapter-express => core}/src/types.ts (100%) create mode 100644 packages/core/tsconfig.json create mode 100644 packages/core/tsup.config.ts create mode 100644 packages/tests/config.d.ts create mode 100644 packages/tests/package.json create mode 100644 packages/tests/readme.md create mode 100644 packages/tests/src/index.ts create mode 100644 packages/tests/tsconfig.json create mode 100644 packages/tests/tsup.config.ts diff --git a/.eslintrc.json b/.eslintrc.json index 91a81f79..6f04ea2a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,13 +6,12 @@ "plugin:@typescript-eslint/recommended", "prettier" ], - "plugins": [ - "@typescript-eslint" - ], + "plugins": ["@typescript-eslint"], "parserOptions": { "sourceType": "module", "ecmaVersion": "latest" }, + "ignorePatterns": ["playground/**"], "rules": { "no-unused-labels": 0, "@typescript-eslint/ban-ts-comment": 0, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 139c9dcd..7f378afa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,5 +61,11 @@ jobs: - name: Build run: pnpm run build - - name: Run CI tests + - name: Run lint + run: pnpm run lint + + - name: Run typecheck + run: pnpm run test:typecheck + + - name: Run tests run: pnpm run test diff --git a/.idea/universal-handler.iml b/.idea/universal-handler.iml index 21f7f5d0..cde52d10 100644 --- a/.idea/universal-handler.iml +++ b/.idea/universal-handler.iml @@ -6,6 +6,9 @@ + + + diff --git a/package.json b/package.json index 1e439fa9..434dff9d 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "dev:hattip": "hattip serve ./playground/hattip-entry.ts --client", "lint": "eslint --ext .js,.jsx,.ts,.tsx .", "build": "pnpm run -r build", - "test": "pnpm run -r test" + "test": "pnpm run -r --sequential test", + "test:typecheck": "pnpm run -r test:typecheck" }, "keywords": [], "author": "", @@ -50,5 +51,10 @@ "tsx": "^4.16.2", "vite": "^5.3.3" }, + "pnpm": { + "overrides": { + "@universal-middleware/core": "link:./packages/core" + } + }, "packageManager": "pnpm@9.4.0" } diff --git a/packages/.DS_Store b/packages/.DS_Store deleted file mode 100644 index 3b9301a47f951dee78ea25d92d1862b4da79035e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKNlpVX5G+Fuk+|f@(I3bGUNA)Az?laCvj_qMGa_)GNAO>$a+_sf&Jlv{$X)GT zyp$B%10bxP>my(RV9q8CGA2as$-s-E z5%-L5@W6fbv?|G`bqOemqP z=dCbiEHVy;j8KA=60J1kPmEyY^v9f6WE>2w93jojaq`UXA1@)zPJc}42!)|*XTTX4 zGq7*nh3@}T{$(aV^2a6Ka|WD&KgK|qt1Niu|dZ=nsKJh%0Ac2MoLce`i4X diff --git a/packages/adapter-express/deno.json b/packages/adapter-express/deno.json new file mode 100644 index 00000000..7f101352 --- /dev/null +++ b/packages/adapter-express/deno.json @@ -0,0 +1,8 @@ +{ + "imports": { + "@universal-middleware/tests": "../tests/dist", + "mri": "npm:mri", + "zx": "npm:zx", + "wait-port": "npm:wait-port" + } +} diff --git a/packages/adapter-express/deno.lock b/packages/adapter-express/deno.lock index 4e68dac8..2b2a292d 100644 --- a/packages/adapter-express/deno.lock +++ b/packages/adapter-express/deno.lock @@ -4,18 +4,17 @@ "specifiers": { "npm:@brillout/release-me@^0.3.9": "npm:@brillout/release-me@0.3.9", "npm:@types/node@^20.14.10": "npm:@types/node@20.14.10", - "npm:express@4.18.2": "npm:express@4.18.2", + "npm:@universal-middleware/core@^0.1.1": "npm:@universal-middleware/core@0.1.1", "npm:express@^4.19.2": "npm:express@4.19.2", "npm:helmet@^7.1.0": "npm:helmet@7.1.0", - "npm:mri@^1.2.0": "npm:mri@1.2.0", - "npm:readable-stream@^4.5.2": "npm:readable-stream@4.5.2", + "npm:mri": "npm:mri@1.2.0", "npm:rimraf@^6.0.0": "npm:rimraf@6.0.1", "npm:tsup@^8.1.0": "npm:tsup@8.1.0_typescript@5.5.3_esbuild@0.21.5", "npm:tsx@^4.16.2": "npm:tsx@4.16.2", "npm:typescript@^5.5.3": "npm:typescript@5.5.3", "npm:vitest@^2.0.2": "npm:vitest@2.0.2_@types+node@20.14.10", - "npm:wait-port@^1.1.0": "npm:wait-port@1.1.0", - "npm:zx@^8.1.4": "npm:zx@8.1.4" + "npm:wait-port": "npm:wait-port@1.1.0", + "npm:zx": "npm:zx@8.1.4" }, "npm": { "@ampproject/remapping@2.3.0": { @@ -310,6 +309,10 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dependencies": {} }, + "@universal-middleware/core@0.1.1": { + "integrity": "sha512-1paKMQ/B/l5NL9j5vR3T7mvk3VqfP3aIuJj0XU5WvlrqZGjde1qFyjEDfw4RQtSkgloUobgttdhs4qzop9lS2g==", + "dependencies": {} + }, "@vitest/expect@2.0.2": { "integrity": "sha512-nKAvxBYqcDugYZ4nJvnm5OR8eDJdgWjk4XM9owQKUjzW70q0icGV2HVnQOyYsp906xJaBDUXw0+9EHw2T8e0mQ==", "dependencies": { @@ -362,12 +365,6 @@ "through": "through@2.3.8" } }, - "abort-controller@3.0.0": { - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "event-target-shim@5.0.1" - } - }, "accepts@1.3.8": { "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { @@ -434,31 +431,10 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dependencies": {} }, - "base64-js@1.5.1": { - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dependencies": {} - }, "binary-extensions@2.3.0": { "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dependencies": {} }, - "body-parser@1.20.1": { - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dependencies": { - "bytes": "bytes@3.1.2", - "content-type": "content-type@1.0.5", - "debug": "debug@2.6.9", - "depd": "depd@2.0.0", - "destroy": "destroy@1.2.0", - "http-errors": "http-errors@2.0.0", - "iconv-lite": "iconv-lite@0.4.24", - "on-finished": "on-finished@2.4.1", - "qs": "qs@6.11.0", - "raw-body": "raw-body@2.5.1", - "type-is": "type-is@1.6.18", - "unpipe": "unpipe@1.0.0" - } - }, "body-parser@1.20.2": { "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { @@ -488,13 +464,6 @@ "fill-range": "fill-range@7.1.1" } }, - "buffer@6.0.3": { - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dependencies": { - "base64-js": "base64-js@1.5.1", - "ieee754": "ieee754@1.2.1" - } - }, "bundle-require@4.2.1_esbuild@0.21.5": { "integrity": "sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==", "dependencies": { @@ -716,10 +685,6 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dependencies": {} }, - "cookie@0.5.0": { - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dependencies": {} - }, "cookie@0.6.0": { "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dependencies": {} @@ -862,14 +827,6 @@ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dependencies": {} }, - "event-target-shim@5.0.1": { - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dependencies": {} - }, - "events@3.3.0": { - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dependencies": {} - }, "execa@5.1.1": { "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dependencies": { @@ -898,42 +855,6 @@ "strip-final-newline": "strip-final-newline@3.0.0" } }, - "express@4.18.2": { - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "dependencies": { - "accepts": "accepts@1.3.8", - "array-flatten": "array-flatten@1.1.1", - "body-parser": "body-parser@1.20.1", - "content-disposition": "content-disposition@0.5.4", - "content-type": "content-type@1.0.5", - "cookie": "cookie@0.5.0", - "cookie-signature": "cookie-signature@1.0.6", - "debug": "debug@2.6.9", - "depd": "depd@2.0.0", - "encodeurl": "encodeurl@1.0.2", - "escape-html": "escape-html@1.0.3", - "etag": "etag@1.8.1", - "finalhandler": "finalhandler@1.2.0", - "fresh": "fresh@0.5.2", - "http-errors": "http-errors@2.0.0", - "merge-descriptors": "merge-descriptors@1.0.1", - "methods": "methods@1.1.2", - "on-finished": "on-finished@2.4.1", - "parseurl": "parseurl@1.3.3", - "path-to-regexp": "path-to-regexp@0.1.7", - "proxy-addr": "proxy-addr@2.0.7", - "qs": "qs@6.11.0", - "range-parser": "range-parser@1.2.1", - "safe-buffer": "safe-buffer@5.2.1", - "send": "send@0.18.0", - "serve-static": "serve-static@1.15.0", - "setprototypeof": "setprototypeof@1.2.0", - "statuses": "statuses@2.0.1", - "type-is": "type-is@1.6.18", - "utils-merge": "utils-merge@1.0.1", - "vary": "vary@1.1.2" - } - }, "express@4.19.2": { "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { @@ -1194,10 +1115,6 @@ "safer-buffer": "safer-buffer@2.1.2" } }, - "ieee754@1.2.1": { - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dependencies": {} - }, "ignore@5.3.1": { "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dependencies": {} @@ -1598,10 +1515,6 @@ "source-map-js": "source-map-js@1.2.0" } }, - "process@0.11.10": { - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dependencies": {} - }, "proxy-addr@2.0.7": { "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": { @@ -1627,15 +1540,6 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dependencies": {} }, - "raw-body@2.5.1": { - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "bytes@3.1.2", - "http-errors": "http-errors@2.0.0", - "iconv-lite": "iconv-lite@0.4.24", - "unpipe": "unpipe@1.0.0" - } - }, "raw-body@2.5.2": { "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { @@ -1662,16 +1566,6 @@ "type-fest": "type-fest@4.21.0" } }, - "readable-stream@4.5.2": { - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dependencies": { - "abort-controller": "abort-controller@3.0.0", - "buffer": "buffer@6.0.3", - "events": "events@3.3.0", - "process": "process@0.11.10", - "string_decoder": "string_decoder@1.3.0" - } - }, "readdirp@3.6.0": { "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { @@ -1883,12 +1777,6 @@ "strip-ansi": "strip-ansi@7.1.0" } }, - "string_decoder@1.3.0": { - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "safe-buffer@5.2.1" - } - }, "strip-ansi@6.0.1": { "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { @@ -2184,21 +2072,23 @@ }, "remote": {}, "workspace": { + "dependencies": [ + "npm:mri", + "npm:wait-port", + "npm:zx" + ], "packageJson": { "dependencies": [ "npm:@brillout/release-me@^0.3.9", "npm:@types/node@^20.14.10", + "npm:@universal-middleware/core@^0.1.1", "npm:express@^4.19.2", "npm:helmet@^7.1.0", - "npm:mri@^1.2.0", - "npm:readable-stream@^4.5.2", "npm:rimraf@^6.0.0", "npm:tsup@^8.1.0", "npm:tsx@^4.16.2", "npm:typescript@^5.5.3", - "npm:vitest@^2.0.2", - "npm:wait-port@^1.1.0", - "npm:zx@^8.1.4" + "npm:vitest@^2.0.2" ] } } diff --git a/packages/adapter-express/package.json b/packages/adapter-express/package.json index 9b82486d..f50e189e 100644 --- a/packages/adapter-express/package.json +++ b/packages/adapter-express/package.json @@ -6,7 +6,6 @@ "files": [ "dist" ], - "types": "./config.d.ts", "exports": { ".": "./dist/index.js" }, @@ -29,19 +28,19 @@ "release:minor": "LANG=en_US release-me minor", "release:commit": "LANG=en_US release-me commit" }, + "dependencies": { + "@universal-middleware/core": "^0.1.1" + }, "devDependencies": { "@brillout/release-me": "^0.3.9", "@types/node": "^20.14.10", + "@universal-middleware/tests": "workspace:*", "express": "^4.19.2", "helmet": "^7.1.0", - "mri": "^1.2.0", - "readable-stream": "^4.5.2", "rimraf": "^6.0.0", "tsup": "^8.1.0", "tsx": "^4.16.2", "typescript": "^5.5.3", - "vitest": "^2.0.2", - "wait-port": "^1.1.0", - "zx": "^8.1.4" + "vitest": "^2.0.2" } } diff --git a/packages/adapter-express/src/common.ts b/packages/adapter-express/src/common.ts index 3eaa9707..3360910c 100644 --- a/packages/adapter-express/src/common.ts +++ b/packages/adapter-express/src/common.ts @@ -9,7 +9,7 @@ import type { Awaitable, UniversalHandler, UniversalMiddleware, -} from "./types.js"; +} from "@universal-middleware/core"; export const contextSymbol = Symbol("unContext"); export const requestSymbol = Symbol("unRequest"); diff --git a/packages/adapter-express/tests/all.spec.ts b/packages/adapter-express/tests/all.spec.ts deleted file mode 100644 index 2bec8515..00000000 --- a/packages/adapter-express/tests/all.spec.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { kill } from "zx"; -import { afterAll, beforeAll, describe, expect, test } from "vitest"; -import { type ChildProcess, spawn } from "node:child_process"; -import waitPort from "wait-port"; - -interface Run { - name: string; - command: string; - port: number; -} - -const runs: Run[] = [ - { - name: "adapter-express: node", - command: "pnpm run test:run-express:node", - port: 3000, - }, - { - name: "adapter-express: bun", - command: "pnpm run test:run-express:bun", - port: 3001, - }, - { - name: "adapter-express: deno", - command: "pnpm run test:run-express:deno", - port: 3002, - }, -]; - -describe.concurrent.each(runs)("$name", (run) => { - let server: ChildProcess | undefined = undefined; - const { command, port } = run; - let host = `http://localhost:${port}`; - - beforeAll(async () => { - server = spawn(`${command} --port ${port}`, { - shell: true, - stdio: "inherit", - env: { - ...process.env, - }, - }); - - // Wait until server is ready - await new Promise((resolve, reject) => { - server!.on("error", (error) => { - server = undefined; - reject(error); - }); - - server!.on("exit", (code) => { - if (code !== 0) { - server = undefined; - reject(new Error(`Process exited with code ${code}`)); - } - }); - - waitPort({ port, interval: 250, timeout: 10_000 }) - .then((res) => { - if (res.ipVersion === 4) { - host = `http://127.0.0.1:${port}`; - } - resolve(undefined); - }) - .catch(reject); - }); - }, 30_000); - - afterAll(async () => { - const pid = server?.pid; - if (typeof pid === "number") { - await kill(pid, "SIGKILL").finally(() => { - server = undefined; - }); - } - }); - - test("middlewares", async () => { - const response = await fetch(host); - const text = await response.text(); - expect(response.status).toBe(200); - expect(JSON.parse(text)).toEqual({ - something: { - a: 1, - }, - somethingElse: { - b: 2, - }, - }); - expect(response.headers.get("x-test-value")).toBe("universal-middleware"); - expect(response.headers.has("x-should-be-removed")).toBe(false); - // added by helmet - expect(response.headers.has("content-security-policy")).toBe(true); - expect(response.headers.has("x-xss-protection")).toBe(true); - }); -}); diff --git a/packages/adapter-express/tests/entry-express.ts b/packages/adapter-express/tests/entry-express.ts index 7cd59933..cda175c0 100644 --- a/packages/adapter-express/tests/entry-express.ts +++ b/packages/adapter-express/tests/entry-express.ts @@ -1,73 +1,16 @@ import { createHandler, createMiddleware } from "../src/index.js"; import express from "express"; -import mri from "mri"; import helmet from "helmet"; - -declare global { - namespace Universal { - interface Context { - something?: Record; - somethingElse?: Record; - } - } -} - -const args = mri<{ port: string }>( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (globalThis as any).Deno?.args ?? globalThis.process.argv.slice(2), -); +import { args, handler, middlewares } from "@universal-middleware/tests"; const app = express(); -// standard express middleware app.use(helmet()); -// universal middleware that updates the context synchronously -app.use( - createMiddleware((_request, context) => { - context.something = { - a: 1, - c: 3, - }; - }), -); - -// universal middleware that update the response headers asynchronously -app.use( - createMiddleware((_request, _context) => { - return async (response) => { - response.headers.set("x-test-value", "universal-middleware"); - response.headers.delete("x-should-be-removed"); - - await new Promise((resolve) => setTimeout(resolve, 1000)); - - return response; - }; - }), -); - -// universal middleware that updates the context asynchronously -app.use( - createMiddleware(async (_request, context) => { - await new Promise((resolve) => setTimeout(resolve, 100)); - - context.somethingElse = { - b: 2, - }; - delete context.something!.c; - }), -); +middlewares.forEach((middleware) => app.use(createMiddleware(middleware))); // universal handler -app.use( - createHandler((_request, context) => { - return new Response(JSON.stringify(context, null, 2), { - headers: { - "x-should-be-removed": "universal-middleware", - }, - }); - }), -); +app.get("/", createHandler(handler)); const port = args.port ? parseInt(args.port) : 3000; diff --git a/packages/adapter-express/tests/express.spec.ts b/packages/adapter-express/tests/express.spec.ts new file mode 100644 index 00000000..80ae28bb --- /dev/null +++ b/packages/adapter-express/tests/express.spec.ts @@ -0,0 +1,31 @@ +import { type Run, runTests } from "@universal-middleware/tests"; +import * as vitest from "vitest"; + +let port = 3100; + +const runs: Run[] = [ + { + name: "adapter-express: node", + command: "pnpm run test:run-express:node", + port: port++, + }, + { + name: "adapter-express: bun", + command: "pnpm run test:run-express:bun", + port: port++, + }, + { + name: "adapter-express: deno", + command: "pnpm run test:run-express:deno", + port: port++, + }, +]; + +runTests(runs, { + vitest, + test(response) { + // added by helmet + vitest.expect(response.headers.has("content-security-policy")).toBe(true); + vitest.expect(response.headers.has("x-xss-protection")).toBe(true); + }, +}); diff --git a/packages/adapter-express/tsconfig.json b/packages/adapter-express/tsconfig.json index dff7e4f0..90b448ed 100644 --- a/packages/adapter-express/tsconfig.json +++ b/packages/adapter-express/tsconfig.json @@ -1,21 +1,6 @@ { - "compilerOptions": { - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "sourceMap": true, - "verbatimModuleSyntax": true, - "noEmit": true, - "module": "NodeNext", - "moduleResolution": "NodeNext", - "target": "ES2022", - "lib": [ - "ES2022", - "DOM", - "DOM.Iterable" - ] - }, - "exclude": ["**/dist/**/*"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["@types/node"] + } } diff --git a/packages/adapter-hono/deno.json b/packages/adapter-hono/deno.json new file mode 100644 index 00000000..7f101352 --- /dev/null +++ b/packages/adapter-hono/deno.json @@ -0,0 +1,8 @@ +{ + "imports": { + "@universal-middleware/tests": "../tests/dist", + "mri": "npm:mri", + "zx": "npm:zx", + "wait-port": "npm:wait-port" + } +} diff --git a/packages/adapter-hono/deno.lock b/packages/adapter-hono/deno.lock new file mode 100644 index 00000000..38ef4d13 --- /dev/null +++ b/packages/adapter-hono/deno.lock @@ -0,0 +1,1697 @@ +{ + "version": "3", + "packages": { + "specifiers": { + "npm:@brillout/release-me@^0.3.9": "npm:@brillout/release-me@0.3.9", + "npm:@types/node@^20.14.10": "npm:@types/node@20.14.10", + "npm:@universal-middleware/core@^0.1.1": "npm:@universal-middleware/core@0.1.1", + "npm:hono@^4.4.13": "npm:hono@4.4.13", + "npm:mri": "npm:mri@1.2.0", + "npm:rimraf@^6.0.0": "npm:rimraf@6.0.1", + "npm:tsup@^8.1.0": "npm:tsup@8.1.0_typescript@5.5.3_esbuild@0.21.5", + "npm:tsx@^4.16.2": "npm:tsx@4.16.2", + "npm:typescript@^5.5.3": "npm:typescript@5.5.3", + "npm:vitest@^2.0.2": "npm:vitest@2.0.2_@types+node@20.14.10", + "npm:wait-port": "npm:wait-port@1.1.0", + "npm:zx": "npm:zx@8.1.4" + }, + "npm": { + "@ampproject/remapping@2.3.0": { + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "@jridgewell/gen-mapping@0.3.5", + "@jridgewell/trace-mapping": "@jridgewell/trace-mapping@0.3.25" + } + }, + "@babel/code-frame@7.24.7": { + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dependencies": { + "@babel/highlight": "@babel/highlight@7.24.7", + "picocolors": "picocolors@1.0.1" + } + }, + "@babel/helper-validator-identifier@7.24.7": { + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dependencies": {} + }, + "@babel/highlight@7.24.7": { + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dependencies": { + "@babel/helper-validator-identifier": "@babel/helper-validator-identifier@7.24.7", + "chalk": "chalk@2.4.2", + "js-tokens": "js-tokens@4.0.0", + "picocolors": "picocolors@1.0.1" + } + }, + "@brillout/picocolors@1.0.13": { + "integrity": "sha512-LblvMKItHbvkaIMI+Awsk1EEjmReE8E8Mgjtj3Pdn/qBvwQ6e+ts5uEqG6iTrK6JWndcxrQgSe664KfoteN6fA==", + "dependencies": {} + }, + "@brillout/release-me@0.3.9": { + "integrity": "sha512-7Q9YD+rnVF9hFmRFNSEePAejYSgZzWABJTA5sFrfD1utREt5K8aokoldvm/WES83SOMIkPO97c2kII9J4snc7Q==", + "dependencies": { + "@brillout/picocolors": "@brillout/picocolors@1.0.13", + "commander": "commander@11.1.0", + "conventional-changelog": "conventional-changelog@5.1.0", + "execa": "execa@5.1.1", + "semver": "semver@7.6.2" + } + }, + "@esbuild/aix-ppc64@0.21.5": { + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "dependencies": {} + }, + "@esbuild/android-arm64@0.21.5": { + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "dependencies": {} + }, + "@esbuild/android-arm@0.21.5": { + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "dependencies": {} + }, + "@esbuild/android-x64@0.21.5": { + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "dependencies": {} + }, + "@esbuild/darwin-arm64@0.21.5": { + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "dependencies": {} + }, + "@esbuild/darwin-x64@0.21.5": { + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "dependencies": {} + }, + "@esbuild/freebsd-arm64@0.21.5": { + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "dependencies": {} + }, + "@esbuild/freebsd-x64@0.21.5": { + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "dependencies": {} + }, + "@esbuild/linux-arm64@0.21.5": { + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "dependencies": {} + }, + "@esbuild/linux-arm@0.21.5": { + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "dependencies": {} + }, + "@esbuild/linux-ia32@0.21.5": { + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "dependencies": {} + }, + "@esbuild/linux-loong64@0.21.5": { + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "dependencies": {} + }, + "@esbuild/linux-mips64el@0.21.5": { + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "dependencies": {} + }, + "@esbuild/linux-ppc64@0.21.5": { + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "dependencies": {} + }, + "@esbuild/linux-riscv64@0.21.5": { + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "dependencies": {} + }, + "@esbuild/linux-s390x@0.21.5": { + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "dependencies": {} + }, + "@esbuild/linux-x64@0.21.5": { + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "dependencies": {} + }, + "@esbuild/netbsd-x64@0.21.5": { + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "dependencies": {} + }, + "@esbuild/openbsd-x64@0.21.5": { + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "dependencies": {} + }, + "@esbuild/sunos-x64@0.21.5": { + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "dependencies": {} + }, + "@esbuild/win32-arm64@0.21.5": { + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "dependencies": {} + }, + "@esbuild/win32-ia32@0.21.5": { + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "dependencies": {} + }, + "@esbuild/win32-x64@0.21.5": { + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "dependencies": {} + }, + "@hutson/parse-repository-url@5.0.0": { + "integrity": "sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==", + "dependencies": {} + }, + "@isaacs/cliui@8.0.2": { + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "string-width@5.1.2", + "string-width-cjs": "string-width@4.2.3", + "strip-ansi": "strip-ansi@7.1.0", + "strip-ansi-cjs": "strip-ansi@6.0.1", + "wrap-ansi": "wrap-ansi@8.1.0", + "wrap-ansi-cjs": "wrap-ansi@7.0.0" + } + }, + "@jridgewell/gen-mapping@0.3.5": { + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "@jridgewell/set-array@1.2.1", + "@jridgewell/sourcemap-codec": "@jridgewell/sourcemap-codec@1.5.0", + "@jridgewell/trace-mapping": "@jridgewell/trace-mapping@0.3.25" + } + }, + "@jridgewell/resolve-uri@3.1.2": { + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dependencies": {} + }, + "@jridgewell/set-array@1.2.1": { + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dependencies": {} + }, + "@jridgewell/sourcemap-codec@1.5.0": { + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dependencies": {} + }, + "@jridgewell/trace-mapping@0.3.25": { + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "@jridgewell/resolve-uri@3.1.2", + "@jridgewell/sourcemap-codec": "@jridgewell/sourcemap-codec@1.5.0" + } + }, + "@nodelib/fs.scandir@2.1.5": { + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "@nodelib/fs.stat@2.0.5", + "run-parallel": "run-parallel@1.2.0" + } + }, + "@nodelib/fs.stat@2.0.5": { + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dependencies": {} + }, + "@nodelib/fs.walk@1.2.8": { + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "@nodelib/fs.scandir@2.1.5", + "fastq": "fastq@1.17.1" + } + }, + "@pkgjs/parseargs@0.11.0": { + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dependencies": {} + }, + "@rollup/rollup-android-arm-eabi@4.18.1": { + "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", + "dependencies": {} + }, + "@rollup/rollup-android-arm64@4.18.1": { + "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", + "dependencies": {} + }, + "@rollup/rollup-darwin-arm64@4.18.1": { + "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", + "dependencies": {} + }, + "@rollup/rollup-darwin-x64@4.18.1": { + "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", + "dependencies": {} + }, + "@rollup/rollup-linux-arm-gnueabihf@4.18.1": { + "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", + "dependencies": {} + }, + "@rollup/rollup-linux-arm-musleabihf@4.18.1": { + "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", + "dependencies": {} + }, + "@rollup/rollup-linux-arm64-gnu@4.18.1": { + "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", + "dependencies": {} + }, + "@rollup/rollup-linux-arm64-musl@4.18.1": { + "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", + "dependencies": {} + }, + "@rollup/rollup-linux-powerpc64le-gnu@4.18.1": { + "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", + "dependencies": {} + }, + "@rollup/rollup-linux-riscv64-gnu@4.18.1": { + "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", + "dependencies": {} + }, + "@rollup/rollup-linux-s390x-gnu@4.18.1": { + "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", + "dependencies": {} + }, + "@rollup/rollup-linux-x64-gnu@4.18.1": { + "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", + "dependencies": {} + }, + "@rollup/rollup-linux-x64-musl@4.18.1": { + "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", + "dependencies": {} + }, + "@rollup/rollup-win32-arm64-msvc@4.18.1": { + "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", + "dependencies": {} + }, + "@rollup/rollup-win32-ia32-msvc@4.18.1": { + "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", + "dependencies": {} + }, + "@rollup/rollup-win32-x64-msvc@4.18.1": { + "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", + "dependencies": {} + }, + "@types/estree@1.0.5": { + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dependencies": {} + }, + "@types/fs-extra@11.0.4": { + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dependencies": { + "@types/jsonfile": "@types/jsonfile@6.1.4", + "@types/node": "@types/node@18.16.19" + } + }, + "@types/jsonfile@6.1.4": { + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dependencies": { + "@types/node": "@types/node@18.16.19" + } + }, + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + }, + "@types/node@20.14.10": { + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dependencies": { + "undici-types": "undici-types@5.26.5" + } + }, + "@types/normalize-package-data@2.4.4": { + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dependencies": {} + }, + "@universal-middleware/core@0.1.1": { + "integrity": "sha512-1paKMQ/B/l5NL9j5vR3T7mvk3VqfP3aIuJj0XU5WvlrqZGjde1qFyjEDfw4RQtSkgloUobgttdhs4qzop9lS2g==", + "dependencies": {} + }, + "@vitest/expect@2.0.2": { + "integrity": "sha512-nKAvxBYqcDugYZ4nJvnm5OR8eDJdgWjk4XM9owQKUjzW70q0icGV2HVnQOyYsp906xJaBDUXw0+9EHw2T8e0mQ==", + "dependencies": { + "@vitest/spy": "@vitest/spy@2.0.2", + "@vitest/utils": "@vitest/utils@2.0.2", + "chai": "chai@5.1.1", + "tinyrainbow": "tinyrainbow@1.2.0" + } + }, + "@vitest/pretty-format@2.0.2": { + "integrity": "sha512-SBCyOXfGVvddRd9r2PwoVR0fonQjh9BMIcBMlSzbcNwFfGr6ZhOhvBzurjvi2F4ryut2HcqiFhNeDVGwru8tLg==", + "dependencies": { + "tinyrainbow": "tinyrainbow@1.2.0" + } + }, + "@vitest/runner@2.0.2": { + "integrity": "sha512-OCh437Vi8Wdbif1e0OvQcbfM3sW4s2lpmOjAE7qfLrpzJX2M7J1IQlNvEcb/fu6kaIB9n9n35wS0G2Q3en5kHg==", + "dependencies": { + "@vitest/utils": "@vitest/utils@2.0.2", + "pathe": "pathe@1.1.2" + } + }, + "@vitest/snapshot@2.0.2": { + "integrity": "sha512-Yc2ewhhZhx+0f9cSUdfzPRcsM6PhIb+S43wxE7OG0kTxqgqzo8tHkXFuFlndXeDMp09G3sY/X5OAo/RfYydf1g==", + "dependencies": { + "@vitest/pretty-format": "@vitest/pretty-format@2.0.2", + "magic-string": "magic-string@0.30.10", + "pathe": "pathe@1.1.2" + } + }, + "@vitest/spy@2.0.2": { + "integrity": "sha512-MgwJ4AZtCgqyp2d7WcQVE8aNG5vQ9zu9qMPYQHjsld/QVsrvg78beNrXdO4HYkP0lDahCO3P4F27aagIag+SGQ==", + "dependencies": { + "tinyspy": "tinyspy@3.0.0" + } + }, + "@vitest/utils@2.0.2": { + "integrity": "sha512-pxCY1v7kmOCWYWjzc0zfjGTA3Wmn8PKnlPvSrsA643P1NHl1fOyXj2Q9SaNlrlFE+ivCsxM80Ov3AR82RmHCWQ==", + "dependencies": { + "@vitest/pretty-format": "@vitest/pretty-format@2.0.2", + "estree-walker": "estree-walker@3.0.3", + "loupe": "loupe@3.1.1", + "tinyrainbow": "tinyrainbow@1.2.0" + } + }, + "JSONStream@1.3.5": { + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dependencies": { + "jsonparse": "jsonparse@1.3.1", + "through": "through@2.3.8" + } + }, + "add-stream@1.0.0": { + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", + "dependencies": {} + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dependencies": {} + }, + "ansi-regex@6.0.1": { + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dependencies": {} + }, + "ansi-styles@3.2.1": { + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "color-convert@1.9.3" + } + }, + "ansi-styles@4.3.0": { + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "color-convert@2.0.1" + } + }, + "ansi-styles@6.2.1": { + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dependencies": {} + }, + "any-promise@1.3.0": { + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dependencies": {} + }, + "anymatch@3.1.3": { + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "normalize-path@3.0.0", + "picomatch": "picomatch@2.3.1" + } + }, + "array-ify@1.0.0": { + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dependencies": {} + }, + "array-union@2.1.0": { + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dependencies": {} + }, + "assertion-error@2.0.1": { + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dependencies": {} + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dependencies": {} + }, + "binary-extensions@2.3.0": { + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dependencies": {} + }, + "brace-expansion@2.0.1": { + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "balanced-match@1.0.2" + } + }, + "braces@3.0.3": { + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "fill-range@7.1.1" + } + }, + "bundle-require@4.2.1_esbuild@0.21.5": { + "integrity": "sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==", + "dependencies": { + "esbuild": "esbuild@0.21.5", + "load-tsconfig": "load-tsconfig@0.2.5" + } + }, + "cac@6.7.14": { + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dependencies": {} + }, + "chai@5.1.1": { + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dependencies": { + "assertion-error": "assertion-error@2.0.1", + "check-error": "check-error@2.1.1", + "deep-eql": "deep-eql@5.0.2", + "loupe": "loupe@3.1.1", + "pathval": "pathval@2.0.0" + } + }, + "chalk@2.4.2": { + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "ansi-styles@3.2.1", + "escape-string-regexp": "escape-string-regexp@1.0.5", + "supports-color": "supports-color@5.5.0" + } + }, + "chalk@4.1.2": { + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "ansi-styles@4.3.0", + "supports-color": "supports-color@7.2.0" + } + }, + "check-error@2.1.1": { + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dependencies": {} + }, + "chokidar@3.6.0": { + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "anymatch@3.1.3", + "braces": "braces@3.0.3", + "fsevents": "fsevents@2.3.3", + "glob-parent": "glob-parent@5.1.2", + "is-binary-path": "is-binary-path@2.1.0", + "is-glob": "is-glob@4.0.3", + "normalize-path": "normalize-path@3.0.0", + "readdirp": "readdirp@3.6.0" + } + }, + "color-convert@1.9.3": { + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "color-name@1.1.3" + } + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "color-name@1.1.4" + } + }, + "color-name@1.1.3": { + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dependencies": {} + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dependencies": {} + }, + "commander@11.1.0": { + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dependencies": {} + }, + "commander@4.1.1": { + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dependencies": {} + }, + "commander@9.5.0": { + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dependencies": {} + }, + "compare-func@2.0.0": { + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dependencies": { + "array-ify": "array-ify@1.0.0", + "dot-prop": "dot-prop@5.3.0" + } + }, + "conventional-changelog-angular@7.0.0": { + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dependencies": { + "compare-func": "compare-func@2.0.0" + } + }, + "conventional-changelog-atom@4.0.0": { + "integrity": "sha512-q2YtiN7rnT1TGwPTwjjBSIPIzDJCRE+XAUahWxnh+buKK99Kks4WLMHoexw38GXx9OUxAsrp44f9qXe5VEMYhw==", + "dependencies": {} + }, + "conventional-changelog-codemirror@4.0.0": { + "integrity": "sha512-hQSojc/5imn1GJK3A75m9hEZZhc3urojA5gMpnar4JHmgLnuM3CUIARPpEk86glEKr3c54Po3WV/vCaO/U8g3Q==", + "dependencies": {} + }, + "conventional-changelog-conventionalcommits@7.0.2": { + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", + "dependencies": { + "compare-func": "compare-func@2.0.0" + } + }, + "conventional-changelog-core@7.0.0": { + "integrity": "sha512-UYgaB1F/COt7VFjlYKVE/9tTzfU3VUq47r6iWf6lM5T7TlOxr0thI63ojQueRLIpVbrtHK4Ffw+yQGduw2Bhdg==", + "dependencies": { + "@hutson/parse-repository-url": "@hutson/parse-repository-url@5.0.0", + "add-stream": "add-stream@1.0.0", + "conventional-changelog-writer": "conventional-changelog-writer@7.0.1", + "conventional-commits-parser": "conventional-commits-parser@5.0.0", + "git-raw-commits": "git-raw-commits@4.0.0", + "git-semver-tags": "git-semver-tags@7.0.1", + "hosted-git-info": "hosted-git-info@7.0.2", + "normalize-package-data": "normalize-package-data@6.0.2", + "read-pkg": "read-pkg@8.1.0", + "read-pkg-up": "read-pkg-up@10.1.0" + } + }, + "conventional-changelog-ember@4.0.0": { + "integrity": "sha512-D0IMhwcJUg1Y8FSry6XAplEJcljkHVlvAZddhhsdbL1rbsqRsMfGx/PIkPYq0ru5aDgn+OxhQ5N5yR7P9mfsvA==", + "dependencies": {} + }, + "conventional-changelog-eslint@5.0.0": { + "integrity": "sha512-6JtLWqAQIeJLn/OzUlYmzd9fKeNSWmQVim9kql+v4GrZwLx807kAJl3IJVc3jTYfVKWLxhC3BGUxYiuVEcVjgA==", + "dependencies": {} + }, + "conventional-changelog-express@4.0.0": { + "integrity": "sha512-yWyy5c7raP9v7aTvPAWzqrztACNO9+FEI1FSYh7UP7YT1AkWgv5UspUeB5v3Ibv4/o60zj2o9GF2tqKQ99lIsw==", + "dependencies": {} + }, + "conventional-changelog-jquery@5.0.0": { + "integrity": "sha512-slLjlXLRNa/icMI3+uGLQbtrgEny3RgITeCxevJB+p05ExiTgHACP5p3XiMKzjBn80n+Rzr83XMYfRInEtCPPw==", + "dependencies": {} + }, + "conventional-changelog-jshint@4.0.0": { + "integrity": "sha512-LyXq1bbl0yG0Ai1SbLxIk8ZxUOe3AjnlwE6sVRQmMgetBk+4gY9EO3d00zlEt8Y8gwsITytDnPORl8al7InTjg==", + "dependencies": { + "compare-func": "compare-func@2.0.0" + } + }, + "conventional-changelog-preset-loader@4.1.0": { + "integrity": "sha512-HozQjJicZTuRhCRTq4rZbefaiCzRM2pr6u2NL3XhrmQm4RMnDXfESU6JKu/pnKwx5xtdkYfNCsbhN5exhiKGJA==", + "dependencies": {} + }, + "conventional-changelog-writer@7.0.1": { + "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", + "dependencies": { + "conventional-commits-filter": "conventional-commits-filter@4.0.0", + "handlebars": "handlebars@4.7.8", + "json-stringify-safe": "json-stringify-safe@5.0.1", + "meow": "meow@12.1.1", + "semver": "semver@7.6.2", + "split2": "split2@4.2.0" + } + }, + "conventional-changelog@5.1.0": { + "integrity": "sha512-aWyE/P39wGYRPllcCEZDxTVEmhyLzTc9XA6z6rVfkuCD2UBnhV/sgSOKbQrEG5z9mEZJjnopjgQooTKxEg8mAg==", + "dependencies": { + "conventional-changelog-angular": "conventional-changelog-angular@7.0.0", + "conventional-changelog-atom": "conventional-changelog-atom@4.0.0", + "conventional-changelog-codemirror": "conventional-changelog-codemirror@4.0.0", + "conventional-changelog-conventionalcommits": "conventional-changelog-conventionalcommits@7.0.2", + "conventional-changelog-core": "conventional-changelog-core@7.0.0", + "conventional-changelog-ember": "conventional-changelog-ember@4.0.0", + "conventional-changelog-eslint": "conventional-changelog-eslint@5.0.0", + "conventional-changelog-express": "conventional-changelog-express@4.0.0", + "conventional-changelog-jquery": "conventional-changelog-jquery@5.0.0", + "conventional-changelog-jshint": "conventional-changelog-jshint@4.0.0", + "conventional-changelog-preset-loader": "conventional-changelog-preset-loader@4.1.0" + } + }, + "conventional-commits-filter@4.0.0": { + "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", + "dependencies": {} + }, + "conventional-commits-parser@5.0.0": { + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dependencies": { + "JSONStream": "JSONStream@1.3.5", + "is-text-path": "is-text-path@2.0.0", + "meow": "meow@12.1.1", + "split2": "split2@4.2.0" + } + }, + "cross-spawn@7.0.3": { + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "path-key@3.1.1", + "shebang-command": "shebang-command@2.0.0", + "which": "which@2.0.2" + } + }, + "dargs@8.1.0": { + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dependencies": {} + }, + "debug@4.3.5": { + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "ms@2.1.2" + } + }, + "deep-eql@5.0.2": { + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dependencies": {} + }, + "dir-glob@3.0.1": { + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "path-type@4.0.0" + } + }, + "dot-prop@5.3.0": { + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dependencies": { + "is-obj": "is-obj@2.0.0" + } + }, + "eastasianwidth@0.2.0": { + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dependencies": {} + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dependencies": {} + }, + "emoji-regex@9.2.2": { + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dependencies": {} + }, + "error-ex@1.3.2": { + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "is-arrayish@0.2.1" + } + }, + "esbuild@0.21.5": { + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dependencies": { + "@esbuild/aix-ppc64": "@esbuild/aix-ppc64@0.21.5", + "@esbuild/android-arm": "@esbuild/android-arm@0.21.5", + "@esbuild/android-arm64": "@esbuild/android-arm64@0.21.5", + "@esbuild/android-x64": "@esbuild/android-x64@0.21.5", + "@esbuild/darwin-arm64": "@esbuild/darwin-arm64@0.21.5", + "@esbuild/darwin-x64": "@esbuild/darwin-x64@0.21.5", + "@esbuild/freebsd-arm64": "@esbuild/freebsd-arm64@0.21.5", + "@esbuild/freebsd-x64": "@esbuild/freebsd-x64@0.21.5", + "@esbuild/linux-arm": "@esbuild/linux-arm@0.21.5", + "@esbuild/linux-arm64": "@esbuild/linux-arm64@0.21.5", + "@esbuild/linux-ia32": "@esbuild/linux-ia32@0.21.5", + "@esbuild/linux-loong64": "@esbuild/linux-loong64@0.21.5", + "@esbuild/linux-mips64el": "@esbuild/linux-mips64el@0.21.5", + "@esbuild/linux-ppc64": "@esbuild/linux-ppc64@0.21.5", + "@esbuild/linux-riscv64": "@esbuild/linux-riscv64@0.21.5", + "@esbuild/linux-s390x": "@esbuild/linux-s390x@0.21.5", + "@esbuild/linux-x64": "@esbuild/linux-x64@0.21.5", + "@esbuild/netbsd-x64": "@esbuild/netbsd-x64@0.21.5", + "@esbuild/openbsd-x64": "@esbuild/openbsd-x64@0.21.5", + "@esbuild/sunos-x64": "@esbuild/sunos-x64@0.21.5", + "@esbuild/win32-arm64": "@esbuild/win32-arm64@0.21.5", + "@esbuild/win32-ia32": "@esbuild/win32-ia32@0.21.5", + "@esbuild/win32-x64": "@esbuild/win32-x64@0.21.5" + } + }, + "escape-string-regexp@1.0.5": { + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dependencies": {} + }, + "estree-walker@3.0.3": { + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "@types/estree@1.0.5" + } + }, + "execa@5.1.1": { + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "cross-spawn@7.0.3", + "get-stream": "get-stream@6.0.1", + "human-signals": "human-signals@2.1.0", + "is-stream": "is-stream@2.0.1", + "merge-stream": "merge-stream@2.0.0", + "npm-run-path": "npm-run-path@4.0.1", + "onetime": "onetime@5.1.2", + "signal-exit": "signal-exit@3.0.7", + "strip-final-newline": "strip-final-newline@2.0.0" + } + }, + "execa@8.0.1": { + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dependencies": { + "cross-spawn": "cross-spawn@7.0.3", + "get-stream": "get-stream@8.0.1", + "human-signals": "human-signals@5.0.0", + "is-stream": "is-stream@3.0.0", + "merge-stream": "merge-stream@2.0.0", + "npm-run-path": "npm-run-path@5.3.0", + "onetime": "onetime@6.0.0", + "signal-exit": "signal-exit@4.1.0", + "strip-final-newline": "strip-final-newline@3.0.0" + } + }, + "fast-glob@3.3.2": { + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "@nodelib/fs.stat@2.0.5", + "@nodelib/fs.walk": "@nodelib/fs.walk@1.2.8", + "glob-parent": "glob-parent@5.1.2", + "merge2": "merge2@1.4.1", + "micromatch": "micromatch@4.0.7" + } + }, + "fastq@1.17.1": { + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "reusify@1.0.4" + } + }, + "fill-range@7.1.1": { + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "to-regex-range@5.0.1" + } + }, + "find-up@6.3.0": { + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dependencies": { + "locate-path": "locate-path@7.2.0", + "path-exists": "path-exists@5.0.0" + } + }, + "foreground-child@3.2.1": { + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dependencies": { + "cross-spawn": "cross-spawn@7.0.3", + "signal-exit": "signal-exit@4.1.0" + } + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dependencies": {} + }, + "get-func-name@2.0.2": { + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dependencies": {} + }, + "get-stream@6.0.1": { + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dependencies": {} + }, + "get-stream@8.0.1": { + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dependencies": {} + }, + "get-tsconfig@4.7.5": { + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dependencies": { + "resolve-pkg-maps": "resolve-pkg-maps@1.0.0" + } + }, + "git-raw-commits@4.0.0": { + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dependencies": { + "dargs": "dargs@8.1.0", + "meow": "meow@12.1.1", + "split2": "split2@4.2.0" + } + }, + "git-semver-tags@7.0.1": { + "integrity": "sha512-NY0ZHjJzyyNXHTDZmj+GG7PyuAKtMsyWSwh07CR2hOZFa+/yoTsXci/nF2obzL8UDhakFNkD9gNdt/Ed+cxh2Q==", + "dependencies": { + "meow": "meow@12.1.1", + "semver": "semver@7.6.2" + } + }, + "glob-parent@5.1.2": { + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "is-glob@4.0.3" + } + }, + "glob@10.4.5": { + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "foreground-child@3.2.1", + "jackspeak": "jackspeak@3.4.3", + "minimatch": "minimatch@9.0.5", + "minipass": "minipass@7.1.2", + "package-json-from-dist": "package-json-from-dist@1.0.0", + "path-scurry": "path-scurry@1.11.1" + } + }, + "glob@11.0.0": { + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dependencies": { + "foreground-child": "foreground-child@3.2.1", + "jackspeak": "jackspeak@4.0.1", + "minimatch": "minimatch@10.0.1", + "minipass": "minipass@7.1.2", + "package-json-from-dist": "package-json-from-dist@1.0.0", + "path-scurry": "path-scurry@2.0.0" + } + }, + "globby@11.1.0": { + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "array-union@2.1.0", + "dir-glob": "dir-glob@3.0.1", + "fast-glob": "fast-glob@3.3.2", + "ignore": "ignore@5.3.1", + "merge2": "merge2@1.4.1", + "slash": "slash@3.0.0" + } + }, + "handlebars@4.7.8": { + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dependencies": { + "minimist": "minimist@1.2.8", + "neo-async": "neo-async@2.6.2", + "source-map": "source-map@0.6.1", + "uglify-js": "uglify-js@3.18.0", + "wordwrap": "wordwrap@1.0.0" + } + }, + "has-flag@3.0.0": { + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dependencies": {} + }, + "has-flag@4.0.0": { + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dependencies": {} + }, + "hono@4.4.13": { + "integrity": "sha512-c6qqenclmQ6wpXzqiElMa2jt423PVCmgBreDfC5s2lPPpGk7d0lOymd8QTzFZyYC5mSSs6imiTMPip+gLwuW/g==", + "dependencies": {} + }, + "hosted-git-info@7.0.2": { + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dependencies": { + "lru-cache": "lru-cache@10.4.3" + } + }, + "human-signals@2.1.0": { + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dependencies": {} + }, + "human-signals@5.0.0": { + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dependencies": {} + }, + "ignore@5.3.1": { + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dependencies": {} + }, + "is-arrayish@0.2.1": { + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dependencies": {} + }, + "is-binary-path@2.1.0": { + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "binary-extensions@2.3.0" + } + }, + "is-extglob@2.1.1": { + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dependencies": {} + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dependencies": {} + }, + "is-glob@4.0.3": { + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "is-extglob@2.1.1" + } + }, + "is-number@7.0.0": { + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dependencies": {} + }, + "is-obj@2.0.0": { + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dependencies": {} + }, + "is-stream@2.0.1": { + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dependencies": {} + }, + "is-stream@3.0.0": { + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dependencies": {} + }, + "is-text-path@2.0.0": { + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dependencies": { + "text-extensions": "text-extensions@2.4.0" + } + }, + "isexe@2.0.0": { + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dependencies": {} + }, + "jackspeak@3.4.3": { + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "@isaacs/cliui@8.0.2", + "@pkgjs/parseargs": "@pkgjs/parseargs@0.11.0" + } + }, + "jackspeak@4.0.1": { + "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", + "dependencies": { + "@isaacs/cliui": "@isaacs/cliui@8.0.2", + "@pkgjs/parseargs": "@pkgjs/parseargs@0.11.0" + } + }, + "joycon@3.1.1": { + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dependencies": {} + }, + "js-tokens@4.0.0": { + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dependencies": {} + }, + "json-parse-even-better-errors@3.0.2": { + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dependencies": {} + }, + "json-stringify-safe@5.0.1": { + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dependencies": {} + }, + "jsonparse@1.3.1": { + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dependencies": {} + }, + "lilconfig@3.1.2": { + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dependencies": {} + }, + "lines-and-columns@1.2.4": { + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dependencies": {} + }, + "lines-and-columns@2.0.4": { + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dependencies": {} + }, + "load-tsconfig@0.2.5": { + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dependencies": {} + }, + "locate-path@7.2.0": { + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dependencies": { + "p-locate": "p-locate@6.0.0" + } + }, + "lodash.sortby@4.7.0": { + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", + "dependencies": {} + }, + "loupe@3.1.1": { + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dependencies": { + "get-func-name": "get-func-name@2.0.2" + } + }, + "lru-cache@10.4.3": { + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dependencies": {} + }, + "lru-cache@11.0.0": { + "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "dependencies": {} + }, + "magic-string@0.30.10": { + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dependencies": { + "@jridgewell/sourcemap-codec": "@jridgewell/sourcemap-codec@1.5.0" + } + }, + "meow@12.1.1": { + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dependencies": {} + }, + "merge-stream@2.0.0": { + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dependencies": {} + }, + "merge2@1.4.1": { + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dependencies": {} + }, + "micromatch@4.0.7": { + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dependencies": { + "braces": "braces@3.0.3", + "picomatch": "picomatch@2.3.1" + } + }, + "mimic-fn@2.1.0": { + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dependencies": {} + }, + "mimic-fn@4.0.0": { + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dependencies": {} + }, + "minimatch@10.0.1": { + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dependencies": { + "brace-expansion": "brace-expansion@2.0.1" + } + }, + "minimatch@9.0.5": { + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "brace-expansion@2.0.1" + } + }, + "minimist@1.2.8": { + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dependencies": {} + }, + "minipass@7.1.2": { + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dependencies": {} + }, + "mri@1.2.0": { + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dependencies": {} + }, + "ms@2.1.2": { + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dependencies": {} + }, + "mz@2.7.0": { + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "any-promise@1.3.0", + "object-assign": "object-assign@4.1.1", + "thenify-all": "thenify-all@1.6.0" + } + }, + "nanoid@3.3.7": { + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dependencies": {} + }, + "neo-async@2.6.2": { + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dependencies": {} + }, + "normalize-package-data@6.0.2": { + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dependencies": { + "hosted-git-info": "hosted-git-info@7.0.2", + "semver": "semver@7.6.2", + "validate-npm-package-license": "validate-npm-package-license@3.0.4" + } + }, + "normalize-path@3.0.0": { + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dependencies": {} + }, + "npm-run-path@4.0.1": { + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "path-key@3.1.1" + } + }, + "npm-run-path@5.3.0": { + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dependencies": { + "path-key": "path-key@4.0.0" + } + }, + "object-assign@4.1.1": { + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dependencies": {} + }, + "onetime@5.1.2": { + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "mimic-fn@2.1.0" + } + }, + "onetime@6.0.0": { + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dependencies": { + "mimic-fn": "mimic-fn@4.0.0" + } + }, + "p-limit@4.0.0": { + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dependencies": { + "yocto-queue": "yocto-queue@1.1.1" + } + }, + "p-locate@6.0.0": { + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dependencies": { + "p-limit": "p-limit@4.0.0" + } + }, + "package-json-from-dist@1.0.0": { + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dependencies": {} + }, + "parse-json@7.1.1": { + "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", + "dependencies": { + "@babel/code-frame": "@babel/code-frame@7.24.7", + "error-ex": "error-ex@1.3.2", + "json-parse-even-better-errors": "json-parse-even-better-errors@3.0.2", + "lines-and-columns": "lines-and-columns@2.0.4", + "type-fest": "type-fest@3.13.1" + } + }, + "path-exists@5.0.0": { + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dependencies": {} + }, + "path-key@3.1.1": { + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dependencies": {} + }, + "path-key@4.0.0": { + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dependencies": {} + }, + "path-scurry@1.11.1": { + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "lru-cache@10.4.3", + "minipass": "minipass@7.1.2" + } + }, + "path-scurry@2.0.0": { + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dependencies": { + "lru-cache": "lru-cache@11.0.0", + "minipass": "minipass@7.1.2" + } + }, + "path-type@4.0.0": { + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dependencies": {} + }, + "pathe@1.1.2": { + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dependencies": {} + }, + "pathval@2.0.0": { + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dependencies": {} + }, + "picocolors@1.0.1": { + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dependencies": {} + }, + "picomatch@2.3.1": { + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dependencies": {} + }, + "pirates@4.0.6": { + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dependencies": {} + }, + "postcss-load-config@4.0.2": { + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dependencies": { + "lilconfig": "lilconfig@3.1.2", + "yaml": "yaml@2.4.5" + } + }, + "postcss@8.4.39": { + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dependencies": { + "nanoid": "nanoid@3.3.7", + "picocolors": "picocolors@1.0.1", + "source-map-js": "source-map-js@1.2.0" + } + }, + "punycode@2.3.1": { + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dependencies": {} + }, + "queue-microtask@1.2.3": { + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dependencies": {} + }, + "read-pkg-up@10.1.0": { + "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", + "dependencies": { + "find-up": "find-up@6.3.0", + "read-pkg": "read-pkg@8.1.0", + "type-fest": "type-fest@4.21.0" + } + }, + "read-pkg@8.1.0": { + "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", + "dependencies": { + "@types/normalize-package-data": "@types/normalize-package-data@2.4.4", + "normalize-package-data": "normalize-package-data@6.0.2", + "parse-json": "parse-json@7.1.1", + "type-fest": "type-fest@4.21.0" + } + }, + "readdirp@3.6.0": { + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "picomatch@2.3.1" + } + }, + "resolve-from@5.0.0": { + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dependencies": {} + }, + "resolve-pkg-maps@1.0.0": { + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dependencies": {} + }, + "reusify@1.0.4": { + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dependencies": {} + }, + "rimraf@6.0.1": { + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dependencies": { + "glob": "glob@11.0.0", + "package-json-from-dist": "package-json-from-dist@1.0.0" + } + }, + "rollup@4.18.1": { + "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", + "dependencies": { + "@rollup/rollup-android-arm-eabi": "@rollup/rollup-android-arm-eabi@4.18.1", + "@rollup/rollup-android-arm64": "@rollup/rollup-android-arm64@4.18.1", + "@rollup/rollup-darwin-arm64": "@rollup/rollup-darwin-arm64@4.18.1", + "@rollup/rollup-darwin-x64": "@rollup/rollup-darwin-x64@4.18.1", + "@rollup/rollup-linux-arm-gnueabihf": "@rollup/rollup-linux-arm-gnueabihf@4.18.1", + "@rollup/rollup-linux-arm-musleabihf": "@rollup/rollup-linux-arm-musleabihf@4.18.1", + "@rollup/rollup-linux-arm64-gnu": "@rollup/rollup-linux-arm64-gnu@4.18.1", + "@rollup/rollup-linux-arm64-musl": "@rollup/rollup-linux-arm64-musl@4.18.1", + "@rollup/rollup-linux-powerpc64le-gnu": "@rollup/rollup-linux-powerpc64le-gnu@4.18.1", + "@rollup/rollup-linux-riscv64-gnu": "@rollup/rollup-linux-riscv64-gnu@4.18.1", + "@rollup/rollup-linux-s390x-gnu": "@rollup/rollup-linux-s390x-gnu@4.18.1", + "@rollup/rollup-linux-x64-gnu": "@rollup/rollup-linux-x64-gnu@4.18.1", + "@rollup/rollup-linux-x64-musl": "@rollup/rollup-linux-x64-musl@4.18.1", + "@rollup/rollup-win32-arm64-msvc": "@rollup/rollup-win32-arm64-msvc@4.18.1", + "@rollup/rollup-win32-ia32-msvc": "@rollup/rollup-win32-ia32-msvc@4.18.1", + "@rollup/rollup-win32-x64-msvc": "@rollup/rollup-win32-x64-msvc@4.18.1", + "@types/estree": "@types/estree@1.0.5", + "fsevents": "fsevents@2.3.3" + } + }, + "run-parallel@1.2.0": { + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": { + "queue-microtask": "queue-microtask@1.2.3" + } + }, + "semver@7.6.2": { + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dependencies": {} + }, + "shebang-command@2.0.0": { + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "shebang-regex@3.0.0" + } + }, + "shebang-regex@3.0.0": { + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dependencies": {} + }, + "siginfo@2.0.0": { + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dependencies": {} + }, + "signal-exit@3.0.7": { + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dependencies": {} + }, + "signal-exit@4.1.0": { + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dependencies": {} + }, + "slash@3.0.0": { + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dependencies": {} + }, + "source-map-js@1.2.0": { + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dependencies": {} + }, + "source-map@0.6.1": { + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dependencies": {} + }, + "source-map@0.8.0-beta.0": { + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "whatwg-url@7.1.0" + } + }, + "spdx-correct@3.2.0": { + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dependencies": { + "spdx-expression-parse": "spdx-expression-parse@3.0.1", + "spdx-license-ids": "spdx-license-ids@3.0.18" + } + }, + "spdx-exceptions@2.5.0": { + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dependencies": {} + }, + "spdx-expression-parse@3.0.1": { + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dependencies": { + "spdx-exceptions": "spdx-exceptions@2.5.0", + "spdx-license-ids": "spdx-license-ids@3.0.18" + } + }, + "spdx-license-ids@3.0.18": { + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dependencies": {} + }, + "split2@4.2.0": { + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dependencies": {} + }, + "stackback@0.0.2": { + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dependencies": {} + }, + "std-env@3.7.0": { + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dependencies": {} + }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "emoji-regex@8.0.0", + "is-fullwidth-code-point": "is-fullwidth-code-point@3.0.0", + "strip-ansi": "strip-ansi@6.0.1" + } + }, + "string-width@5.1.2": { + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "eastasianwidth@0.2.0", + "emoji-regex": "emoji-regex@9.2.2", + "strip-ansi": "strip-ansi@7.1.0" + } + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "ansi-regex@5.0.1" + } + }, + "strip-ansi@7.1.0": { + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "ansi-regex@6.0.1" + } + }, + "strip-final-newline@2.0.0": { + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dependencies": {} + }, + "strip-final-newline@3.0.0": { + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dependencies": {} + }, + "sucrase@3.35.0": { + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "@jridgewell/gen-mapping@0.3.5", + "commander": "commander@4.1.1", + "glob": "glob@10.4.5", + "lines-and-columns": "lines-and-columns@1.2.4", + "mz": "mz@2.7.0", + "pirates": "pirates@4.0.6", + "ts-interface-checker": "ts-interface-checker@0.1.13" + } + }, + "supports-color@5.5.0": { + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "has-flag@3.0.0" + } + }, + "supports-color@7.2.0": { + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "has-flag@4.0.0" + } + }, + "text-extensions@2.4.0": { + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dependencies": {} + }, + "thenify-all@1.6.0": { + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": "thenify@3.3.1" + } + }, + "thenify@3.3.1": { + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "any-promise@1.3.0" + } + }, + "through@2.3.8": { + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dependencies": {} + }, + "tinybench@2.8.0": { + "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "dependencies": {} + }, + "tinypool@1.0.0": { + "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "dependencies": {} + }, + "tinyrainbow@1.2.0": { + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dependencies": {} + }, + "tinyspy@3.0.0": { + "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "dependencies": {} + }, + "to-regex-range@5.0.1": { + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "is-number@7.0.0" + } + }, + "tr46@1.0.1": { + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "punycode@2.3.1" + } + }, + "tree-kill@1.2.2": { + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dependencies": {} + }, + "ts-interface-checker@0.1.13": { + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dependencies": {} + }, + "tsup@8.1.0_typescript@5.5.3_esbuild@0.21.5": { + "integrity": "sha512-UFdfCAXukax+U6KzeTNO2kAARHcWxmKsnvSPXUcfA1D+kU05XDccCrkffCQpFaWDsZfV0jMyTsxU39VfCp6EOg==", + "dependencies": { + "bundle-require": "bundle-require@4.2.1_esbuild@0.21.5", + "cac": "cac@6.7.14", + "chokidar": "chokidar@3.6.0", + "debug": "debug@4.3.5", + "esbuild": "esbuild@0.21.5", + "execa": "execa@5.1.1", + "globby": "globby@11.1.0", + "joycon": "joycon@3.1.1", + "postcss-load-config": "postcss-load-config@4.0.2", + "resolve-from": "resolve-from@5.0.0", + "rollup": "rollup@4.18.1", + "source-map": "source-map@0.8.0-beta.0", + "sucrase": "sucrase@3.35.0", + "tree-kill": "tree-kill@1.2.2", + "typescript": "typescript@5.5.3" + } + }, + "tsx@4.16.2": { + "integrity": "sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==", + "dependencies": { + "esbuild": "esbuild@0.21.5", + "fsevents": "fsevents@2.3.3", + "get-tsconfig": "get-tsconfig@4.7.5" + } + }, + "type-fest@3.13.1": { + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dependencies": {} + }, + "type-fest@4.21.0": { + "integrity": "sha512-ADn2w7hVPcK6w1I0uWnM//y1rLXZhzB9mr0a3OirzclKF1Wp6VzevUmzz/NRAWunOT6E8HrnpGY7xOfc6K57fA==", + "dependencies": {} + }, + "typescript@5.5.3": { + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dependencies": {} + }, + "uglify-js@3.18.0": { + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "dependencies": {} + }, + "undici-types@5.26.5": { + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dependencies": {} + }, + "validate-npm-package-license@3.0.4": { + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dependencies": { + "spdx-correct": "spdx-correct@3.2.0", + "spdx-expression-parse": "spdx-expression-parse@3.0.1" + } + }, + "vite-node@2.0.2_@types+node@20.14.10": { + "integrity": "sha512-w4vkSz1Wo+NIQg8pjlEn0jQbcM/0D+xVaYjhw3cvarTanLLBh54oNiRbsT8PNK5GfuST0IlVXjsNRoNlqvY/fw==", + "dependencies": { + "cac": "cac@6.7.14", + "debug": "debug@4.3.5", + "pathe": "pathe@1.1.2", + "tinyrainbow": "tinyrainbow@1.2.0", + "vite": "vite@5.3.3_@types+node@20.14.10" + } + }, + "vite@5.3.3_@types+node@20.14.10": { + "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", + "dependencies": { + "@types/node": "@types/node@20.14.10", + "esbuild": "esbuild@0.21.5", + "fsevents": "fsevents@2.3.3", + "postcss": "postcss@8.4.39", + "rollup": "rollup@4.18.1" + } + }, + "vitest@2.0.2_@types+node@20.14.10": { + "integrity": "sha512-WlpZ9neRIjNBIOQwBYfBSr0+of5ZCbxT2TVGKW4Lv0c8+srCFIiRdsP7U009t8mMn821HQ4XKgkx5dVWpyoyLw==", + "dependencies": { + "@ampproject/remapping": "@ampproject/remapping@2.3.0", + "@types/node": "@types/node@20.14.10", + "@vitest/expect": "@vitest/expect@2.0.2", + "@vitest/pretty-format": "@vitest/pretty-format@2.0.2", + "@vitest/runner": "@vitest/runner@2.0.2", + "@vitest/snapshot": "@vitest/snapshot@2.0.2", + "@vitest/spy": "@vitest/spy@2.0.2", + "@vitest/utils": "@vitest/utils@2.0.2", + "chai": "chai@5.1.1", + "debug": "debug@4.3.5", + "execa": "execa@8.0.1", + "magic-string": "magic-string@0.30.10", + "pathe": "pathe@1.1.2", + "std-env": "std-env@3.7.0", + "tinybench": "tinybench@2.8.0", + "tinypool": "tinypool@1.0.0", + "tinyrainbow": "tinyrainbow@1.2.0", + "vite": "vite@5.3.3_@types+node@20.14.10", + "vite-node": "vite-node@2.0.2_@types+node@20.14.10", + "why-is-node-running": "why-is-node-running@2.3.0" + } + }, + "wait-port@1.1.0": { + "integrity": "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==", + "dependencies": { + "chalk": "chalk@4.1.2", + "commander": "commander@9.5.0", + "debug": "debug@4.3.5" + } + }, + "webidl-conversions@4.0.2": { + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dependencies": {} + }, + "whatwg-url@7.1.0": { + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "lodash.sortby@4.7.0", + "tr46": "tr46@1.0.1", + "webidl-conversions": "webidl-conversions@4.0.2" + } + }, + "which@2.0.2": { + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "isexe@2.0.0" + } + }, + "why-is-node-running@2.3.0": { + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dependencies": { + "siginfo": "siginfo@2.0.0", + "stackback": "stackback@0.0.2" + } + }, + "wordwrap@1.0.0": { + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dependencies": {} + }, + "wrap-ansi@7.0.0": { + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "ansi-styles@4.3.0", + "string-width": "string-width@4.2.3", + "strip-ansi": "strip-ansi@6.0.1" + } + }, + "wrap-ansi@8.1.0": { + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "ansi-styles@6.2.1", + "string-width": "string-width@5.1.2", + "strip-ansi": "strip-ansi@7.1.0" + } + }, + "yaml@2.4.5": { + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dependencies": {} + }, + "yocto-queue@1.1.1": { + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dependencies": {} + }, + "zx@8.1.4": { + "integrity": "sha512-QFDYYpnzdpRiJ3dL2102Cw26FpXpWshW4QLTGxiYfIcwdAqg084jRCkK/kuP/NOSkxOjydRwNFG81qzA5r1a6w==", + "dependencies": { + "@types/fs-extra": "@types/fs-extra@11.0.4", + "@types/node": "@types/node@20.14.10" + } + } + } + }, + "remote": {}, + "workspace": { + "dependencies": [ + "npm:mri", + "npm:wait-port", + "npm:zx" + ], + "packageJson": { + "dependencies": [ + "npm:@brillout/release-me@^0.3.9", + "npm:@types/node@^20.14.10", + "npm:@universal-middleware/core@^0.1.1", + "npm:hono@^4.4.13", + "npm:rimraf@^6.0.0", + "npm:tsup@^8.1.0", + "npm:tsx@^4.16.2", + "npm:typescript@^5.5.3", + "npm:vitest@^2.0.2" + ] + } + } +} diff --git a/packages/adapter-hono/package.json b/packages/adapter-hono/package.json new file mode 100644 index 00000000..d13e9fa1 --- /dev/null +++ b/packages/adapter-hono/package.json @@ -0,0 +1,42 @@ +{ + "name": "@universal-middleware/hono", + "version": "0.1.0", + "type": "module", + "description": "Hono adapter for universal middlewares", + "files": [ + "dist" + ], + "exports": { + ".": "./dist/index.js" + }, + "author": "Joël Charles ", + "repository": "https://github.com/magne4000/universal-handler", + "license": "MIT", + "scripts": { + "build": "rimraf dist && tsup", + "dev": "tsup --watch", + "prepack": "pnpm build", + "test": "vitest run", + "test:run-hono:node": "tsx tests/entry-hono.ts", + "test:run-hono:bun": "bun tests/entry-hono.ts", + "test:run-hono:deno": "deno run --unstable-sloppy-imports -A tests/entry-hono.ts", + "test:typecheck": "tsc -p tsconfig.json --noEmit", + "release": "LANG=en_US release-me patch", + "release:minor": "LANG=en_US release-me minor", + "release:commit": "LANG=en_US release-me commit" + }, + "dependencies": { + "@universal-middleware/core": "^0.1.1" + }, + "devDependencies": { + "@brillout/release-me": "^0.3.9", + "@types/node": "^20.14.10", + "@universal-middleware/tests": "workspace:*", + "hono": "^4.4.13", + "rimraf": "^6.0.0", + "tsup": "^8.1.0", + "tsx": "^4.16.2", + "typescript": "^5.5.3", + "vitest": "^2.0.2" + } +} diff --git a/packages/adapter-hono/readme.md b/packages/adapter-hono/readme.md new file mode 100644 index 00000000..7f7e1bcd --- /dev/null +++ b/packages/adapter-hono/readme.md @@ -0,0 +1,3 @@ +# `@universal-middleware/hono` + +[Universal Middleware](https://github.com/magne4000/universal-middleware) adapter for [Hono](https://hono.dev/). diff --git a/packages/adapter-hono/src/common.ts b/packages/adapter-hono/src/common.ts new file mode 100644 index 00000000..512afa69 --- /dev/null +++ b/packages/adapter-hono/src/common.ts @@ -0,0 +1,52 @@ +import type { Context as HonoContext, Handler, MiddlewareHandler } from "hono"; +import type { + UniversalHandler, + UniversalMiddleware, +} from "@universal-middleware/core"; + +export const contextSymbol = Symbol("unContext"); + +/** + * Creates a request handler to be passed to app.all() or any other route function + */ +export function createHandler(handler: UniversalHandler): Handler { + return (honoContext) => { + let context: Universal.Context = honoContext.get(contextSymbol); + if (typeof context !== "object") { + context = {}; + honoContext.set(contextSymbol, context); + } + return handler(honoContext.req.raw, context); + }; +} + +/** + * Creates a middleware to be passed to app.use() or any route function + */ +export function createMiddleware( + middleware: UniversalMiddleware, +): MiddlewareHandler { + return async (honoContext, next) => { + let context: Universal.Context = honoContext.get(contextSymbol); + if (typeof context !== "object") { + context = {}; + honoContext.set(contextSymbol, context); + } + const response = await middleware(honoContext.req.raw, context); + + if (typeof response === "function") { + await next(); + honoContext.res = await response(honoContext.res); + } else if (typeof response === "object" && "body" in response) { + return response; + } else { + return next(); + } + }; +} + +export function getContext( + honoContext: HonoContext, +): Universal.Context | undefined { + return honoContext.get(contextSymbol); +} diff --git a/packages/adapter-hono/src/index.ts b/packages/adapter-hono/src/index.ts new file mode 100644 index 00000000..2f74b9ca --- /dev/null +++ b/packages/adapter-hono/src/index.ts @@ -0,0 +1 @@ +export { createHandler, createMiddleware, getContext } from "./common.js"; diff --git a/packages/adapter-hono/tests/entry-hono.ts b/packages/adapter-hono/tests/entry-hono.ts new file mode 100644 index 00000000..69e9a88e --- /dev/null +++ b/packages/adapter-hono/tests/entry-hono.ts @@ -0,0 +1,52 @@ +import { createHandler, createMiddleware } from "../src/index.js"; +import { Hono } from "hono"; +import { secureHeaders } from "hono/secure-headers"; +import { + args, + bun, + deno, + handler, + middlewares, +} from "@universal-middleware/tests"; + +const app = new Hono(); + +// standard Hono middleware +app.use(secureHeaders()); + +middlewares.forEach((middleware) => app.use(createMiddleware(middleware))); + +// universal handler +app.get("/", createHandler(handler)); + +const port = args.port ? parseInt(args.port) : 3000; + +if (deno) { + // @ts-ignore + Deno.serve( + { + port, + onListen() { + console.log(`Server listening on http://localhost:${port}`); + }, + }, + app.fetch, + ); +} else if (!bun) { + const { serve } = await import("@hono/node-server"); + serve( + { + fetch: app.fetch, + port, + }, + () => { + console.log(`Server listening on http://localhost:${port}`); + }, + ); +} + +// Bun +export default { + port, + fetch: app.fetch, +}; diff --git a/packages/adapter-hono/tests/hono.spec.ts b/packages/adapter-hono/tests/hono.spec.ts new file mode 100644 index 00000000..f1ebd5fb --- /dev/null +++ b/packages/adapter-hono/tests/hono.spec.ts @@ -0,0 +1,33 @@ +import { type Run, runTests } from "@universal-middleware/tests"; +import * as vitest from "vitest"; + +let port = 3000; + +const runs: Run[] = [ + { + name: "adapter-hono: node", + command: "pnpm run test:run-hono:node", + port: port++, + }, + { + name: "adapter-hono: bun", + command: "pnpm run test:run-hono:bun", + port: port++, + }, + { + name: "adapter-hono: deno", + command: "pnpm run test:run-hono:deno", + port: port++, + }, +]; + +runTests(runs, { + vitest, + test(response) { + // added by hono/secure-headers + vitest + .expect(response.headers.has("cross-origin-opener-policy")) + .toBe(true); + vitest.expect(response.headers.has("x-xss-protection")).toBe(true); + }, +}); diff --git a/packages/adapter-hono/tsconfig.json b/packages/adapter-hono/tsconfig.json new file mode 100644 index 00000000..4082f16a --- /dev/null +++ b/packages/adapter-hono/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.json" +} diff --git a/packages/adapter-hono/tsup.config.ts b/packages/adapter-hono/tsup.config.ts new file mode 100644 index 00000000..3d7103f1 --- /dev/null +++ b/packages/adapter-hono/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsup"; + +export default defineConfig([ + { + entry: ["./src/index.ts"], + format: ["esm"], + platform: "neutral", + target: "es2022", + dts: true, + clean: true, + }, +]); diff --git a/packages/adapter-hono/vitest.config.ts b/packages/adapter-hono/vitest.config.ts new file mode 100644 index 00000000..f06d95f0 --- /dev/null +++ b/packages/adapter-hono/vitest.config.ts @@ -0,0 +1,4 @@ +/// +import { defineConfig } from "vite"; + +export default defineConfig({}); diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md new file mode 100644 index 00000000..8b4a77bd --- /dev/null +++ b/packages/core/CHANGELOG.md @@ -0,0 +1,4 @@ +## 0.1.1 (2024-07-12) + + + diff --git a/packages/adapter-express/config.d.ts b/packages/core/config.d.ts similarity index 100% rename from packages/adapter-express/config.d.ts rename to packages/core/config.d.ts diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 00000000..fb9536d0 --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,30 @@ +{ + "name": "@universal-middleware/core", + "version": "0.1.1", + "type": "module", + "description": "Universal middlewares core utilities", + "files": [ + "dist" + ], + "exports": { + ".": "./dist/index.js" + }, + "author": "Joël Charles ", + "repository": "https://github.com/magne4000/universal-handler", + "license": "MIT", + "scripts": { + "build": "rimraf dist && tsup", + "prepack": "pnpm build", + "test:typecheck": "tsc -p tsconfig.json --noEmit", + "release": "LANG=en_US release-me patch", + "release:minor": "LANG=en_US release-me minor", + "release:commit": "LANG=en_US release-me commit" + }, + "devDependencies": { + "@brillout/release-me": "^0.3.9", + "@types/node": "^20.14.10", + "rimraf": "^6.0.0", + "tsup": "^8.1.0", + "typescript": "^5.5.3" + } +} diff --git a/packages/core/readme.md b/packages/core/readme.md new file mode 100644 index 00000000..e406ce73 --- /dev/null +++ b/packages/core/readme.md @@ -0,0 +1,3 @@ +# `@universal-middleware/core` + +[Universal Middleware](https://github.com/magne4000/universal-middleware) core utilities. diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts new file mode 100644 index 00000000..44e6f360 --- /dev/null +++ b/packages/core/src/index.ts @@ -0,0 +1,5 @@ +export type { + Awaitable, + UniversalHandler, + UniversalMiddleware, +} from "./types.js"; diff --git a/packages/adapter-express/src/types.ts b/packages/core/src/types.ts similarity index 100% rename from packages/adapter-express/src/types.ts rename to packages/core/src/types.ts diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json new file mode 100644 index 00000000..4082f16a --- /dev/null +++ b/packages/core/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.json" +} diff --git a/packages/core/tsup.config.ts b/packages/core/tsup.config.ts new file mode 100644 index 00000000..70d86a57 --- /dev/null +++ b/packages/core/tsup.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from "tsup"; + +export default defineConfig([ + { + entry: ["./src/index.ts"], + format: ["esm"], + platform: "node", + target: "node18", + dts: { + banner: `declare global { + namespace Universal { + interface Context extends Record {} + } +}`, + }, + clean: true, + }, +]); diff --git a/packages/tests/config.d.ts b/packages/tests/config.d.ts new file mode 100644 index 00000000..5a4cfa24 --- /dev/null +++ b/packages/tests/config.d.ts @@ -0,0 +1,7 @@ +declare global { + namespace Universal { + interface Context extends Record {} + } +} + +export {}; diff --git a/packages/tests/package.json b/packages/tests/package.json new file mode 100644 index 00000000..daf46edb --- /dev/null +++ b/packages/tests/package.json @@ -0,0 +1,37 @@ +{ + "name": "@universal-middleware/tests", + "private": true, + "version": "0.0.0", + "type": "module", + "description": "Universal middlewares tests utilities", + "files": [ + "dist" + ], + "exports": { + ".": "./dist/index.js" + }, + "author": "Joël Charles ", + "repository": "https://github.com/magne4000/universal-handler", + "license": "MIT", + "scripts": { + "build": "rimraf dist && tsup", + "prepack": "pnpm build", + "test:typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "mri": "^1.2.0", + "wait-port": "^1.1.0", + "zx": "^8.1.4" + }, + "devDependencies": { + "@types/node": "^20.14.10", + "@universal-middleware/core": "workspace:*", + "rimraf": "^6.0.0", + "tsup": "^8.1.0", + "typescript": "^5.5.3", + "vitest": "^2.0.2" + }, + "peerDependencies": { + "vitest": "^2.0.2" + } +} diff --git a/packages/tests/readme.md b/packages/tests/readme.md new file mode 100644 index 00000000..e406ce73 --- /dev/null +++ b/packages/tests/readme.md @@ -0,0 +1,3 @@ +# `@universal-middleware/core` + +[Universal Middleware](https://github.com/magne4000/universal-middleware) core utilities. diff --git a/packages/tests/src/index.ts b/packages/tests/src/index.ts new file mode 100644 index 00000000..95446c4b --- /dev/null +++ b/packages/tests/src/index.ts @@ -0,0 +1,150 @@ +import { kill } from "zx"; +import { type ChildProcess, spawn } from "node:child_process"; +import waitPort from "wait-port"; +import type { UniversalMiddleware } from "@universal-middleware/core"; +import type { UniversalHandler } from "../../../playground/types"; +import mri from "mri"; + +export interface Run { + name: string; + command: string; + port: number; +} + +export interface Options { + vitest: typeof import("vitest"); + test?: (response: Response) => void | Promise; +} + +declare global { + namespace Universal { + interface Context { + something?: Record; + somethingElse?: Record; + } + } +} + +export function runTests(runs: Run[], options: Options) { + options.vitest.describe.concurrent.each(runs)("$name", (run) => { + let server: ChildProcess | undefined = undefined; + const { command, port } = run; + let host = `http://localhost:${port}`; + + options.vitest.beforeAll(async () => { + server = spawn(`${command} --port ${port}`, { + shell: true, + stdio: "inherit", + env: { + ...process.env, + }, + }); + + // Wait until server is ready + await new Promise((resolve, reject) => { + server!.on("error", (error) => { + server = undefined; + reject(error); + }); + + server!.on("exit", (code) => { + if (code !== 0) { + server = undefined; + reject(new Error(`Process exited with code ${code}`)); + } + }); + + waitPort({ port, interval: 250, timeout: 10_000 }) + .then((res) => { + if (res.ipVersion === 4) { + host = `http://127.0.0.1:${port}`; + } + resolve(undefined); + }) + .catch(reject); + }); + }, 30_000); + + options.vitest.afterAll(async () => { + const pid = server?.pid; + if (typeof pid === "number") { + await kill(pid, "SIGKILL").finally(() => { + server = undefined; + }); + } + }, 30_000); + + options.vitest.test( + "middlewares", + async () => { + const response = await fetch(host); + const text = await response.text(); + options.vitest.expect(response.status).toBe(200); + options.vitest.expect(JSON.parse(text)).toEqual({ + something: { + a: 1, + }, + somethingElse: { + b: 2, + }, + }); + options.vitest + .expect(response.headers.get("x-test-value")) + .toBe("universal-middleware"); + options.vitest + .expect(response.headers.has("x-should-be-removed")) + .toBe(false); + await options?.test?.(response); + }, + 30_000, + ); + }); +} + +export const middlewares: UniversalMiddleware[] = [ + // universal middleware that updates the context synchronously + (_request, context) => { + context.something = { + a: 1, + c: 3, + }; + }, + // universal middleware that update the response headers asynchronously + (_request, _context) => { + return async (response) => { + response.headers.set("x-test-value", "universal-middleware"); + response.headers.delete("x-should-be-removed"); + + await new Promise((resolve) => setTimeout(resolve, 1000)); + + return response; + }; + }, + // universal middleware that updates the context asynchronously + async (_request, context) => { + await new Promise((resolve) => setTimeout(resolve, 100)); + + context.somethingElse = { + b: 2, + }; + delete context.something!.c; + }, +]; + +export const handler: UniversalHandler = (_request, context) => { + return new Response(JSON.stringify(context, null, 2), { + headers: { + "x-should-be-removed": "universal-middleware", + }, + }); +}; + +export const args = mri<{ port: string }>( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (globalThis as any).Deno?.args ?? globalThis.process.argv.slice(2), +); + +// @ts-ignore +export const deno = typeof Deno !== "undefined"; +// @ts-ignore +export const bun = typeof Bun !== "undefined"; diff --git a/packages/tests/tsconfig.json b/packages/tests/tsconfig.json new file mode 100644 index 00000000..4082f16a --- /dev/null +++ b/packages/tests/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.json" +} diff --git a/packages/tests/tsup.config.ts b/packages/tests/tsup.config.ts new file mode 100644 index 00000000..a69ef0e6 --- /dev/null +++ b/packages/tests/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsup"; + +export default defineConfig([ + { + entry: ["./src/index.ts"], + format: ["esm"], + platform: "node", + target: "node18", + dts: true, + clean: true, + }, +]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25803532..ca8e7a7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@universal-middleware/core': link:./packages/core + importers: .: @@ -107,6 +110,10 @@ importers: version: 5.5.3 packages/adapter-express: + dependencies: + '@universal-middleware/core': + specifier: link:../core + version: link:../core devDependencies: '@brillout/release-me': specifier: ^0.3.9 @@ -114,18 +121,15 @@ importers: '@types/node': specifier: ^20.14.10 version: 20.14.10 + '@universal-middleware/tests': + specifier: workspace:* + version: link:../tests express: specifier: ^4.19.2 version: 4.19.2 helmet: specifier: ^7.1.0 version: 7.1.0 - mri: - specifier: ^1.2.0 - version: 1.2.0 - readable-stream: - specifier: ^4.5.2 - version: 4.5.2 rimraf: specifier: ^6.0.0 version: 6.0.0 @@ -141,12 +145,89 @@ importers: vitest: specifier: ^2.0.2 version: 2.0.2(@types/node@20.14.10) + + packages/adapter-hono: + dependencies: + '@universal-middleware/core': + specifier: link:../core + version: link:../core + devDependencies: + '@brillout/release-me': + specifier: ^0.3.9 + version: 0.3.9 + '@types/node': + specifier: ^20.14.10 + version: 20.14.10 + '@universal-middleware/tests': + specifier: workspace:* + version: link:../tests + hono: + specifier: ^4.4.13 + version: 4.4.13 + rimraf: + specifier: ^6.0.0 + version: 6.0.0 + tsup: + specifier: ^8.1.0 + version: 8.1.0(postcss@8.4.39)(typescript@5.5.3) + tsx: + specifier: ^4.16.2 + version: 4.16.2 + typescript: + specifier: ^5.5.3 + version: 5.5.3 + vitest: + specifier: ^2.0.2 + version: 2.0.2(@types/node@20.14.10) + + packages/core: + devDependencies: + '@brillout/release-me': + specifier: ^0.3.9 + version: 0.3.9 + '@types/node': + specifier: ^20.14.10 + version: 20.14.10 + rimraf: + specifier: ^6.0.0 + version: 6.0.0 + tsup: + specifier: ^8.1.0 + version: 8.1.0(postcss@8.4.39)(typescript@5.5.3) + typescript: + specifier: ^5.5.3 + version: 5.5.3 + + packages/tests: + dependencies: + mri: + specifier: ^1.2.0 + version: 1.2.0 wait-port: specifier: ^1.1.0 version: 1.1.0 zx: specifier: ^8.1.4 version: 8.1.4 + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.14.10 + '@universal-middleware/core': + specifier: link:../core + version: link:../core + rimraf: + specifier: ^6.0.0 + version: 6.0.0 + tsup: + specifier: ^8.1.0 + version: 8.1.0(postcss@8.4.39)(typescript@5.5.3) + typescript: + specifier: ^5.5.3 + version: 5.5.3 + vitest: + specifier: ^2.0.2 + version: 2.0.2(@types/node@20.14.10) packages: @@ -708,10 +789,6 @@ packages: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -786,9 +863,6 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -807,9 +881,6 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - bundle-require@4.2.1: resolution: {integrity: sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1143,14 +1214,6 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -1361,6 +1424,10 @@ packages: resolution: {integrity: sha512-Lx4Vwbws0IqFfXIVYychxUW0A4EE+7dn/jsjVeM34OXSA2Xs45MkDDP14Mzznp7LlDemUNHQG2uv2N5jQld0hA==} engines: {node: '>=16.0.0'} + hono@4.4.13: + resolution: {integrity: sha512-c6qqenclmQ6wpXzqiElMa2jt423PVCmgBreDfC5s2lPPpGk7d0lOymd8QTzFZyYC5mSSs6imiTMPip+gLwuW/g==} + engines: {node: '>=16.0.0'} + hosted-git-info@7.0.2: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} @@ -1381,9 +1448,6 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -1830,10 +1894,6 @@ packages: printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -1875,10 +1935,6 @@ packages: resolution: {integrity: sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==} engines: {node: '>=16'} - readable-stream@4.5.2: - resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -2032,9 +2088,6 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2893,10 +2946,6 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 - accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -2958,8 +3007,6 @@ snapshots: balanced-match@1.0.2: {} - base64-js@1.5.1: {} - binary-extensions@2.3.0: {} body-parser@1.20.2: @@ -2992,11 +3039,6 @@ snapshots: dependencies: fill-range: 7.1.1 - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - bundle-require@4.2.1(esbuild@0.21.5): dependencies: esbuild: 0.21.5 @@ -3354,10 +3396,6 @@ snapshots: etag@1.8.1: {} - event-target-shim@5.0.1: {} - - events@3.3.0: {} - execa@5.1.1: dependencies: cross-spawn: 7.0.3 @@ -3651,6 +3689,8 @@ snapshots: hono@4.4.12: {} + hono@4.4.13: {} + hosted-git-info@7.0.2: dependencies: lru-cache: 10.4.0 @@ -3671,8 +3711,6 @@ snapshots: dependencies: safer-buffer: 2.1.2 - ieee754@1.2.1: {} - ignore@5.3.1: {} import-fresh@3.3.0: @@ -4028,8 +4066,6 @@ snapshots: printable-characters@1.0.42: {} - process@0.11.10: {} - proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -4071,14 +4107,6 @@ snapshots: parse-json: 7.1.1 type-fest: 4.21.0 - readable-stream@4.5.2: - dependencies: - abort-controller: 3.0.0 - buffer: 6.0.3 - events: 3.3.0 - process: 0.11.10 - string_decoder: 1.3.0 - readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -4245,10 +4273,6 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 diff --git a/tsconfig.json b/tsconfig.json index 4801b63a..6c0ae692 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,6 @@ { "compilerOptions": { "strict": true, - "allowJs": true, - "checkJs": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "verbatimModuleSyntax": true,